Tag installation

The AdPriva Tag is a headless JavaScript file. It renders nothing, sets no cookies and writes nothing to browser storage. On each page load it sends one view event to AdPriva, which seals it as a proof.

The file served from the CDN is about 19 KB, or about 8 KB gzipped (measured on 2026-10-21). Load it with async, so it never delays your page or your ad calls.

Before you start

Add your domain in the console under Domains. The tag reports the page’s hostname as the site, and AdPriva links a proof to your organization by matching that hostname to a domain you added. Add the hostname your pages are served on, for example www.example.com if that is what visitors see.

A proof whose hostname matches no domain is still stored, but it is not linked to your organization and does not appear in your console.

On WordPress, install the AdPriva plugin from WordPress.org instead and click Connect with AdPriva. The plugin registers your site and loads the tag for you, with async. From plugin version 1.2.0 you choose the consent mode under Settings → Visitor consent.

Quickstart

Place this snippet in <head> or just before </body>:

<script async src="https://cdn.adpriva.com/tag.js" data-consent-mode="tcf"></script>

There is no site key. The only attribute is data-consent-mode, described in the next section: choose tcf, manual or off, and always set it. Without it the tag runs as off today, but that default may change, and an explicit mode keeps your embed’s behaviour fixed.

Embeds that load https://cdn.adpriva-ads.com/tag.js keep working. Both hosts serve the same file and stay live; see Content Security Policy for the hosts each one talks to.

The console’s add-domain steps also give you a verification meta tag (<meta name="adpriva-verify" content="...">). It proves that you own the domain. It is separate from the tag.

Collecting consent certificates from your web forms? Start with the Consent Certificates — Quickstart. It is the same snippet, plus one attribute on the form you want witnessed.

The tag can wait for your visitor’s consent before it observes the page or sends anything. You choose how with data-consent-mode on the script tag:

ModeSnippetWhat the tag does
offdata-consent-mode="off"Starts at page load. Use it only where you have confirmed that consent is not needed. A missing attribute also means off today; set it explicitly anyway.
tcfdata-consent-mode="tcf"Follows your IAB TCF v2 consent banner (CMP). It runs only while the CMP reports consent.
manualdata-consent-mode="manual"Waits until your page calls AdPriva.grantConsent(), and stops when it calls AdPriva.revokeConsent().
<script async src="https://cdn.adpriva.com/tag.js" data-consent-mode="manual"></script>

In tcf and manual mode:

  • Nothing is sent before consent, and nothing is recorded, except a consent form you opt in to record-only evidence (below). The tag starts counting interaction at the moment consent is given, and sends its view event about one second later. Activity from before the consent never reaches AdPriva.
  • No answer means no consent. A missing banner, a banner that fails, or a visitor who has not decided yet all count as no consent. There is no timeout after which the tag starts anyway.
  • Withdrawal stops the tag at once. Anything not yet sent, including consent evidence waiting to be sent when the visitor leaves the page, is discarded.
  • Consent evidence follows the same rule, unless you opt a form in. On forms you mark for consent certificates, nothing is captured or sent without consent. If such a form also carries data-adpriva-record-without-consent, its submission is still recorded without consent, but only the record itself: the hash of the consent wording, the Legal Bundle, the checkbox states, the page address without its query string, and the time. No interaction signals, device details or subject reference are sent, and a later withdrawal does not discard the record. See record-only evidence.
  • A mistyped mode does not switch the tag on. An unknown value is treated as manual, and the tag logs a warning starting with [AdPriva] in the browser console.

You can also set the mode from a script that runs before the tag, instead of the attribute: window.AdPriva = { consentMode: 'manual' }. If both are set, the attribute wins.

Loading the script is a request too. When the browser downloads tag.js from AdPriva’s CDN, the visitor’s IP address and browser user agent reach AdPriva’s CDN, whatever the mode. If you want no request to AdPriva at all before consent, load the script only after consent, with the helpers below or your CMP’s script blocking.

TCF mode

tcf works with any consent banner that implements the IAB Transparency and Consent Framework v2 and provides the standard __tcfapi function on the page, for example Quantcast Choice, or Cookiebot, OneTrust and Usercentrics with their TCF option enabled. The banner’s script must be on the page before the window load event.

The tag listens to every consent event of the banner and runs only while the latest event:

  • is successful and final for now (tcloaded when the page loads with a stored choice, useractioncomplete after the visitor chose), and
  • says that GDPR does not apply to this visitor, or that the visitor consented to purpose 1, “Store and/or access information on a device”.

While the banner is open, the tag counts that as no consent.

TCF vendor status. AdPriva is not yet registered on the IAB Europe Global Vendor List, so it has no TCF vendor id and the tag checks purpose 1 only. If your legal review requires vendor-level consent, add AdPriva to your CMP as a custom (non-TCF) vendor and use manual mode with the helpers below.

Add these two helpers to your page, before your CMP’s script, and call them from your CMP or tag manager. They load tag.js only when consent is first given, so nothing reaches AdPriva before that, and they stop the tag again on withdrawal:

<script>
  function adprivaGrant() {
    var a = (window.AdPriva = window.AdPriva || {});
    if (a.grantConsent) { a.grantConsent(); return; } // tag already running: consent again
    a.consentMode = 'manual';
    a.consentGranted = true; // read by the tag when it starts
    if (document.getElementById('adpriva-tag')) return; // already loading
    var s = document.createElement('script');
    s.id = 'adpriva-tag';
    s.async = true;
    s.src = 'https://cdn.adpriva.com/tag.js';
    document.head.appendChild(s);
  }
  function adprivaRevoke() {
    var a = (window.AdPriva = window.AdPriva || {});
    if (a.revokeConsent) a.revokeConsent();
    else a.consentGranted = false;
  }
