Docs/Wire contract (v1)

Beacons

Two signals flow back to the server after a fill: a viewability beacon you fire once, and a click that needs no extra call at all.

Viewability — POST /api/v1/serve/viewable

Fire once per ad, when it has been ≥50% on-screen for ≥1 continuous second — the IAB/MRC display standard. Body:

json
{ "imp_id": "<the imp_id from the ad response>" }

No auth, no api_key. Response is {"success": true} (or {"success": true, "duplicate": true} on repeats — treat both as success).

Only fire the viewability beacon when isTrackable / impId != null. House ads and no-fills have no imp_id and cannot be tracked — see Response shapes.

Prefer a fire-and-forget call that survives page/screen teardown: navigator.sendBeacon on the web (with a keepalive-fetch fallback), a best-effort background call on mobile/server SDKs.

Click — GET /api/v1/serve/click?id={imp_id}

Do not call this endpoint directly yourself. For internal ads, creative.click_url already is this URL — opening it performs the redirect and records the click in one step. For house ads, open creative.click_url (the raw advertiser URL) directly instead.

Dedup & lifecycle rules

NameTypeRequiredNotes
One beacon per adstringOptionalDeduped client-side even though the server also dedups — don't rely solely on server-side dedup for cost or correctness.
Refresh floorstringOptionalAuto-refresh interval must be ≥30 seconds. Values below 30 are clamped or rejected — this protects fill rate and keeps you under rate limits (see Rate limits).
Lazy loadstringOptionalBanner containers should only fire the ad request when within ~200px of the viewport, where the platform supports viewport detection.
TeardownstringOptionalCancel timers, disconnect viewability observers, and abort in-flight requests when the ad view is destroyed.