Ad-server macros look trivial and break campaigns more often than any other part of the
stack. This is the reference we wish we'd had — every major vendor, the macros that actually
go in their tag, where they go, and the gotchas we see most.
The core GAM macros you need to know
Google Ad Manager passes these at ad-call time. Each one substitutes a value before the
tag reaches the browser.
| Macro |
What it resolves to |
When to use |
%%CLICK_URL_UNESC%% |
Click-tracker prefix, unescaped |
When click URL is the last segment of the redirect chain |
%%CLICK_URL_ESC%% |
URL-encoded click-tracker prefix |
When click URL is a query-string value |
%%CLICK_URL_ESC_ESC%% |
Double-encoded |
Nested redirects — e.g., through two trackers |
%%CACHEBUSTER%% |
Random integer per impression |
Bust browser/CDN cache on impression pixels |
%%PATTERN:key%% |
Custom key-value pass-through |
Audience data, A/B variants, GAM key-value targeting |
%%SITE%% |
Publisher site name |
Reporting, vendor audit trails |
%%ADUNIT%% |
Ad unit path |
Reporting |
%%HEIGHT%%, %%WIDTH%% |
Creative dimensions |
Some third-party tags need these at runtime |
${GDPR} |
0 or 1 GDPR-applies flag |
Consent-aware vendors |
${GDPR_CONSENT_755} |
Base64 TCF v2.2 consent string |
EEA / UK traffic |
${US_PRIVACY} |
CCPA/USP signal |
US state-level compliance |
${GPP} |
Global Privacy Platform string |
Multi-jurisdiction consent |
${ADVERTISING_IDENTIFIER} |
Hashed IDFA/GAID |
Mobile app inventory |
Macros are case-sensitive. %%CLICK_URL_UNESC%% works;
%%click_url_unesc%% does not.
Vendor-by-vendor reference
Below are the verified insertion patterns for each major vendor. "Insertion method" refers
to how we insert macros inside CreativeValidator — append a query parameter, prepend a
URL, or replace a placeholder token.
Campaign Manager 360 (DCM)
| Format |
Macro |
Where |
| INS tag |
data-dcm-click-tracker="%%CLICK_URL_UNESC%%" |
On the <ins> element |
| JavaScript tag |
;click0=%%CLICK_URL_ESC%% |
Appended to src query string |
| IMG redirect |
;click=%%CLICK_URL_UNESC%% |
Appended after ord= |
| Any format |
ord=%%CACHEBUSTER%% |
Cache-busting token in tag URL |
Gotcha: The legacy DCM iframe format (not INS) is deprecated. GAM doesn't
auto-insert click macros for it, and most publishers reject it. If you see an old iframe
wrapper, trade it for the INS format.
Flashtalking
| Macro |
Where |
clickTrack=%%CLICK_URL_UNESC%% |
Query param on Flashtalking URL |
cachebuster=%%CACHEBUSTER%% |
Query param |
ftXGdpr=${GDPR} |
GDPR flag |
ftXGdprConsent=${GDPR_CONSENT_755} |
TCF string |
Insertion method: append_param with & separator.
Sizmek / Amazon Ad Server
| Macro |
Where |
;;;;clk=%%CLICK_URL_UNESC%% |
Before the final ? or at tag end |
rnd=%%CACHEBUSTER%% |
Query param |
ord=%%CACHEBUSTER%% |
Alternative CB form on some placements |
Gotcha: Sizmek tags delimit with semicolons, not ampersands. Inserting
with & breaks the tag.
Innovid
| Macro |
Where |
ct=%%CLICK_URL_ESC%% |
Click tracker (URL-encoded) |
cb=[timestamp] |
Innovid prefers its own token, not %%CACHEBUSTER%% |
Gotcha: Innovid uses %%CLICK_URL_ESC%%, not UNESC.
Double-check — GAM will silently pass URLs that break downstream.
Xandr (AppNexus)
| Macro |
Where |
redir=%%CLICK_URL_UNESC%% |
Click param |
cb=%%CACHEBUSTER%% |
Cache bust |
gdpr=${GDPR} |
GDPR flag |
gdpr_consent=${GDPR_CONSENT_755} |
TCF string |
Taboola
| Macro |
Where |
click_url=%%CLICK_URL_UNESC%% |
Query param |
timestamp=%%CACHEBUSTER%% |
Query param |
Criteo
| Macro |
Where |
ct0=%%CLICK_URL_UNESC%% |
Click tracker (unescaped) |
_=%%CACHEBUSTER%% |
Cache bust |
Amazon DSP
| Macro |
Where |
clickurl=%%CLICK_URL_ESC%% |
Query param |
cb=%%CACHEBUSTER%% |
Query param |
DV360
| Macro |
Where |
ddm_click=%%CLICK_URL_UNESC%% |
Click tracker |
cache_buster=%%CACHEBUSTER%% |
Cache bust |
AdForm
| Macro |
Where |
;click=%%CLICK_URL_UNESC%% |
Semicolon-delimited |
;rnd=%%CACHEBUSTER%% |
Semicolon-delimited |
IAS (Integral Ad Science)
| Macro |
Where |
[timestamp] |
Cache bust (IAS-native, GAM will replace) |
[CLICK_URL] |
Click redirect placeholder |
Gotcha: IAS uses bracket-style placeholders, not %% style. They get
replaced by the IAS SDK, not GAM. Don't wrap them in %%.
DoubleVerify
| Macro |
Where |
ctx=%%CLICK_URL_UNESC%% |
Click tracker |
cb=%%CACHEBUSTER%% |
Cache bust |
Nielsen
| Macro |
Where |
cc=%%CACHEBUSTER%% |
Cache bust |
tfcd=${GDPR} |
GDPR flag |
Conversant / Mediaplex
| Macro |
Where |
mpvc=%%CLICK_URL_ESC%% |
Click tracker (escaped) |
mpt=%%CACHEBUSTER%% |
Cache bust (not ord) |
BannerFlow
| Macro |
Where |
cb=%%CACHEBUSTER%% |
Cache bust |
redirecturl=%%CLICK_URL_ESC%% |
Click tracker (escaped) |
EyeReturn
| Macro |
Where |
click=%%CLICK_URL_UNESC%% |
Click tracker |
cb=%%CACHEBUSTER%% |
Cache bust |
Weborama
| Macro |
Where |
%%CLICK_URL_UNESC%% |
Prepended to Weborama URL |
BridgeTrack
| Macro |
Where |
click=%%CLICK_URL_UNESC%% |
Click tracker |
%n |
BridgeTrack-native cache bust; ok to leave |
Yahoo ADTECH
| Macro |
Where |
rdclick=%%CLICK_URL_ESC%% |
Click tracker (escaped) |
cb=%%CACHEBUSTER%% |
Cache bust |
CreativeValidator detects the vendor and auto-inserts the correct macros for 30+
platforms. Paste a tag, see exactly what's missing and where it should go.
Test a tag →
The five failure modes that cause 90% of broken tags
-
Wrong escape level. Using
%%CLICK_URL_UNESC%% where the
vendor expects escaped, or vice versa. Symptoms: click-through goes to a mangled URL or
doesn't fire at all.
-
Missing cache buster. Symptom: impressions under-count, sometimes by
50%+. Most impression pixels hit the same CDN endpoint per session and get deduped.
-
Semicolon vs ampersand delimiters. Sizmek and DCM legacy use
;. Mis-inserting with & breaks the whole tag.
-
GDPR macros in non-EEA placements. Not a blocker, just wasted macro
space. But some vendors (Criteo, Xandr) refuse to serve when
${GDPR}=1 and
${GDPR_CONSENT_755} is empty. You need both or neither.
-
Macro inside a string that gets URL-encoded. If the tag is pasted into
a system that encodes the whole URL before serving,
%%CLICK_URL_UNESC%% becomes %25%25CLICK_URL_UNESC%25%25 and
never resolves.
How we test this
CreativeValidator scans every tag through a headless browser, captures the actual network
requests, and compares them against the vendor's known click/impression endpoints. If a
tag fires to Flashtalking but no clickTrack param is present, we flag it —
along with the exact macro string to insert and where.