A VAST macro is a placeholder token inside an ad tag URL - like [CACHEBUSTING], %%CACHEBUSTER%%, or ROKU_ADS_CACHE_BUSTER - that the video player, ad server, or SSAI stitcher swaps for a real value the instant an ad is requested. One static tag becomes a live, per-request tag carrying a cache-buster, a timestamp, the device advertising ID, the viewer's consent string, the page URL, and the player size.
Miss the macros and everything downstream breaks quietly: caches and CDNs collapse identical requests, impression counts go wrong, targeting has nothing to work with, and privacy signals never reach the ad server. This is the exhaustive reference - the syntax used by IAB VAST, Google Ad Manager, and Roku's RAF, every standard macro with what the player substitutes, a worked example, and the privacy macros you cannot skip. To assemble and test a tag hands-on, use the VAST Macro Builder.
Why a static ad tag needs macros
An ad tag is just a URL. When the ad break arrives the player fetches it, and the ad server responds with VAST XML describing the ad. But the same URL is fetched millions of times - on different devices, for different viewers, under different privacy regimes. A macro is how one URL adapts to each of those requests.
Three things go wrong without macros:
- Caching and counting. Identical URLs get cached by browsers, CDNs, and proxies. The
[CACHEBUSTING]macro drops a random number into every request so each one is unique - which is what stops impression and tracking beacons from being deduplicated. - Targeting. The ad server needs context to choose an ad: content ID, genre, player size, geo, device type. Macros carry that context on the request.
- Privacy and compliance. GDPR consent, US Privacy (CCPA), COPPA / child-directed, and limit-ad-tracking signals all travel as macros. If they are missing, the ad server has to assume the worst - and buyers drop their bids.
Macro syntax: three ecosystems, one idea
The concept is universal; only the delimiters change. You will meet three syntaxes.
| Ecosystem | Syntax | Cache-buster example | Where it is filled |
|---|---|---|---|
| IAB VAST 4.x (cross-platform standard) | [MACRO] | [CACHEBUSTING] | Any spec-compliant player |
| Google Ad Manager / IMA SDK | %%MACRO%% and ${MACRO} | %%CACHEBUSTER%% | Google Ad Manager |
| Roku Advertising Framework (RAF) | bare ROKU_ADS_* token as a value | ROKU_ADS_CACHE_BUSTER | Roku RAF on-device |
A few rules apply everywhere:
- Macros live in the query string of the tag (
?key=[MACRO]&key2=[MACRO2]). The parameter names (key) are defined by the receiving ad server; the macro token is the value. - The component that owns the tag at each hop does the substitution. A player or SSAI stitcher fills client-side macros (device ID, IP, player size) before it calls the ad server; an ad server can fill more and forward the rest to any downstream wrapped tag.
- An unfilled macro should be dropped or left blank - never sent literally. A request that still contains a raw
[IFA]tells the ad server your integration is broken.
The IAB VAST standard macros
These are defined by the IAB Tech Lab in the VAST 4 macro specification and work in any spec-compliant player, whatever your ad server. They are the portable baseline: support these and your tags travel. Square brackets are the delimiter.
| Macro | Category | What the player substitutes | Example |
|---|---|---|---|
[TIMESTAMP] | Generic | Date/time the URI is fired, ISO 8601 with millisecond precision. | 2026-07-07T14:32:05.123Z |
[CACHEBUSTING] | Generic | Random 8-digit integer that defeats caches so each fire counts. | 48213307 |
[CONTENTPLAYHEAD] | Ad break | Content playhead at ad time. Deprecated in 4.1 - use MEDIAPLAYHEAD. | 00:12:31.500 |
[MEDIAPLAYHEAD] | Ad break | Playhead position of the main content (not the ad). | 00:12:31.500 |
[ADPLAYHEAD] | Player state | Playhead position within the ad creative, HH:MM:SS.mmm. | 00:00:07.500 |
[BREAKPOSITION] | Ad break | Break position: 1 pre-roll, 2 mid-roll, 3 post-roll, 4 standalone. | 2 |
[BLOCKEDADCATEGORIES] | Ad break | Comma-separated IAB category codes the player will not accept. | IAB7,IAB25 |
[ADCATEGORIES] | Ad break | Comma-separated desired IAB category codes for the slot. | IAB1,IAB3 |
[ADCOUNT] | Ad break | Number of ads expected by the player / played in the chain. | 1 |
[TRANSACTIONID] | Ad break | UUID that correlates a chain of ad requests end to end. | 3b8e2f10-9a1c-4c1e-9c1a-2f2a9d0f1e77 |
[PLACEMENTTYPE] | Ad break | AdCOM placement subtype (1 in-stream, 2 accompanying, ...). | 1 |
[ADTYPE] | Ad break | Intended ad use: video, audio, or hybrid. | video |
[UNIVERSALADID] | Ad break | Universal Ad ID as 'registry value'. | ad-id.org 8465 |
[BREAKMAXDURATION] | Ad break | Maximum ad-break length in seconds. | 90 |
[BREAKMAXADS] | Ad break | Maximum number of ads allowed in the break. | 3 |
[BREAKMINADLENGTH] | Ad break | Minimum single-ad length in seconds. | 5 |
[BREAKMAXADLENGTH] | Ad break | Maximum single-ad length in seconds. | 30 |
[IFA] | Client | Resettable device ad ID (IDFA / AAID / Roku RIDA) as a UUID. | 38400000-8cf0-11bd-b23e-10b96e40000d |
[IFATYPE] | Client | Type of the IFA (e.g. rida, idfa, aaid, sspid). | rida |
[CLIENTUA] | Client | User-Agent of the player / VAST client processing the ad. | MyPlayer/2.1 (VAST 4.2) |
[SERVERUA] | Client | User-Agent of a server making the request on the client's behalf. | AdStitcher/1.0 |
[DEVICEUA] | Client | User-Agent of the device rendering the ad. | Roku/DVP-12.0 (12.0.0) |
[SERVERSIDE] | Client | 0 client-requested, 1/2 server-requested (SSAI). | 0 |
[DEVICEIP] | Client | IP address of the device rendering the ad. | 203.0.113.7 |
[LATLONG] | Client | Device geolocation as 'lat,long'. | 37.4220,-122.0841 |
[DOMAIN] | Publisher | Domain of the top-level page where the ad is shown. | example.com |
[PAGEURL] | Publisher | Full URL of the top-level page where the ad is shown. | https://example.com/watch/movie |
[APPBUNDLE] | Publisher | Platform-specific app bundle / package name. | com.example.streaming |
[STOREID] | Publisher | App store ID (iTunes, Google Play, Roku, etc.). | 592090 |
[STOREURL] | Publisher | App store URL for the installed app. | https://channelstore.roku.com/details/592090 |
[VASTVERSIONS] | Capabilities | Supported VAST versions as codes (2,3,6=4.0,7=4.1,8=4.2). | 2,3,6,7,8 |
[APIFRAMEWORKS] | Capabilities | Supported API frameworks (e.g. 7 = OMID). | 7 |
[EXTENSIONS] | Capabilities | VAST Extension types the player supports. | AdVerifications |
[VERIFICATIONVENDORS] | Capabilities | Verification vendors the player supports. | doubleverify.com |
[OMIDPARTNER] | Capabilities | OM SDK integration as 'name/version'. | Roku/1.4.2 |
[MEDIAMIME] | Capabilities | Supported media MIME types. | video/mp4,application/x-mpegURL |
[PLAYERCAPABILITIES] | Capabilities | Player capabilities: skip, mute, fullscreen, ... | skip,mute,autoplay |
[CLICKTYPE] | Capabilities | Type of clickthrough the player supports. | 2 |
[PLAYERSTATE] | Player state | Current player state: muted, fullscreen, ... | fullscreen |
[INVENTORYSTATE] | Player state | Inventory attrs: skippable, autoplayed, mutedautoplay. | autoplayed,skippable |
[PLAYERSIZE] | Player state | Player 'width,height' in device-independent pixels. | 1920,1080 |
[ASSETURI] | Player state | URI of the ad asset currently playing. | https://cdn.example.com/ad.mp4 |
[CONTENTID] | Player state | Publisher content ID as 'registry value'. | myreg 98765 |
[CONTENTURI] | Player state | URI of the main content receiving the ad. | https://cdn.example.com/movie.m3u8 |
[PODSEQUENCE] | Player state | Sequence of the currently playing ad in the pod. | 1 |
[ADSERVINGID] | Player state | AdServingId of the currently playing ad. | a1b2c3d4e5 |
[CLICKPOS] | Click | Click coordinates 'x,y' in CSS pixels relative to the player. | 640,360 |
[ERRORCODE] | Error | VAST error code, substituted in the Error URI when an error fires. | 303 |
[REASON] | Verification | Reason code for not executing a verification script. | 2 |
[LIMITADTRACKING] | Regulation | 1 if the user opted into limited ad tracking, else 0. | 0 |
[REGULATIONS] | Regulation | Applicable regulations (coppa, gdpr). | gdpr |
[GDPRCONSENT] | Regulation | Base64 IAB TCF consent string. | CPcqB8APcqB8AAKAsAENCZCgAP |
[GPPSTRING] | Regulation | Global Privacy Platform (GPP) encoded string. | DBABzw~1YNN~ |
[GPPSECTIONID] | Regulation | GPP section IDs to apply. | 2,6 |
[DSAREQUIRED] | Regulation | Flag: DSA transparency info should be made available. | 1 |
[DSAPARAMS] | Regulation | DSA user parameters applied by the platform. | 1,2 |
[DSAPUBRENDER] | Regulation | Signal whether the publisher renders DSA info. | 0 |
[PLAYBACKMETHODS] | Player state | Autoplay / click-to-play inventory attributes. | 2 |
[CONTENTCAT] | Ad break | Content category IDs (IAB Tech Lab taxonomy). | IAB1 |
A handful appear on almost every tag: [CACHEBUSTING] (defeat caches), [TIMESTAMP], [IFA] + [IFATYPE] + [LIMITADTRACKING] (device identity and opt-out), [DEVICEIP] and [DEVICEUA] (client), [DOMAIN] / [PAGEURL] / [APPBUNDLE] (where the ad runs), [PLAYERSIZE], and the regulation set [GDPRCONSENT] / [GPPSTRING] / [REGULATIONS].
Google Ad Manager macros
Google Ad Manager and the IMA SDK predate some of the IAB tokens and use their own %%MACRO%% syntax, with ${MACRO} for privacy signals. If you serve through GAM, these are the tokens you place in the tag; GAM fills them.
| Macro | Category | What the player substitutes | Example |
|---|---|---|---|
%%CACHEBUSTER%% | Cachebusting | Random number for accurate impression counting. | 48213307 |
%%VIDEO_AD_DURATION_SECONDS%% | Timing | Video ad length in seconds. | 30 |
%%VIDEO_DURATION%% | Timing | Video ad length in milliseconds. | 30000 |
%%IMPRESSIONS_EXPIRATION_WINDOW_MINUTES%% | Timing | Impression processing window in minutes. | 60 |
%%CLICK_URL_UNESC%% | Redirect | Unescaped Google click-tracking URL (prepend to your clickthrough). | https://pubads.g.doubleclick.net/pcs/click?xai=AKA |
%%CLICK_URL_ESC%% | Redirect | Escaped click-tracking URL (one level). | https%3A%2F%2Fpubads.g.doubleclick.net%2Fpcs%2Fclick |
%%CLICK_URL_ESC_ESC%% | Redirect | Double-escaped click-tracking URL (for nested redirects). | https%253A%252F%252Fpubads |
%%DEST_URL_UNESC%% | Redirect | Unescaped final destination (clickthrough) URL. | https://advertiser.example/landing |
%%REFERRER_URL_UNESC%% | Redirect | Unescaped page referrer URL. | https://example.com/watch |
%%DESCRIPTION_URL_UNESC%% | Redirect | Unescaped video description URL (for targeting). | https://example.com/movie-page |
%%SCHEME%% | Redirect | http: or https: to match page security. | https: |
${GDPR} | Privacy | 1 if GDPR applies to the request, else 0. | 1 |
${GDPR_CONSENT_XXXX} | Privacy | TCF consent string; replace XXXX with your IAB GVL ID. | CPcqB8APcqB8AAKAsAENCZCg |
${ADDTL_CONSENT} | Privacy | Google Additional Consent string (non-TCF vendors). | 2~1.35.41~dv.9 |
%%TFUA%% | Privacy | Tag-for-under-age-of-consent flag (value 1). | 1 |
%%TAG_PARAM:us_privacy%% | Privacy | US Privacy (CCPA) string passed on the tag. | 1YNN |
%%VIDEO_ID%% | Content | Unique video content identifier. | movie-987 |
%%CMS_ID%% | Content | Content source / CMS identifier. | 2496 |
%%VIDEO_TITLE%% | Content | Video title for reporting / targeting. | Comedy Special |
%%ADVERTISING_IDENTIFIER_PLAIN%% | Device | Resettable device advertising ID. | 38400000-8cf0-11bd-b23e-10b96e40000d |
%%ADVERTISING_IDENTIFIER_IS_LAT%% | Device | Limit Ad Tracking flag for the device. | 0 |
%%TAG_PARAM:vpmute%% | Player | Video player mute state passed on the tag. | 0 |
%%TAG_PARAM:vpos%% | Player | Video position (preroll/midroll/postroll). | preroll |
%eaid! | IDs | Line item ID. | 5839201 |
%ecid! | IDs | Creative ID. | 138472913 |
%eadv! | IDs | Advertiser ID. | 90311 |
%epid! | IDs | Ad unit ID. | 22887 |
Two GAM-specific things are worth knowing. First, the click and destination URL macros come in three escaping levels - _UNESC, _ESC, and _ESC_ESC - because a click URL is often nested inside another redirect, and each hop needs one more level of URL-encoding. Second, consent uses ${...}, not %%...%%: ${GDPR}, ${GDPR_CONSENT_XXXX} (replace XXXX with your IAB Global Vendor List ID), and ${ADDTL_CONSENT}.
Roku RAF macros
Roku's Advertising Framework (RAF) differs in one important way. Instead of embedding a delimited token, you set the bare ROKU_ADS_* keyword as the value of a query parameter, and RAF replaces the whole value at request time. So &dev=ROKU_ADS_TRACKING_ID becomes &dev=<the RIDA>. RAF is the on-device library that renders ads in Roku channels, so these are the macros available when you serve into Roku's SDK.
| Macro | Category | What the player substitutes | Example |
|---|---|---|---|
ROKU_ADS_TRACKING_ID | Client | RIDA - Roku ID for Advertising (resettable device ad ID). | 38400000-8cf0-11bd-b23e-10b96e40000d |
ROKU_ADS_LIMIT_TRACKING | Regulation | 1 if the user enabled Limit Ad Tracking, else 0. | 0 |
ROKU_ADS_APP_ID | Publisher | Channel / app identifier making the request. | 592090 |
ROKU_ADS_APP_VERSION | Publisher | Channel application version string. | 2.3.1 |
ROKU_ADS_LIB_VERSION | Capabilities | RAF (Roku Advertising Framework) library version. | 3.2 |
ROKU_ADS_CONTENT_ID | Content | Content identifier for targeting. | movie-987 |
ROKU_ADS_CONTENT_GENRE | Content | Content genre / category for targeting. | comedy |
ROKU_ADS_CONTENT_LENGTH | Content | Content duration in seconds. | 5400 |
ROKU_ADS_USER_AGENT | Client | Device model and Roku OS version. | Roku/DVP-12.0 (12.0.0) |
ROKU_ADS_DEVICE_MODEL | Client | Roku device model identifier. | 4800X |
ROKU_ADS_EXTERNAL_IP | Client | Device external IP address. | 203.0.113.7 |
ROKU_ADS_DISPLAY_WIDTH | Player | Display width in pixels. | 1920 |
ROKU_ADS_DISPLAY_HEIGHT | Player | Display height in pixels. | 1080 |
ROKU_ADS_TIMESTAMP | Generic | Milliseconds since the Unix epoch (GMT). | 1783432325123 |
ROKU_ADS_CACHE_BUSTER | Generic | Unique value to prevent cached responses / dedupe beacons. | 48213307 |
ROKU_ADS_KIDS_CONTENT | Regulation | Flag indicating child-directed content (COPPA). | false |
ROKU_ADS_LOCALE | Client | Current locale (e.g. en_US, es_ES). | en_US |
Privacy and consent macros: do not skip these
Consent is the one area where a missing macro is not just a data-quality problem - it is a compliance and revenue problem. Buyers drop bids when they cannot read a consent signal. Here is how the major regimes map across the three ecosystems.
| Regime | IAB VAST | Google Ad Manager | Roku RAF |
|---|---|---|---|
| GDPR / TCF (Europe) | [REGULATIONS]=gdpr, [GDPRCONSENT] | ${GDPR}, ${GDPR_CONSENT_XXXX}, ${ADDTL_CONSENT} | pass the TCF string on your own param |
| US Privacy / CCPA | pass us_privacy string | %%TAG_PARAM:us_privacy%% | pass us_privacy string |
| GPP (Global Privacy Platform) | [GPPSTRING], [GPPSECTIONID] | pass the GPP string on your own param | pass the GPP string on your own param |
| Children / COPPA | [REGULATIONS]=coppa | %%TFUA%% | ROKU_ADS_KIDS_CONTENT |
| Limit ad tracking | [LIMITADTRACKING] | %%ADVERTISING_IDENTIFIER_IS_LAT%% | ROKU_ADS_LIMIT_TRACKING |
Advanced macros, decoded: the consent strings
Most macros carry a simple value. A few carry an encoded string whose individual characters each mean something, and getting one character wrong makes a demand partner silently drop the bid. These are the macros worth reading closely.
Breaking down the us_privacy string
The us_privacy string - the CCPA / US Privacy signal, carried by %%TAG_PARAM:us_privacy%% in Google Ad Manager and on your own parameter for IAB VAST and Roku RAF - is defined by the IAB Tech Lab and is exactly four characters. Each position is a single flag:
| Char | Field | Values | What it means |
|---|---|---|---|
| 1 | Specification version | 1 | Version of the US Privacy spec. Today this is always 1. |
| 2 | Explicit notice | Y / N / - | Was the consumer given notice and a chance to opt out? Y yes, N no, - not applicable. |
| 3 | Opt-out of sale | Y / N / - | Has the consumer opted out of the sale of their data? Y opted out, N not opted out, - not applicable. This is the character buyers act on. |
| 4 | Limited Service Provider Agreement | Y / N / - | Is the transaction covered by the IAB LSPA? Y covered, N not covered, - not applicable. |
Read left to right. 1YNN means "version 1, notice given, the user has not opted out, not covered by the LSPA" - a normal, fully addressable US request. Flip the third character to 1YYN and the user has opted out: partners like Google then apply Restricted Data Processing (RDP) and Roku's RAF limits what it passes downstream, so expect fewer targeted bids. When CCPA does not apply at all, the optional fields use the not-applicable hyphen, giving 1---. The one string you must never emit is a literal, unresolved macro: if us_privacy=%%TAG_PARAM:us_privacy%% reaches the ad server unfilled, the request is malformed and demand collapses.
GDPR (TCF) and GPP strings
Europe's signals work the same way but are longer and Base64-encoded rather than human-readable. ${GDPR} (or [REGULATIONS]=gdpr) is a single 1/0 flag for "does GDPR apply?", while ${GDPR_CONSENT_XXXX} and [GDPRCONSENT] carry the full IAB TCF v2 consent string - a Base64 payload encoding purposes and vendor permissions that the SSP decodes, not you. The newer Global Privacy Platform string ([GPPSTRING] with [GPPSECTIONID]) is one container that can carry the US Privacy, US-state, and TCF sections together. You never hand-edit these - a consent management platform produces them - but you must pass them through unmodified and never URL-encode them twice.
A worked example: build a VAST tag with macros
Start with a plain base tag - an ad-server endpoint with a placement. It works, but it is blind:
https://ads.example-ssp.com/vast?slot=preroll&app=com.example.tv
Add a cache-buster so every request is unique and beacons count, then device identity so the buyer can frequency-cap and target (with the opt-out flag), then context - where the ad runs and how big the player is - and finally consent, without which much of the demand disappears. Put together, the authored tag is:
https://ads.example-ssp.com/vast?slot=preroll
&cb=[CACHEBUSTING]
&ifa=[IFA]&ifa_type=[IFATYPE]&lat=[LIMITADTRACKING]
&app=[APPBUNDLE]&url=[PAGEURL]&size=[PLAYERSIZE]&content=[CONTENTID]
&gdpr=[REGULATIONS]&gdpr_consent=[GDPRCONSENT]
At request time the player substitutes each token, and the ad server receives a concrete URL:
https://ads.example-ssp.com/vast?slot=preroll
&cb=48213307
&ifa=38400000-8cf0-11bd-b23e-10b96e40000d&ifa_type=rida&lat=0
&app=com.example.streaming&url=https%3A%2F%2Fexample.com%2Fwatch&size=1920%2C1080&content=movie-987
&gdpr=gdpr&gdpr_consent=CPcqB8APcqB8AAKAsAENCZCg
That is exactly what the VAST Macro Builder does: tick the macros you need and it shows both the authored tag and a simulated filled request. Send that request with the VAST Ad Tag Simulator to preview the exact URL, headers, and curl command a Roku or Fire TV player would use, then parse what the ad server returns - inline ad, wrapper, media files, tracking, or a no-fill. Paste the VAST XML into the VAST Tag Validator to confirm the response is spec-valid.
Best practices and common mistakes
- Match the syntax to the consumer. Sending
[CACHEBUSTING]to Google Ad Manager (which wants%%CACHEBUSTER%%) leaves the token unfilled. Know which system reads the tag. - Never send an unfilled macro literally. If a value is unavailable, drop the parameter or send it empty. A raw
ifa=[IFA]reaching the ad server is a bug. - Get the escaping level right. In redirect chains, each extra hop needs one more layer of URL-encoding - that is why GAM offers
_ESCand_ESC_ESCvariants. - Carry macros down the wrapper chain. In a VAST wrapper, macros on the outer
VASTAdTagURImust be forwarded to the wrapped tag, or the final ad server gets nothing. - Always include the privacy set. Missing consent macros suppress demand and create compliance exposure. Add them by default, not on request.
- Test with real tokens filled. Use the builder's simulated request to sanity-check the URL, then validate the returned XML.
The bottom line
Macros are the small, unglamorous plumbing that makes a single ad tag work across every device, viewer, and privacy regime. The three ecosystems - IAB VAST, Google Ad Manager, and Roku RAF - express the same handful of ideas (cache-bust, identify, contextualize, obtain consent) in different delimiters. Learn the cache-buster, the device ID, the context, and the consent macros for the system you serve through, keep the full reference handy, and never let an unfilled token reach the ad server.
Frequently Asked Questions
What is a VAST macro?
A VAST macro is a placeholder token in an ad tag URL - such as [CACHEBUSTING] or %%CACHEBUSTER%% - that the video player, ad server, or SSAI stitcher replaces with a real value (a cache-buster, timestamp, device ID, consent string, page URL) at the moment the ad is requested. It lets one static tag carry per-request context.
How do IAB, Google, and Roku macro syntaxes differ?
IAB VAST uses square brackets, e.g. [CACHEBUSTING]. Google Ad Manager uses %%CACHEBUSTER%% and ${GDPR} for privacy signals. Roku RAF uses bare tokens such as ROKU_ADS_CACHE_BUSTER placed as a query-parameter value. The concept is identical; only the delimiters differ.
Which macro is the cache-buster, and why does it matter?
IAB VAST: [CACHEBUSTING]. Google Ad Manager: %%CACHEBUSTER%%. Roku RAF: ROKU_ADS_CACHE_BUSTER. It inserts a random value so browsers, CDNs, and proxies cannot dedupe the request. Without it, impression and tracking beacons are collapsed and your counts are wrong.
How do I pass GDPR and CCPA consent in a VAST tag?
For GDPR / TCF use IAB [REGULATIONS]=gdpr with [GDPRCONSENT], or GAM ${GDPR} + ${GDPR_CONSENT_XXXX} + ${ADDTL_CONSENT}. For US Privacy / CCPA pass the us_privacy string (in GAM, %%TAG_PARAM:us_privacy%%). For the newer Global Privacy Platform use IAB [GPPSTRING] and [GPPSECTIONID].
Who replaces the macros - the player or the ad server?
Whichever component owns the tag at that hop. A player or SSAI stitcher fills client-side macros (device ID, IP, player size) before calling the ad server; the ad server can fill more and forward the rest to any downstream wrapped tag. An unfilled macro should be dropped or left blank, never sent literally.
What happens if a macro is not filled in?
The literal token (for example [IFA]) reaches the ad server, which cannot use it, and it may break targeting or parsing. Best practice is to omit the parameter or leave it empty when a value is unavailable, and to test the tag with the macros filled before going live.
Do macros go in the VAST XML or the ad tag URL?
Primarily in the ad tag URL - the request the player makes. Macros also appear inside the returned VAST XML on tracking and error URLs - for example [CACHEBUSTING] on an Impression beacon or [ERRORCODE] on an Error URL - which the player fills when it fires those pixels.
Are VAST macros the same across VAST 2, 3, and 4?
The IAB macro list is versioned with VAST 4 but is designed to be usable with any VAST version. Older tags leaned on ad-server-specific macros (like Google's %%CACHEBUSTER%%); VAST 4 standardized a portable set in square brackets. Newer macros such as GPP and DSA are added to the IAB list as regulations evolve.