Wire contract (v1)
A single ad-serving REST contract — request, render, report — implemented identically by every official SDK. This section is the authoritative reference; if you're integrating without an SDK, start here.
Unfamiliar terms?
This reference uses words like "slot", "fill",imp_id and "auction" freely. If any of them are new, Core concepts explains all of them in plain language first.theaimart-adnetwork (Rust/actix-web) backend source — not written from memory or stale docs. If the backend contract ever changes, this reference changes first, then every SDK follows.Base URL & transport
| Name | Type | Required | Notes |
|---|---|---|---|
Production base URL | Optional | https://api.adx.theaimart.co | |
Serve API prefix | Optional | /api/v1/serve | |
Protocol | Optional | HTTP/1.1 or h2c; responses may be gzip/brotli if Accept-Encoding advertises it | |
Response Content-Type | Optional | application/json (VAST responses use application/xml, out of scope for v1 SDKs) | |
Cache-Control | Optional | no-store — ad responses must never be cached |
Every SDK exposes baseUrl/base_url as a constructor option (default: the production URL above) so you can point at a staging environment.
Endpoints used by a publisher SDK
| Name | Type | Required | Notes |
|---|---|---|---|
GET /api/v1/serve/ad | Optional | Request an ad decision — the core call. See Requesting an ad. | |
POST /api/v1/serve/viewable | Optional | Viewability beacon (≥50% on-screen for ≥1s). See Beacons. | |
GET /api/v1/serve/click?id={imp_id} | Optional | Click tracker → 302 redirect to the advertiser. See Beacons. |
Do not call these yourself
The SDK never calls POST /api/v1/serve/impression — that endpoint is for external/VAST integrations and requires six server-known UUIDs. Impressions for the /serve/ad flow are recorded server-side automatically when the ad is served. Calling it yourself double-counts.
GET /api/v1/serve/vast (video/VAST) is excluded from v1 of every SDK in this repo — its impression pixel is a POST-only, body-required route and its click-through imp_id is never persisted, so clicks redirect to a fallback. Don't ship rewarded/instream video against this backend until that's fixed.
The request/response lifecycle
Every integration, regardless of platform, follows the same three-step lifecycle:
- Request —
GET /api/v1/serve/ad?api_key=…&slot_id=…with an explicit, fraud-safeUser-Agent. - Parse & render — the body is one of four shapes (no-fill / internal image / OpenRTB HTML / house image). Parse the discriminator in order; render HTML only in a sandboxed context.
- Report — fire the viewability beacon once, when the ad is ≥50% visible for ≥1 continuous second. Clicks need no extra call —
click_urlis pre-wrapped.
Versioning
SDKs follow SemVer independently but all track this contract's major version (v1). A breaking change to the wire contract bumps the major version of every SDK simultaneously. Every SDK also sends an X-Adx-Sdk header (name + version) for observability — it is not part of the User-Agent and does not affect fraud scoring.
Reference index
- Requesting an ad — query params, required headers, the identity cookie.
- Response shapes — the 4-way discriminated union, field by field.
- Beacons — viewability and click tracking.
- User-Agent rules — the #1 cause of silent no-fill.
- WAF-safe encoding — why ordinary URL-encoding 403s in production.
- Rate limits & errors — status codes, retry behavior, refresh floors.
- Getting credentials — signup → site → slot, end to end.