Skip to main content
POST
The endpoint URL is yours — configure it with the Thrad team during onboarding.

Headers

string
required
Always application/json.
string
required
Always 2.6 — explicit version declaration. Some DSPs gate the parser on this header; reject unsupported versions with 400.
string
application/json — sent on every request.

Authentication

Two auth styles are supported per DSP — picked at onboarding and stored against your DSP config.
string
Bearer <your-shared-key> — provided by you at onboarding. Use this if you prefer header-based auth.
Or: pubid-in-URL pattern. If your endpoint identifies the publisher via a URL query parameter (e.g. https://your-host/bid?pubid=12345), provide the full URL with the parameter baked in at onboarding and leave the bearer token blank. We will not add any Authorization header in that case. NoBid is integrated this way.

Envelope

string
required
Auction id. Echo in BidResponse.id.
integer
required
Always 1 — first-price.
integer
required
The time we hold you to, in ms; responses after it are dropped. 3000 on in-conversation (card_*) requests and 1000 on opener_* requests from publishers. On supply resold from another exchange it is that exchange’s tmax minus our reserve, capped at 3000. Read it per request.
string[]
required
Always ["USD"].
integer
required
1 during onboarding, 0 in production.

imp[]

Always a single impression.
string
required
Always "1".
string
required
Slot identifier. Encodes the slot and its render mode — key your bid multipliers, frequency caps, and creative eligibility off this together with site.id. One of:
Until 2026-10 these were spelled sponsored_message_{image,text}_v1 and opener_{image,text}_v1. Match on the _image / _text suffix rather than the full string if you want to be robust to the change.
float
required
Floor in CPM USD. A bid at or above it is never rejected on price. On supply Thrad resells from another exchange the floor already includes Thrad’s margin, so you do not need to bid above it to cover the downstream floor.
string
required
Always "USD".
Fields Thrad intentionally does not send:
  • imp[].pos — none of the oRTB position enums (above-fold, full-screen, etc.) cleanly describe inline chatbot inventory. Route on imp[].tagid and the Native asset list instead.
  • imp[].battr — the Native 1.2 asset shape Thrad requests already structurally rejects video, audio, expandable, and pop creatives. Sending battr would be noise on top.
integer
required
Always 1. All URLs in your response must be HTTPS.
string
required
Always "1.2" (outer ver double-declaration). The inner native.request envelope also carries ver: "1.2".
string
required
JSON-encoded Native 1.2 request object. Shape forks by render mode (signalled in imp[].tagid) — the publisher’s image_enabled config drives both the tagid and the asset list, so they’re always consistent.Image mode (tagid ends in _image) — accepts both image and text creatives:
Text mode (tagid ends in _text) — publisher cannot render images. Asset 3 is omitted entirely and asset 4 (logo) becomes required:
Asset ids are 0-based (title=0 … CTA=5) — your response must echo the same ids the request sent.Required assets in both modes: 0 (title), 1 (description), 2 (sponsoredBy), 5 (CTA). Bids missing any of these are rejected.Asset 4 (logo): required in text mode, optional in image mode.Asset 3 (main image): only present (and only acceptable in your response) in image mode. If you return image_url on a text-mode request, the SSP drops it server-side before render — a logo-only creative will still serve, but if you sent neither asset 4 nor a usable image, the bid is silently lost. Always honour the tagid signal.title.len is parameterised by the publisher’s max_headline_chars setting (≥ 30, default 90). The other len values and image dimensions are global per format. len is a maximum character count; wmin/hmin are minimum image dimensions in pixels.
string
Non-standard convenience duplicate. Byte-for-byte identical to imp[].native.request — the same stringified Native 1.2 envelope, not an object. Native 1.2 defines only request; we additionally send request_native because some bidders key their native parser on this field name and reject the spec field with a bad adslot error. If your bidder already reads native.request, ignore this field — it carries identical content and is provided purely for parser compatibility.
object
Thrad extension — what Thrad shares about the conversation. It lives under ext because no standard oRTB field describes a conversation: site.cat / site.keywords describe the site. Spec-strict bidders can ignore it; none of these affect SSP-side auction logic. The slot and its render mode are in imp[].tagid, not here.
In 2026-10 the conversation signals moved here from site.keywords, site.cat and user.keywords, which are no longer sent, and n_ads_before, prefetched and request_type were removed. site.search (the rephrased conversation) is no longer sent at all: target on keywords, intent, task and iab_tier1.

site / app

Exactly one of site or app is present per request. app ships when the publisher’s inventory is in-app (ios_app / android_app); otherwise site. The publisher subblock is identical in both.
string
required
Opaque publisher slot id. Resolved in priority: (1) per-DSP external_site_id override if your DSP requires a fixed id (set at onboarding), (2) the chatbot’s public_id (UUID), (3) stringified internal publisher id (legacy fallback). Stable for a given chatbot.
string
Hostname where the chatbot is rendered (lowercased, scheme stripped). Derived from the publisher’s per-request URL. Omitted when the publisher doesn’t provide a URL.
string
Full page URL where the chatbot is rendered. Omitted when not provided.
integer
required
Always 1. The Thrad network operates under a privacy policy.
string
required
Opaque publisher organisation id. Resolved in priority: (1) per-DSP external_site_id override, (2) the organisation’s public_id (UUID), (3) stringified internal publisher id. Equals site.id when override (1) is in play; differs otherwise.
string
Organisation name, lowercased. Adtech allow/denylists key on string equality — we normalise upstream so you don’t have to. Omitted when unset.
string
Organisation domain, lowercased, scheme + path stripped. Omitted when unset. Different concept from site.domain — this is the publisher organisation’s domain (the sellers.json target); site.domain is where the ad runs.
site.cat, site.cattax, site.search and site.keywords are not sent: they describe a site, and the conversation is in imp[].ext.thrad.

app block (in-app inventory only)

Same id / publisher semantics as site. Additionally:
string
iOS bundle ID (com.example.app) or Android package name. Required for in-app inventory.
string
App Store / Play Store listing URL.
string
App marketing site domain — reuses the publisher organisation’s domain (same value as app.publisher.domain).

device

string
required
End-user User-Agent.
string
End-user IPv4. Omitted when the user is on IPv6 (see device.ipv6).
string
End-user IPv6. Sent instead of device.ip when applicable.
integer
required
2=desktop, 4=phone, 5=tablet, 0 for unknown.
integer
required
Always 1. Thrad’s chatbot widget is JS-rendered — noscript fallbacks are never needed.
string
ISO 639-1 alpha-2. Priority: (1) conversation language auto-detected from messages (best for in-chat ads), (2) Accept-Language header parsed from the publisher request (fallback for openers and sparse conversations). Field is omitted entirely when neither signal is available.
string
ISO-3 country code.
string
Region/state, when available.
string
City, when available.
integer
Always 2 (IP-based) when the geo block is present. Thrad does not collect GPS-grade geolocation.
string
OS string, UA-parsed.
string
Advertising id (IDFA/GAID). In-app only.
integer
1 if Do Not Track.
integer
1 if Limit Ad Tracking.

user

string
required
Anonymous Thrad user id.
string
DSP cookie-match value, when available via cookie sync.
IAB TCF v2.x consent string. Present when regs.gdpr=1.

regs

integer
required
1 when the user’s country falls under GDPR / UK GDPR / EEA / Swiss FADP (based on Thrad SSP’s IP-geo lookup), 0 otherwise. user.ext.consent is not yet sent; TCF v2 consent forwarding is planned. EU-compliant DSPs that require a consent string on gdpr=1 should refuse to bid on those requests (the correct behavior); we explicitly declare 1 so eligibility logic isn’t ambiguous.
string
CCPA string, when supplied by the publisher. Not yet sent.
string
GPP string, when supplied by the publisher. Not yet sent.
integer
1 if user is flagged under-13. Not yet sent.

source

integer
required
Always 0. SSP is the entity making the auction decision.
string
required
Transaction id. Echoes BidRequest.id.
object
IAB SupplyChain object (sellers.json chain) — oRTB 2.6 location (root source, not source.ext). Sent on every request where the publisher’s organisation public_id is available. Single-node chain today: asi is Thrad’s host (matches our sellers.json), sid is the publisher organisation public_id, hp: 1. Verify the asi value resolves to a seller_id entry at https://<asi>/sellers.json if you do supply-chain validation.

bcat / badv

string[]
Blocked IAB categories. Only present when set.
string[]
Blocked advertiser domains. Only present when set.

Last updated: 2026-06-14 — source.schain, regs.gdpr (country-based), headers, and pubid-in-URL auth reflect production behavior since the oRTB v1 launch.