Skip to content
Docs/Help & safety

Developer FAQ

The questions that actually come up while integrating — most of them one specific gotcha in the wire contract, answered once and for all.

Debugging a specific error?

This page answers conceptual questions. For a symptom → cause → fix table (403s, zero fills, CORS, rate limits…), see Troubleshooting instead.

Is the api_key safe to embed in a shipped client app?

+
Yes. It is a public client identifier — like any ad SDK's publisher key — designed to be shipped inside client binaries. It grants no account access and is not a server secret. See Requesting an ad.

My integration never fills, with no error at all. What's wrong?

+
One possible cause: a default HTTP-client User-Agent (python-requests, okhttp, Java/…, curl/…) is on the backend's bot/fraud blocklist, which returns an ordinary {"fill": false} with no error to see. Server and native SDKs set platform User-Agent values; browsers use their own User-Agent — see User-Agent rules if you're building a custom client.

A request with a completely ordinary page_url gets a 403. Why?

+
Your query string may contain one of the WAF's blocked substrings — end, open, cast, select, @, etc. — which occur constantly in real URLs (weekend, /opensource, user@…). Ordinary URL-encoding does not hide these substrings; every SDK byte-percent-encodes the value instead. See WAF-safe encoding.

Which ad formats can I actually serve?

+
Banner and image creative paths exist in the SDK source. Native and interstitial presentation need runtime-specific integration. Video uses a separate VAST path with a Web playback helper; rewarded delivery and reward verification are not established for all SDKs. See runtime availability.

Do I need to call POST /api/v1/serve/impression myself?

+
No — never, for the SDK flow. Impressions for GET /api/v1/serve/ad are recorded server-side automatically when the ad is served. That endpoint exists only for external/VAST integrations and requires six server-known UUIDs; calling it from an SDK integration would double-count. See Wire contract overview.

How do I test my integration without spending real budget or polluting analytics?

+
Use local mocks or a confirmed publisher sandbox workflow. Do not assume normal production serving is free of billing and tracking side effects. Start with the injected transport in the Quickstart.

There's no SDK for my stack. What do I do?

+
Two options. Call the wire contract directly — it's a plain REST API, and this reference documents every byte you need to get right (encoding, User-Agent, response parsing). Or, if you already run a header-bidding stack, connect it to the inbound OpenRTB 2.5 endpoint from the publisher dashboard instead of integrating an SDK at all.

House ads have no imp_id — does that mean they're not worth anything?

+
It means they can't be tracked by this SDK's viewability beacon — house ads are backfill inventory with their own advertiser-side tracking baked into click_url (which is the raw, un-wrapped destination). Skip the viewability beacon for them; everything else renders the same as an internal image ad. See Response shapes.

How does versioning work — what happens if the contract changes?

+
Pin the specific SDK version and check its changelog and wire-contract compatibility. The documented contract is v1; do not assume synchronized releases or production acceptance across runtimes. See Wire contract overview.

Can I point an SDK at a staging environment?

+
Yes — every SDK exposes baseUrl/base_url as a constructor option, defaulting to the production https://api.adx.theaimart.co. Point it at your own staging host to test against a non-production backend.