Requesting ads
The Ad API is how a player asks for ads to show and reports what happened during playback. It is public: no access token or project header. The two endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/v1alpha2/ads |
GET | Request an ad decision (VAST XML) |
/v1alpha2/track |
GET | Report a playback event |
The /v1alpha2/track path is illustrative. The player never builds this URL. The server stamps the real tracking URLs inside the VAST. Read them verbatim from each <Impression> and <Tracking>, then append &ets=<now> and fire. The host, path, and query params are all server-owned; treat them as opaque.
This section is split into focused pages; start here, then follow the loop below into the detail.
Before the player starts
Section titled “Before the player starts”| Prerequisite | How the player gets it |
|---|---|
| Base URL per environment | Provided at onboarding (sandbox host for integration, production host for live traffic). |
| Player identity | A retailer-scoped playerid + key, issued when the player’s device and retailer scope are provisioned. |
Conventions:
- All endpoints are HTTPS. No auth beyond the player’s
playerid+key. - Timestamps are RFC3339, UTC (
2026-05-28T14:32:05.1234Z). Appendetsin this format on every fire. The server deduplicates on the parsed instant: two distinct fires must carry different timestamps, and a replayed fire must carry its originalets. Keep the device clock healthy.
The loop
Section titled “The loop”This is the whole integration. Everything after it is detail.
Online, per slot:
GET /v1alpha2/ads?playerid=…&key=…(add audience signals withseg/products, and&dvactid=…if the player’s sensor gave the player one) → VAST XML. An empty<VAST/>means no ad: play from the player’s stored playlist.- Play each
<Ad>, dispatching on its<MediaFile type>(video, image, or HTML5). - As each playback event happens, fire that event’s URL straight from the VAST, appending
&ets=<now>. That means<Impression>+startwhen the creative first renders, andcompletewhen it ends (or itsDurationelapses).
Offline (device loses connectivity):
- Ahead of time:
GET …&offline=true, store the playlist AND download each ad’s creative. - While offline: play from the stored playlist, buffer every fire (URL +
ets). - On reconnect: replay the buffered fires as GETs (staggered, so a whole site doesn’t reconnect in lockstep).
Two rules carry most of the design:
- The player fires every pixel. Read each
<Impression>and<Tracking>URL straight from the VAST and fire it, appendingetson every fire. With a VAST SDK, drive fires from its progress callbacks and disable its built-in firing: a stock SDK won’t appendetsor buffer offline fires. - Relay each tracking URL verbatim and never parse its query params. Every param the server stamped (
asid,ae,ce,sts) is opaque: treat them as an indivisible URL.
Per-ad identity and metadata
Section titled “Per-ad identity and metadata”Each <Ad> carries a <Extension type="verve-metadata"> with JSON:
| Field | What the player uses it for |
|---|---|
expires_at |
Drop the ad at slot time once past it. Bound stored ads with the player’s own max TTL too. |
request_id |
Group all ads from one /ads response (correlation / debug). |
flight_id |
Verve attribution. Optional, present only for Verve-booked ads. |
campaign_id |
Attribution / debug. Optional. |
source |
Which kind of source served the ad: SOURCE_TYPE_AD_SERVER, SOURCE_TYPE_SSP, or SOURCE_TYPE_CMS. |
source_id |
The specific source this ad came from (a particular CMS, SSP, or ad server). Offline, the key the player groups by to honor the player’s source mix. |
audience |
Offline selection: the flight’s dynamic targeting (targeting_groups) to match against the player’s locally detected audience, cart, and weather. Present only for targeted Verve ads; see Matching audience offline. |
expires_at drives player behavior for every ad, and audience drives offline selection for the ads that carry it; the rest are optional attribution. Ignore any JSON field or <Extension type> the player does not recognize, and skip any <Ad> whose Extension JSON is malformed (play the others). New fields and types may be added, and older players must keep working.
Some ads also carry a VAST-native <Pricing model="cpm" currency="EUR"> element. It is informational: the player does not need it to render or fire, and it may be absent for CMS or fallback content. Read the price from this <Pricing> element, not from verve-metadata.
Cache creatives by their media URL and key the player’s asset cache on it. The <Creative id> attribute is the logical creative identifier.
For which events to fire on each ad and when, see Reporting exposure.
Where to go next
Section titled “Where to go next”| Page | What it covers |
|---|---|
| Basic request | The core GET /v1alpha2/ads request: parameters, modes, response envelope, status codes, and the player’s MUST / MUST NOT contract. |
| Demographics | Refining selection online with the seg signal: IAB segment composition, per-sensor interpretation, and validation. |
| Products | Refining selection online with the shopper’s basket via products. |
| Operating offline | Pre-fetching, storing, and rotating a playlist offline; honoring the source mix; matching audience locally. |
| Creative formats | Rendering video, image, and HTML5 creatives, with worked VAST examples. |
| Reporting exposure | Firing playback events to GET /v1alpha2/track, which events fire when, and offline buffering. |
For full request and response schemas, see the Ad API reference. The response envelope follows the IAB VAST 4.2 standard.