</script>

Calling adprivaGrant() more than once is safe: the tag is loaded once and sends one view event per page load.

If you prefer to keep the snippet in your page, load it with data-consent-mode="manual" and call AdPriva.grantConsent() and AdPriva.revokeConsent() directly once the tag has loaded.

Setting it up with your CMP or tag manager

AdPriva measures whether your traffic is human. The closest standard category for it in most consent tools is statistics / analytics (called “performance” in OneTrust). Which category and legal basis you use is your decision as the controller.

Quantcast Choice, or any CMP with TCF enabled. Use data-consent-mode="tcf" on the snippet. Nothing else is needed.

Cookiebot. Call the helpers from Cookiebot’s events:

<script>
  window.addEventListener('CookiebotOnAccept', function () {
    if (Cookiebot.consent.statistics) adprivaGrant(); else adprivaRevoke();
  });
  window.addEventListener('CookiebotOnDecline', adprivaRevoke);
</script>

Cookiebot also fires CookiebotOnAccept on later page views when the visitor consented on an earlier visit, so the tag starts on those pages too.

OneTrust. OneTrust calls OptanonWrapper() when its banner loads and on every change. Performance is category C0002:

<script>
  function OptanonWrapper() {
    if ((window.OnetrustActiveGroups || '').indexOf(',C0002,') !== -1) adprivaGrant();
    else adprivaRevoke();
  }
</script>

If you already have an OptanonWrapper(), add the two lines to it.

Usercentrics. Add AdPriva as a custom data processing service named AdPriva. Under Implementation, add a data layer of type Window Event named ucEvent, then:

<script>
  window.addEventListener('ucEvent', function (e) {
    if (!e.detail || e.detail.event !== 'consent_status') return;
    if (e.detail['AdPriva'] === true) adprivaGrant(); else adprivaRevoke();
  });
</script>

Google Tag Manager. Put the helpers in a Custom HTML tag that fires on Consent Initialization – All Pages. Then create two more Custom HTML tags:

  1. AdPriva – grant, containing <script>adprivaGrant();</script>. In Advanced Settings → Consent Settings, choose Require additional consent for tag to fire and add analytics_storage. Fire it on All Pages and on the event your CMP sends when the visitor changes consent. GTM then fires it only while analytics_storage is granted.
  2. AdPriva – revoke, containing <script>adprivaRevoke();</script>. Fire it on your CMP’s consent-change event, with a trigger condition on your CMP’s consent variable that matches when analytics consent is denied.

What the tag sends

  • One view event per page load, about one second after the page loads, or after consent in tcf and manual mode. A visitor who leaves within that second sends nothing.
  • The event carries aggregate interaction counts, automation hints, a low-detail device snapshot, the page path, the referrer and a one-time nonce. The full field list is on the AdPriva Tag page.
  • If the request fails with a network error or a server error, the tag retries once after 1.5 seconds. A withdrawal cancels the retry.
  • On forms you mark for consent, the tag also sends the consent evidence when the form is submitted.

The tag does not send separate click or conversion events, and it has no custom-event API.

Content Security Policy

The tag sends its events to the ingest host that pairs with the CDN host it was loaded from. If your site sets a Content Security Policy, allow the pair your snippet uses:

Snippet loads the tag fromscript-srcconnect-src
https://cdn.adpriva.com/tag.jshttps://cdn.adpriva.comhttps://ingest.adpriva.com
https://cdn.adpriva-ads.com/tag.jshttps://cdn.adpriva-ads.comhttps://server.adpriva-ads.com

Switch both together. A page that loads the tag from cdn.adpriva.com but allows only server.adpriva-ads.com in connect-src blocks every event. When you move an existing embed to cdn.adpriva.com, update script-src and connect-src in the same change.

Cloudflare Rocket Loader. If Rocket Loader runs on your site, add data-cfasync="false" to the tag’s <script>, so it runs as itself: <script async data-cfasync="false" src="https://cdn.adpriva.com/tag.js" data-consent-mode="tcf"></script>. Otherwise the tag may not find its own script element, and it then falls back to server.adpriva-ads.com without your data-consent-mode.

If you use the helpers above, your policy must also allow the inline script, for example with a nonce.

Testing your installation

  1. Install the tag on a page of a domain you added.
  2. Open the page and stay on it for a few seconds. In tcf or manual mode, give consent first.
  3. In your browser’s developer tools, check the Network tab for a POST to https://ingest.adpriva.com/proofs (or https://server.adpriva-ads.com/proofs if your snippet loads the tag from cdn.adpriva-ads.com). The response contains the proof’s signature, which is its proof id. In tcf or manual mode, check too that there is no such request before you consent.
  4. In the console, open Traffic Quality → Events. The proof appears there with its score and verdict.
  5. (Optional) Search the proof id in the Explorer. The proof shows as pending until its batch is anchored.

If the request fails, the tag logs a warning starting with [AdPriva] in the browser console. window.AdPriva.consentMode shows the consent mode the tag is using.

How a proof flows

  1. A visitor opens your page, and the tag loads.
  2. About one second later (or after consent, in tcf and manual mode), the tag sends the view event to AdPriva’s ingest server.
  3. The server refuses the event if its nonce was already used. Otherwise it seals the event with an HMAC. The signature is the proof id.
  4. The server scores the proof and stores the score and verdict with it.
  5. Within about 5 minutes, the proof is put in a batch. The batch’s Merkle root is anchored on Horizen.
  6. Anyone with the proof id can look it up in the Explorer or through the public API.