Validated Actor Inventory (VAI)

Technical specification

Validated Actor Inventory (VAI) is a publisher-originated, pre-bid classification signal 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.

ValueMeaningCommon examples
HUMANLikely human attentionTypical users in browsers
AI_AGENTAI system retrieving content on behalf of a userAI assistants, research agents, summarization tools
SHARINGSocial sharing and preview botsLink preview generators, social card fetchers
OTHERNon-human automation not intended to influence a personCrawlers, 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.

ValueMeaningTypical use
ACT-1High confidence — known pattern match or definitive signalPremium routing / strongest assumptions
ACT-2Medium confidence — reasonable signal without corroborationStandard routing / tolerant strategies
ACT-3Low confidence — unmatched or unknownConservative 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 vat and act
  • 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": "https://paywalls.net",
  "aud": "vai",
  "dom": "example.com",
  "vat": "HUMAN",
  "act": "ACT-2",
  "did": "01J...ULID",
  "iat": 1736629940,
  "exp": 1736630040,
  "kid": "2026-01-a",
  "assertion": "BASE64URL_JWS"
}

Field definitions:

FieldTypeNotes
issstringrequired. Issuer identifier (prototype commonly uses https://paywalls.net).
audstringrequired. Audience identifier (canonical: "vai").
domstringrequired. Inventory domain binding (the request hostname, e.g. example.com).
vatstringrequired. One of HUMAN, AI_AGENT, SHARING, OTHER.
actstringrequired. One of ACT-1, ACT-2, ACT-3.
assertionstringrequired. JWS/JWT-like token (details below).
iatnumberrecommended. Issued-at (epoch seconds).
expnumberrequired. Expiry (epoch seconds).
kidstringrequired. Key identifier used to sign assertion.
didstringoptional. Short-lived decision identifier for debugging/analytics (MUST NOT be user-stable).

Normative rule:

  • The clear-text fields (iss, aud, dom, vat, act, did, iat, exp) MUST match the corresponding assertion claims.

TTL guidance: exp - iat SHOULD be between 30 and 120 seconds.

Endpoint: GET /pw/vai.js

Returns a small JavaScript payload that exposes the VAI object to client-side integrations.

Recommended behavior:

  • The script sets window.__PW_VAI__ to the same object shape returned by /pw/vai.json.
  • The script does not set cookies or localStorage.

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 assertion 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" }

Payload claims (recommended):

  • vat (string, required)
  • act (string, required)
  • iss (string, required): issuer identifier (publisher or service)
  • aud (string, required): audience identifier (canonical: "vai")
  • iat (number, recommended)
  • exp (number, required)
  • dom (string, required): inventory domain binding (the request hostname, e.g., example.com)
  • jti (string, recommended): unique token id (short-lived) to improve replay detection
  • did (string, optional): decision/debug id (short-lived)

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:

  1. Parse the JWS header and payload.
  2. Resolve the public key via kid from the publisher’s JWKS endpoint.
  3. Verify the signature.
  4. Validate time bounds: iat <= now <= exp with a small clock skew tolerance (e.g., 5–15s).
  5. Validate dom matches the inventory domain.
  6. Confirm vat and act are 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 kid.

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 SHOULD be placed in OpenRTB site.ext (or app.ext) as a namespaced object.

Example:

{
  "site": {
    "domain": "example.com",
    "ext": {
      "pw_vai": {
        "iss": "https://paywalls.net",
        "aud": "vai",
        "dom": "example.com",
        "vat": "HUMAN",
        "act": "ACT-2",
        "kid": "2026-01-a",
        "exp": 1736630040,
        "assertion": "BASE64URL_JWS"
      }
    }
  }
}

Notes:

  • The assertion SHOULD be included so downstream parties can verify authenticity.
  • Intermediaries SHOULD NOT rewrite vat/act; they MAY add their own separate fields if needed.

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 pw_vai
  return;
}

pbjs.setConfig({
  ortb2: {
    site: {
      ext: {
        pw_vai: vai
      }
    }
  }
});

Caching and performance

VAI is designed to avoid cache fragmentation.

  • /pw/vai.json MUST NOT be cached by browsers, CDNs, or intermediaries (use Cache-Control: private, no-store, max-age=0).
  • /pw/vai.js MUST NOT be cached by browsers, CDNs, or intermediaries (use Cache-Control: private, no-store, max-age=0).
  • 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 paths
  • HUMAN + ACT-2: eligible for standard demand paths
  • ACT-3: eligible for conservative demand paths or limited monetization
  • AI_AGENT: may be excluded from ads, routed to specific deals, or used for future licensing models
  • SHARING: may serve ads if the preview generates downstream human traffic; some publishers exclude
  • OTHER: 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:

  1. Endpoints reachable: /pw/vai.json, /pw/vai.js, and /pw/jwks.json return 200.
  2. Time bounds: exp is in the future; TTL is 30–120s; clocks are correct.
  3. Key rotation: kid in assertions exists in JWKS.
  4. Domain binding: dom matches the inventory domain used in OpenRTB.
  5. Propagation: wrapper passes pw_vai through to the SSP unchanged.
  6. Size limits: ensure the assertion doesn’t exceed platform limits; prefer compact keys and short claims.