VAI Busy Ops Guide

This page is the fastest way to put VAI on a page using a script tag.

Publishers can integrate VAI in two modes:

  1. Paywalls-hosted VAI (easier): load VAI directly from https://paywalls.net/.
  2. Publisher-hosted VAI (additional integration): serve VAI from the same origin as your inventory domain (typically via CDN integration). This is also the approach used for cryptographically signed domain provenance that buyers can verify in RTB.

In both modes, your wrapper / ad stack reads VAI and passes it into:

  • RTB (e.g. OpenRTB via Prebid ORTB2)
  • Ad server tags (key-values / targeting as supported)

If you need the full details (claims, signing, JWKS, and verification), see the VAI technical spec.


Mode 1: Paywalls-hosted VAI (easiest)

Script URL

Use the Paywalls-hosted script base:

<script src="https://paywalls.net/pw/vai.js"></script>

Option A: simplest script tag (blocking, no hook)

<!-- 1) Load VAI (Paywalls-hosted) -->
<script src="https://paywalls.net/pw/vai.js"></script>

<!-- 2) Read window.__PW_VAI__ and pass it into your stack -->
<script>
  (function () {
    var vai = window.__PW_VAI__;
    if (!vai) return;

    // Example: Prebid ORTB2
    if (window.pbjs && pbjs.setConfig) {
      pbjs.setConfig({
        ortb2: {
          site: {
            ext: {
              pw_vai: vai
            }
          }
        }
      });
    }
  })();
</script>

Option B: hook-based setup (recommended for tag managers)

<script>
  // Define the hook first
  window.__PW_VAI_HOOK__ = function (vai) {
    if (window.pbjs && pbjs.setConfig) {
      pbjs.setConfig({
        ortb2: {
          site: {
            ext: {
              pw_vai: vai
            }
          }
        }
      });
    }

    // Optional: expose it for debugging
    window.__PW_VAI__ = vai;
  };
</script>

<script src="https://paywalls.net/pw/vai.js"></script>

Quick verification

  • In DevTools Console, confirm window.__PW_VAI__ is defined.
  • Confirm window.__PW_VAI__.vat and window.__PW_VAI__.act are present.

Common issues

  • CSP blocks the script: ensure your CSP allows https://paywalls.net in script-src.
  • Ordering issues (tag manager): use the hook approach and define window.__PW_VAI_HOOK__ before loading the script.

Mode 2: Publisher-hosted VAI (same-origin + domain provenance)

Use this mode when you want VAI to be served from your inventory domain (same-origin), and when you want buyers to be able to verify publisher-signed domain provenance via the assertion + your jwks.json.

This mode typically requires CDN integration so VAI endpoints are present on your public surface.

Prerequisites (must already be live)

Before you touch page code, confirm these endpoints work on your inventory domain:

  • GET /pw/vai.js returns JavaScript that sets window.__PW_VAI__.
  • GET /pw/vai.json returns the same data as JSON.
  • GET /pw/jwks.json returns public keys so partners can verify the assertion.

Important operational requirements:

  • These endpoints should be same-origin (avoid third-party script hosts for VAI).
  • vai.js and vai.json should be not cacheable (e.g. Cache-Control: private, no-store, max-age=0) because assertions are short-lived.
  • Don’t vary HTML by VAI (keep VAI cache-friendly; VAI is metadata, not page personalization).

If you don’t have these endpoints yet, start with CDN integration and then follow the VAI technical spec.


Option A: simplest script tag (blocking, no hook)

Use this when you control the HTML and can load VAI before your wrapper reads it.

<!-- 1) Load VAI (same-origin) -->
<script src="/pw/vai.js"></script>

<!-- 2) Read window.__PW_VAI__ and pass it into your stack -->
<script>
  (function () {
    var vai = window.__PW_VAI__;
    if (!vai) return;

    // Example: Prebid ORTB2
    if (window.pbjs && pbjs.setConfig) {
      pbjs.setConfig({
        ortb2: {
          site: {
            ext: {
              pw_vai: vai
            }
          }
        }
      });
    }
  })();
</script>

Notes:

  • Don’t add async or defer to the /pw/vai.js tag if your next script assumes VAI is already present.
  • If your environment can’t guarantee ordering (common with tag managers), use the hook approach below.

Option B: hook-based setup (recommended for tag managers)

If you need strict ordering without relying on script execution timing, define a hook before loading /pw/vai.js.

<script>
  // 1) Define the hook first
  window.__PW_VAI_HOOK__ = function (vai) {
    // Example: Prebid ORTB2
    if (window.pbjs && pbjs.setConfig) {
      pbjs.setConfig({
        ortb2: {
          site: {
            ext: {
              pw_vai: vai
            }
          }
        }
      });
    }

    // Optional: expose it for debugging
    window.__PW_VAI__ = vai;
  };
</script>

<!-- 2) Load VAI (same-origin) -->
<script src="/pw/vai.js"></script>

Notes:

  • The hook should be a simple function (no dependencies) and should be defined as early as possible.
  • If both the hook and window.__PW_VAI__ are supported by your /pw/vai.js implementation, you can use either downstream.

Quick verification checklist

In a browser on the inventory domain:

  1. Open https://YOUR_DOMAIN/pw/vai.json and confirm:
    • aud is "vai"
    • dom matches the page hostname
    • exp is in the future and short-lived
    • assertion is present
  2. Open the page and check in DevTools Console:
    • window.__PW_VAI__ is defined
    • window.__PW_VAI__.vat and window.__PW_VAI__.act look reasonable
  3. Open https://YOUR_DOMAIN/pw/jwks.json and confirm:
    • It returns a keys array and includes the kid referenced by the VAI object

Common issues (fast fixes)

  • /pw/vai.js is 404: the endpoint isn’t deployed on the public surface. Fix routing/edge deployment.
  • CSP blocks the script: ensure your CSP allows same-origin scripts (typically script-src 'self' ...).
  • VAI loads but doesn’t update: check caching headers; vai.js must not be cached.
  • dom mismatch: VAI must be bound to the inventory domain; ensure you’re testing on the real host.
  • Hook not called: make sure window.__PW_VAI_HOOK__ is defined before the /pw/vai.js script tag.