CTV integration
Connected TV runs the same two-key model as the web: a delivery report, a device confirmation, a match, and a claim — except the claim usually happens on the viewer's phone. There are three integration paths, depending on how your app is built.
Path 1 — Web-based apps (works today)
If your TV app is HTML5/JavaScript (the common case on smart-TV and streaming-stick
platforms), the integration is the publisher integration,
unchanged: include the tag, call trackVideo() with your completion threshold,
and the tag reports delivery plus a completion_confirm carrying
completion_pct and view_duration_ms. Give the slot a name
containing ctv (for example slot: "ctv-preroll") so verified
views are treated as CTV pairs for phone notifications. The earn mark can render on the TV
UI as well, but the phone claim below is the primary surface.
Path 2 — Ad-server beacons, server-to-server (works today)
Native apps and SSAI setups report through the ad server instead. Both keys are plain posts to the same ingest endpoint — no session required:
POST https://api.myadrewards.com/v1/events
{ "v": 1, "event_type": "delivery_report", "source": "publisher",
"publisher_id": "pub_123", "app_id": "ctv_app_1",
"identity_token": "…the screen's server-minted token…",
"creative_id": "adv_42:cre_7", "campaign_id": "cmp_9",
"slot": "ctv-preroll", "nonce": "…16 hex, one per break…",
"ts": "2026-09-27T20:00:00Z" }
{ "v": 1, "event_type": "completion_confirm", "source": "device",
"publisher_id": "pub_123", "app_id": "ctv_app_1",
"identity_token": "…same token…", "nonce": "…same nonce…",
"completion_pct": 100, "view_duration_ms": 30000,
"ts": "2026-09-27T20:00:30Z" }
The binding rules are the same as the web: both halves must carry the same
nonce, publisher_id, and identity_token, and arrive
within the 10-minute match window; timestamps are rejected if older than 24 hours or more
than 5 minutes in the future. The field table in the
publisher guide, §4 applies as-is.
Device binding. The identity_token is what ties the break
to a household screen. For a screen to earn, its token must be
server-minted — issued by the API for the viewer's account and that screen
(see API reference) — and the screen must be paired to the account,
next section. A self-generated token still lets you report and measure, but the screen is
not registered, so no claim notification is created.
Native CTV SDKs (Android TV, tvOS, Roku, Fire TV) and a formal standalone CTV specification document are on the roadmap. Today, web-based apps use the JavaScript tag and native apps use the beacon path above — both are fully supported by the ingest API as documented here.
Pairing a screen to an account
Viewers link a TV to their account with a short code, from the wallet:
- 1
The wallet mints a code (signed in):
POST /v1/identity/pairing-codes→201 { "code": "XXXX-XXXX" }. Codes are 8 characters from an unambiguous alphabet, live 10 minutes, and are single-use. - 2
The TV confirms the code the viewer types in (no session — the code itself is the capability):
POST /v1/identity/pairing/confirmwith{ "code": "…", "device_id": "…", "label": "Living room TV", "kind": "ctv" }. The response is the registered screen:{ device_id, user_id, label, kind, registered_at, revoked }. - 3
Manage screens in the wallet: list paired screens, revoke any of them. Re-confirming the same screen on the same account is idempotent; a screen already linked to a different account is refused.
The phone claim
When a CTV pair verifies on a registered screen, the viewer's wallet
gets a claim notification. Notifications are created only for CTV pairs (a
completion_confirm, or a slot containing ctv) on registered
devices:
GET /v1/notifications (wallet session)
{ "notifications": [
{ "id": "…", "nonce": "…", "points": 25, "status": "claimable",
"created_at": "…", "expires_at": "…" } ],
"total": 1 }
Tapping one claims it — POST /v1/claims/impressions/{nonce} with the wallet
session — and the points land in the same wallet as every other surface. Outcomes:
200 claimed · 404 unknown view · 403 not the
viewer's · 409 already claimed · 410 claim window closed ·
402 funding couldn't cover it.
Unregistered TVs
Nothing changes for the viewer. Ads play exactly as before, no badge or prompt appears on the TV, no notification is created, and no reward accrues. Registration is what turns a screen into an earning screen — measurement via the beacon path works either way, but earning starts at pairing.