Basic request
The smallest useful call to /v1alpha2/ads is just the player identity. This is the baseline every player must support.
GET /v1alpha2/ads?playerid=screen-01&key=retailer-acme| Param | Required | Description |
|---|---|---|
playerid |
yes | The player’s device id, scoped by key. |
key |
yes | Retailer scope for playerid. |
The server selects using whatever it already knows about the device: its configuration (location, zone, ad networks, supported formats) and any audience context previously pushed for it out-of-band via /adsignals (see When signals apply). It returns a fully targeted decision when context exists, or an empty <VAST/> when nothing is eligible (or the device’s context is still warming). See Response.
Additional request parameters
Section titled “Additional request parameters”On top of the required playerid + key identity, the request takes these optional parameters:
GET /v1alpha2/ads?playerid=<player_id>&key=<retailer_key>[&limit=<N>][&source=<SRC>...] HTTP/1.1| Param | Required | Description |
|---|---|---|
limit |
no | How many ads. Online default 1. Offline defaults to the server-side cap; a smaller limit requests fewer. Clamped server-side. |
source |
no | Restrict the response to one or more source types: SOURCE_TYPE_AD_SERVER, SOURCE_TYPE_SSP, SOURCE_TYPE_CMS. Repeatable (&source=SOURCE_TYPE_SSP&source=SOURCE_TYPE_CMS); multiple values are OR’d. Applied after the server’s normal selection, so only matching winners are returned. Default: all sources. In offline mode the server bypasses per-source decision metrics and fetches from all sources, so the player-side rotation (grouped by source_id) is what honors the player’s source mix. |
retail_grocery_zone |
no | The grocery zone the player currently is in, e.g. VENUE_RETAIL_GROCERY_CHECK_OUT. Single-valued; mutually exclusive with retail_mall_zone; requires SENSOR_LOCATION; online only. See Position. |
retail_mall_zone |
no | The mall zone the player currently is in, e.g. VENUE_RETAIL_MALLS_FOOD_COURT. Single-valued; mutually exclusive with retail_grocery_zone; requires SENSOR_LOCATION; online only. See Position. |
aisle |
no | The grocery product aisle the player currently is at, e.g. AISLE_DAIRY. Single-valued; requires SENSOR_LOCATION; online only. Implies the grocery Aisles zone. See Position. |
The offline parameter selects one of two modes:
Online (default)
Section titled “Online (default)”offline=false (or omitted). Ask for an ad to play right now, in the next slot.
- Returns
1ad by default; setlimitto a higher value to get a targeted set. - These ads are for imminent playback — they are not meant to be stored and played later.
GET /v1alpha2/ads?playerid=screen-01&key=retailer-acmeOffline
Section titled “Offline”offline=true. Ask for the full eligible playlist to store on the player and rotate through over time.
- Returns up to a server-side cap; a smaller
limitrequests fewer. - These ads are built to be stored and played later. For how to store and rotate them, see Operating offline.
GET /v1alpha2/ads?playerid=screen-01&key=retailer-acme&offline=trueHow to read a multi-ad response
Section titled “How to read a multi-ad response”A response with more than one ad is a set to choose from, not a playback sequence:
- The ads are independent — pick one per slot.
- Order does not matter — it is not a pod to play back-to-back.
- Store the set, then rotate through it over time.
Two terms to keep separate:
| Term | What it means |
|---|---|
| Playlist | The set of ads the player stores. |
| Creative | Each ad’s <MediaFile> bytes that the player downloads. |
Response
Section titled “Response”Every request returns 200 OK with a VAST 4.2 XML document (Content-Type: application/xml). The body holds zero or more <Ad> elements.
Each ad references a creative in one of three formats:
| Format | <MediaFile type> |
|---|---|
| Video | video/mp4 |
| Image | image/png, image/jpeg |
| HTML5 | application/zip |
Dispatch on the <MediaFile type> attribute to decide how to render each ad. For the full list and rendering rules, see Creative formats.
Empty responses (no-fill)
Section titled “Empty responses (no-fill)”An empty document — <VAST version="4.2"/> with zero <Ad> elements — means no-fill. It is a normal outcome, not an error, and the player should always respond the same way: play from its stored playlist.
A correctly registered screen receives an empty response whenever:
- no ad is currently eligible for it, or
- its audience context is still warming, or
- the
playeridis unknown or not yet registered.
There is no separate “unknown player” status and no 404 — every one of these cases is an empty 200. Treat any empty response as “play from the stored playlist.”
See the Ads API reference for a full response example and schema.
Status codes
Section titled “Status codes”| HTTP | Meaning | The player’s action |
|---|---|---|
200 |
Success (may be empty <VAST/>) |
Play, or fall back to playlist |
400 |
Validation failure, e.g. missing playerid/key; dvactid/seg/products/a position with offline=true; a malformed seg/products value, an unsupported or unknown seg segment, seg on a device with no demographic sensor, or a zone/aisle combination that is not a valid position |
Fix the request |
429 |
Rate-limited (if enforced by the gateway) | Back off per Retry-After |
500 |
Infrastructure failure | Retry with backoff |
A 2xx response carries the VAST document (or an empty body); on any 4xx/5xx the body is a JSON error in google.rpc.Status format.
An unknown, unregistered, or not-yet-warmed playerid does not return an error: the request succeeds with an empty <VAST/> (no-fill). There is no 404 for “unknown player.”
Requirements
Section titled “Requirements”MUST
- Fire every
<Impression>and<Tracking>pixel. With a VAST SDK, disable its built-in firing and drive fires from its progress callbacks. - Fire each stamped event at its lifecycle moment and let the platform decide what counts.
- Append
ets(occurrence time) to every fire, and preserve it unchanged when the player replays a buffered fire. - Fire the server-stamped URLs verbatim: never strip or rewrite the token.
- Treat
<VAST/>as no-fill;4xxas permanent;5xxas transient (retry with backoff, then fall back to playlist). - Drop expired ads from the playlist at slot time.
- Offline, honor the player’s source mix by grouping stored ads by
source_id. - On first boot, run an
offline=truepre-fetch and download its creatives before serving anything. - Refresh the offline playlist before stored ads near
expires_at. - Bound
GET /v1alpha2/adswith a client-side timeout at slot time; fall back to the playlist.
MUST NOT
- Mint or modify the tracking token.
- Block other ads on one ad’s failure.