User-Agent rules
The single most common cause of an integration that silently never fills. Two independent backend filters check the User-Agent, and a match on either kills the impression.
The two filters
The backend runs two UA filters. A match on either causes silent no-fill or a fraud score bump:
| Name | Type | Required | Notes |
|---|---|---|---|
is_bot blocklist | substring, case-insensitive | Optional | bot, crawler, spider, scraper, google, bing, yahoo, facebook, twitter, instagram, pinterest, slack → immediate {fill:false}. |
Fraud bot_signatures | substring, +0.45 score | Optional | bot, crawler, spider, scraper, HeadlessChrome, PhantomJS, Selenium, Puppeteer, Playwright, curl/, wget/, python-requests, Go-http-client, httpclient, Java/, okhttp — rejects outright above a 0.75 fraud score. |
Default client UAs are on this list
python-requests/2.x, okhttp/4.x, Java/17 and Go-http-client/1.1 — the defaults of the most common HTTP libraries — all match. An integration built by hand against the raw contract that forgets to set a custom User-Agent will no-fill 100% of the time with no error, no exception, no log line — just an empty {"fill": false}. This is the #1 support question for anyone integrating without an SDK.What every official SDK sends
Every SDK sets an explicit UA that (a) avoids all of the substrings above and (b) includes a platform token so get_device_type classifies correctly (android/iphone/ipad/mobile/tablet, else desktop):
| Name | Type | Required | Notes |
|---|---|---|---|
Python | string | Optional | theaimart-adx-python/<ver> |
Node | string | Optional | theaimart-adx-node/<ver> |
Rust | string | Optional | theaimart-adx-rust/<ver> |
Web | string | Optional | (browser sets its own real UA — do not override) |
React Native | string | Optional | theaimart-adx-reactnative/<ver> (<os>) |
Android | string | Optional | theaimart-adx-android/<ver> (Android <osver>; <model>) |
iOS | string | Optional | theaimart-adx-ios/<ver> (iPhone; iOS <osver>) |
Flutter | string | Optional | theaimart-adx-flutter/<ver> (<android|iPhone>...) |
Unity | string | Optional | theaimart-adx-unity/<ver> (<platform>) |
Server-side SDKs: forward the real user
Python, Node and Rust are typically used to proxy an ad request on behalf of an end user (e.g. server-side rendering a page). In that case, the integrator must forward the end user's own User-Agent and IP (via X-Forwarded-For) — not the server's. Otherwise every impression across every user looks like one device from one datacenter IP, which gets fraud-scored to a no-fill. Both SDKs expose userAgent/user_agent and clientIp/client_ip per-request overrides for exactly this — see Node or Python.