Validated Actor Inventory (VAI)
Technical specification
Validated Actor Inventory (VAI) is a publisher-originated, pre-bid classification signal backed by a cryptographically secure assertion of domain provenance. It is used to route traffic into different monetization paths and tiers (for example: premium, standard, conservative, or suppressed). It is most valuable when it enables segmentation and routing—not blanket blocking.
VAI describes:
- Validated Actor Type (VAT): who or what is most likely responsible for the request
- Actor Confidence Tier (ACT): how confident the classification is at the time of evaluation
This document explains what the signal is, how it is generated, how it is verified, and how to pass it into your programmatic stack.
Audience and goals
This spec is written for publishers (product, ad ops, and engineering). The goal is to make VAI:
- Practical: clear integration steps and operational guidance
- Verifiable: cryptographically authenticatable end-to-end
- Cache-friendly: no HTML variation and minimal origin changes
- Privacy-preserving: no user identification and no cross-site identifiers
Core concepts
1) Validated Actor Type (VAT)
VAT expresses which category of actor the impression is intended to influence.
| Value | Meaning | Common examples |
|---|---|---|
HUMAN | Likely human attention | Typical users in browsers |
AI_AGENT | AI system retrieving content on behalf of a user | AI assistants, research agents, summarization tools |
SHARING | Social sharing and preview bots | Link preview generators, social card fetchers |
OTHER | Non-human automation not intended to influence a person | Crawlers, scrapers, monitoring, QA, renderers |
VAT is a classification, not an identity claim.
2) Actor Confidence Tier (ACT)
ACT is an explicit confidence tier describing certainty in the VAT assignment.
| Value | Meaning | Typical use |
|---|---|---|
ACT-1 | High confidence — known pattern match or definitive signal | Premium routing / strongest assumptions |
ACT-2 | Medium confidence — reasonable signal without corroboration | Standard routing / tolerant strategies |
ACT-3 | Low confidence — unmatched or unknown | Conservative routing / limited monetization |
Publishers and buyers can choose how to treat each tier (route, discount, exclude, analyze separately, etc.).
Signal requirements (normative)
The keywords MUST, SHOULD, and MAY are used as described in RFC 2119.
A VAI assertion:
- MUST include
vatandact - MUST be produced server-side by publisher-controlled infrastructure (edge/CDN/gateway/origin)
- MUST be cryptographically signed
- MUST be time-bound (short TTL) to limit replay
- MUST be bound to the publisher inventory domain (
dom) (and MAY be additionally bound to coarse request context) - MUST NOT contain user identity, persistent user identifiers, or cross-site IDs
Transport and endpoints
VAI is designed to be easy to deploy without fragmenting cache or requiring origin template changes.
Endpoint: GET /pw/vai.json
Returns the current request’s classification plus a signed assertion suitable for downstream verification.
Recommended response (application/json):
{
"iss": "paywalls.net",
"dom": "example.com",
"mstk": "01J4X9K2ABCDEF01234567",
"vat": "HUMAN",
"act": "ACT-2",
"iat": 1736629940,
"exp": 1736630040,
"kid": "2026-01-a",
"jws": "BASE64URL_JWS"
}
Field definitions:
| Field | Type | Notes |
|---|---|---|
iss | string | required. Issuer identifier (bare domain, e.g. paywalls.net). |
dom | string | required. Inventory domain binding (the request hostname, e.g. example.com). |
mstk | string | required. Micro-session token; short-lived identifier scoping the current actor + inventory attributes (MUST NOT be user-stable). |
vat | string | required. One of HUMAN, AI_AGENT, SHARING, OTHER. |
act | string | required. One of ACT-1, ACT-2, ACT-3. |
iat | number | recommended. Issued-at (epoch seconds). |
exp | number | required. Expiry (epoch seconds). |
kid | string | required. Key identifier used to sign jws (also present in the JWS header). |
jws | string | required. JWS/JWT-like token (details below). |
Normative rule:
- The clear-text fields (
iss,dom,vat,act,mstk,iat,exp) MUST match the correspondingjwsclaims.
TTL guidance: exp - iat SHOULD be 300 seconds (5 minutes).
Endpoint: GET /pw/vai.js
Returns a static loader script that fetches /pw/vai.json and exposes the result to client-side integrations.
Recommended behavior:
- The script fetches
/pw/vai.json(same-origin, synchronous) and setswindow.__PW_VAI__to the response. - The script does not set cookies. It MAY use localStorage for optional caching when the server enables it (
_ls_cacheflag). - The script itself is static and identical for every request — safe to cache.
Example usage in an HTML template:
<script src="/pw/vai.js"></script>
This enables header bidding wrappers to read a normalized object without needing additional calls.
Assertion format and cryptographic verification
VAI assertions are designed to be verified by intermediaries (SSPs, verification partners) and/or buyers.
Signing format
The jws value SHOULD be a JWS compact serialization token (JWT-style) containing a JSON payload.
- Algorithm SHOULD be EdDSA (Ed25519) or ES256.
- Algorithm MUST NOT be
none.
Header (example):
{ "alg": "EdDSA", "typ": "JWT", "kid": "2026-01-a", "jku": "https://example.com/pw/jwks.json" }
Payload claims (recommended):
iss(string, required): issuer identifier (bare domain, e.g.paywalls.net)dom(string, required): inventory domain binding (the request hostname, e.g.,example.com)mstk(string, required): micro-session tokenvat(string, required)act(string, required)iat(number, recommended)exp(number, required)
Binding guidance:
- The assertion MUST be bound to the serving domain (
dom). - The assertion MAY be additionally bound to coarse request context (for example, path class or site section). It MUST NOT be bound to user identifiers.
Verification steps (SSP/buyer)
A verifier SHOULD:
- Parse the JWS header and payload.
- Resolve the public key via
kidfrom the JWS header, using the publisher's JWKS endpoint (discoverable viajkuin the header). - Verify the signature.
- Validate time bounds:
iat <= now <= expwith a small clock skew tolerance (e.g., 5–15s). - Validate
dommatches the inventory domain. - Confirm
vatandactare in the allowed enum sets.
If any checks fail, the verifier should treat the signal as unverified and ignore it or downgrade it according to policy.
Key distribution (JWKS)
Publishers MUST provide a public key set for verifiers.
Endpoint: GET /pw/jwks.json
Recommended response (application/json):
{
"keys": [
{
"kty": "OKP",
"crv": "Ed25519",
"kid": "2026-01-a",
"use": "sig",
"alg": "EdDSA",
"x": "BASE64URL_PUBLIC_KEY"
}
]
}
Operational guidance:
- Keys SHOULD be cacheable (e.g.,
Cache-Control: public, max-age=3600). - Publishers SHOULD support key rotation by serving multiple keys during transitions.
- Assertions MUST reference the active signing key via
kidin the JWS header.
Passing VAI into the programmatic stack
VAI is intended to be carried as publisher-originated metadata that survives through:
- header bidding wrappers
- ad servers
- OpenRTB bid requests
- SSP and exchange routing
Recommended OpenRTB mapping
VAI signals are split across ORTB2 scopes:
site.ext.data.vai— domain provenance fields (issuer, domain). Thedomvalue can be cryptographically verified through the signedjwsinuser.ext.data.vai.user.ext.data.vai— actor classification fields (validated actor type, confidence tier, micro-session token, signed assertion)imp[].ext.data.vai— pageview correlation (pvtk)
Example:
{
"site": {
"domain": "example.com",
"ext": {
"data": {
"vai": {
"iss": "paywalls.net",
"dom": "example.com"
}
}
}
},
"user": {
"ext": {
"data": {
"vai": {
"iss": "paywalls.net",
"mstk": "01J4X9K2ABCDEF01234567",
"vat": "HUMAN",
"act": "ACT-2",
"jws": "BASE64URL_JWS"
}
}
}
},
"imp": [{
"ext": {
"data": {
"vai": {
"pvtk": "01J4X9K2ABCDEF01234567/3"
}
}
}
}]
}
Notes:
- The
jwsSHOULD be included so downstream parties can verify authenticity. - The
jwsis placed atuser.ext.data.vai; its signed payload also containsdomfor cross-section validation. pvtkis client-derived and unsigned; buyers correlate pageviews using themstkroot.
Prebid.js / wrapper integration (example)
Load /pw/vai.js early (it sets window.__PW_VAI__), then attach the fields you need to ORTB2:
<script src="/pw/vai.js"></script>
var vai = window.__PW_VAI__;
// If VAI isn't available yet, proceed without it.
if (!vai) {
// pbjs.requestBids(); // continue without vai
return;
}
pbjs.setConfig({
ortb2: {
site: {
ext: {
data: {
vai: { iss: vai.iss, dom: vai.dom }
}
}
},
user: {
ext: {
data: {
vai: { iss: vai.iss, vat: vai.vat, act: vai.act, mstk: vai.mstk, jws: vai.jws }
}
}
}
}
});
Caching and performance
VAI is designed to avoid cache fragmentation.
/pw/vai.jsonMUST NOT be cached by browsers, CDNs, or intermediaries (useCache-Control: private, no-store, max-age=0)./pw/vai.jsis a static loader script that contains no per-request data — it MAY be cached (e.g.Cache-Control: public, max-age=300). The per-request classification is fetched at runtime via/pw/vai.json.- Pages and HTML responses SHOULD NOT vary by VAT/ACT.
Because the assertion is short-lived, the integration can be implemented without per-user storage.
Privacy and compliance posture
VAI is designed as a traffic-origin classification signal, not an identity system.
VAI implementations:
- MUST NOT include:
- IP addresses
- full user agents
- stable user IDs
- cookies, localStorage IDs, or fingerprinting outputs
- SHOULD minimize request-derived entropy in the assertion payload
Publishers should treat VAI like other operational metadata used to route demand (similar to brand-safety or contextual signals), not as personal data.
Recommended publisher routing policies (non-normative)
Different publishers will route differently. A common starting point:
HUMAN+ACT-1: eligible for premium demand pathsHUMAN+ACT-2: eligible for standard demand pathsACT-3: eligible for conservative demand paths or limited monetizationAI_AGENT: may be excluded from ads, routed to specific deals, or used for future licensing modelsSHARING: may serve ads if the preview generates downstream human traffic; some publishers excludeOTHER: typically excluded from ads (to prevent dilution)
VAI is most valuable when it enables segmentation, not blanket blocking.
Troubleshooting checklist
If partners report “missing or unverifiable VAI,” check:
- Endpoints reachable:
/pw/vai.json,/pw/vai.js, and/pw/jwks.jsonreturn 200. - Time bounds:
expis in the future; TTL is 30–120s; clocks are correct. - Key rotation:
kidin JWS header assertions exists in JWKS. - Domain binding:
dommatches the inventory domain used in OpenRTB. - Propagation: wrapper passes
vaithrough to the SSP unchanged. - Size limits: ensure the assertion doesn’t exceed platform limits; prefer compact keys and short claims.