Pass consent and privacy signals to the ad server
Get your visitors' consent to the ad server — the vendor ID (849) to list in your TCF 2.x CMP, what the Universal JS tag reads from it and how long it waits, what a visitor without consent gets under each network policy, how US privacy signals and Global Privacy Control are treated, and the parameters for VAST, API and other URLs you build yourself.
What it is and why
The consent your visitors give in your consent manager has to reach the ad server with every ad
request. The Universal JS tag does that on its own for a TCF 2.x CMP; a VAST URL, an API request
or a tag whose verdict you already know carries the signals as parameters instead. What a
visitor without consent gets is your network’s choice, not yours. The other half of going live —
your ads.txt — is on Publish your ads.txt and app-ads.txt.
Example. A German news site loads its CMP and the Epom tag on every page. A visitor accepts the banner: the tag waits for the CMP (at most 5 seconds), sends the TCF string with the request, and the slot fills with a normal ad. The next visitor declines. The request carries a string with no consent for vendor 849, and what that visitor gets is the network’s choice — on a network set to Do not serve ads the slot shows the placement’s Default code; on Do not use any cookies it shows an ad with no cookies.
Typical scenarios
| You have | Do | Where |
|---|---|---|
| A website with EEA visitors and a TCF 2.x CMP | Add vendor 849 (or the ID your network gave you) to the CMP’s vendor list; load the CMP before the tag; nothing else | Your CMP; the page |
| A video player or outstream unit that loads its own VAST URL | Put gdpr=1&gdprConsentIab=<string> on that URL — the player does not see the tag’s attributes | The VAST URL your player calls |
| An app that calls the ad API | Send gdpr, gdprConsentIab (or your own verdict as uc), and usPrivacy / gpp / gppSid / coppa as request parameters | The API request |
| A page where your own logic already knows the verdict | data-user-consent="1" or "0" on the <ins> element | The tag |
| A visitor who opted out under CCPA and your legal setup requires acting on it | Do not load the tag for that visitor, or set data-cookie-policy — the ad server only passes usPrivacy on, it does not enforce it | The page |
Step by step
-
Add Epom to your CMP’s vendor list. Epom’s IAB Global Vendor List ID is 849. Your network can be set up to check a different vendor ID; if it gave you one, list that one too.
-
Load the CMP before the ad tag, or at least on the same page. You do not need to wire the consent string yourself: the tag finds the CMP and waits for the visitor’s decision (see What the tag reads).
-
Tags you build yourself — a VAST URL in a video player, an API request from an app, a tag whose consent you already know — pass the signals as request parameters or tag attributes instead (see Options and fields).
-
Test from a browser that has accepted your consent banner. A browser that refused, or has not answered yet, may legitimately get no ad or an ad without cookies.
What the tag reads
The Universal JS tag looks for a TCF 2.x CMP once per page and shares the answer with every slot on it:
- It calls the page’s
__tcfapifunction or, when the CMP lives in a parent frame, reaches it through the__tcfapiLocatorframe the TCF standard requires. - It waits until the CMP reports a final decision — the string is ready, or the visitor has made their choice — for at most 5 seconds. After that the ad request goes out with whatever it has.
- If the CMP says GDPR does not apply, the request says so. Otherwise the request carries the visitor’s TCF consent string.
- It keeps listening: when the visitor changes their choice later, slots that refill afterwards send the new string.
A page with no CMP still gets ads requested; the request simply carries no consent string, and the ad server decides whether GDPR applies from where the visitor is (the EEA countries). Only TCF 2.x strings count — a string of any other version is treated as no consent.
What happens without consent
Consent matters only for requests the ad server treats as in GDPR scope: the request says GDPR applies, or it says nothing and the visitor is in the EEA. For those, your network administrator chooses one network-wide behaviour when the visitor has not consented to the vendor:
| Network setting | What your visitor gets |
|---|---|
| Not enforced (the default) | Ads as usual |
| Do not serve ads | No ad; the slot shows your Default code or stays empty |
| Do not use the user-ID cookie | An ad, without the user-identifier cookie |
| Do not use any cookies | An ad, with no cookies set or read |
| No cookies or server-side processing | An ad, with no cookies, and the visitor’s IP shortened, location reduced to country and browser details withheld |
Ask your network manager which one your network uses — it decides what your EEA fill looks like for visitors who decline. The policy itself is set under GDPR and TCF consent.
US privacy signals
- CCPA / US Privacy string, GPP and COPPA: the JavaScript tag does not read them from a CMP. A
VAST, API or other URL you build yourself — or your stitcher fills in — can carry them as
usPrivacy,gpp,gppSidandcoppa. The ad server does not act on them itself: it passes them to programmatic demand when your network has Pass privacy signals to DSPs on, and into the$$US_PRIVACY$$,$$GPP$$,$$GPP_SID$$and$$COPPA$$macros. If your legal setup requires acting on an opt-out, stop the tag yourself — do not load it, or setdata-cookie-policy— for visitors who opted out. - Global Privacy Control (GPC): browsers that send GPC add it to every request, so it reaches the ad server without any work on your side. Your network administrator decides whether it counts. When it does, a GPC opt-out is treated as no consent, but only for requests in GDPR scope (above); for other visitors it changes nothing.
Caveats and exceptions
data-gdpr-consent-iab switches the CMP lookup off for that slot. If you set it from a
variable that is empty when the page loads, the slot sends no consent at all — leave the
attribute out and let the tag ask the CMP.
A CMP that takes longer than 5 seconds to answer loses the first request: it goes out without a string. Later refills use the visitor’s answer.
A video player or outstream unit that loads its own VAST URL does not see the tag’s attributes. Put the parameters on that URL as well.
Who does what between publisher, network manager and administrator is on Privacy signals and ads.txt on your pages.
Not working?
- EEA visitors get no ad, or an ad without cookies. Where: the CMP’s vendor list (vendor 849, or the ID your network gave you) and the network’s no-consent policy — ask your network manager which one applies.
- The first ad on a page carries no consent string. Where: your CMP’s load order — it answered after the 5-second wait; load it before the tag.
- A slot sends no consent at all. Where: the tag’s
<ins>attributes —data-gdpr-consent-iabset from an empty variable also stops the CMP lookup; remove it.
The full symptom table, consent and ads.txt together, is on Privacy signals and ads.txt on your pages.
Reference
Every tag attribute and request parameter (data-gdpr, data-gdpr-consent-iab,
data-user-consent, data-cookie-policy, usPrivacy, gpp, gppSid, coppa) and the fixed
values (vendor ID, CMP wait) are on
Options and fields. The network-side policy:
GDPR and TCF consent.