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:
{ "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).
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
| Name | Type | Required | Notes |
|---|---|---|---|
One beacon per ad | string | Optional | Deduped client-side even though the server also dedups — don't rely solely on server-side dedup for cost or correctness. |
Refresh floor | string | Optional | Auto-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 load | string | Optional | Banner containers should only fire the ad request when within ~200px of the viewport, where the platform supports viewport detection. |
Teardown | string | Optional | Cancel timers, disconnect viewability observers, and abort in-flight requests when the ad view is destroyed. |