API Reference
Bid
OpenRTB 2.6 bid endpoint your DSP must expose. Thrad SSP POSTs a BidRequest and expects a BidResponse or no-bid.
POST
The endpoint URL is yours — configure it with the Thrad team during onboarding.
Headers
Always
application/json.Always
2.6 — explicit version declaration. Some DSPs gate the parser on this header; reject unsupported versions with 400.application/json — sent on every request.Authentication
Two auth styles are supported per DSP — picked at onboarding and stored against your DSP config.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.- BidRequest
- BidResponse
Envelope
Auction id. Echo in
BidResponse.id.Always
1 — first-price.Always
2000 ms. Responses after this are dropped.Always
["USD"].1 during onboarding, 0 in production.imp[]
Always a single impression.Always
"1".Slot identifier. Encodes both format and render mode — key your bid multipliers, frequency caps, and creative eligibility off this. One of:
Bumps to
| tagid | Format | Mode | DSP must populate |
|---|---|---|---|
sponsored_message_image_v1 | In-conversation | Image preferred (logo also accepted) | Asset 4 (image) or asset 5 (icon) |
sponsored_message_text_v1 | In-conversation | Text only — image will be rejected server-side | Asset 5 (icon/logo) — required |
opener_image_v1 | Pre-chat opener | Image preferred (logo also accepted) | Asset 4 (image) or asset 5 (icon) |
opener_text_v1 | Pre-chat opener | Text only — image will be rejected server-side | Asset 5 (icon/logo) — required |
_vN only happen when the slot’s creative contract changes in a way that breaks existing creatives.Floor in CPM USD.
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 onimp[].tagidand the Native asset list instead.imp[].battr— the Native 1.2 asset shape Thrad requests already structurally rejects video, audio, expandable, and pop creatives. Sendingbattrwould be noise on top.
Always
1. All URLs in your response must be HTTPS.Always
"1.2" (outer ver double-declaration). The inner native.request envelope also carries ver: "1.2".JSON-encoded Native 1.2 request object. Shape forks by render mode (signalled in Text mode (Required assets in both modes: 1 (title), 2 (description), 3 (sponsoredBy), 6 (CTA). Bids missing any of these are rejected.Asset 5 (logo): required in text mode, optional in image mode.Asset 4 (main image): only present (and only acceptable in your response) in image mode. If you return
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_v1) — accepts both image and text creatives:tagid ends in _text_v1) — publisher cannot render images. Asset 4 is omitted entirely and asset 5 (logo) becomes required: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 5 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.Thrad extension — conversation-level signals that do not fit any standard oRTB field. Lives under
ext so spec-strict bidders can ignore it cleanly; none of these affect SSP-side auction logic, they’re hints your DSP can use for creative selection or pacing.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.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.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.
Full page URL where the chatbot is rendered. Omitted when not provided.
Always
1. The Thrad network operates under a privacy policy.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.Organisation name, lowercased. Adtech allow/denylists key on string equality — we normalise upstream so you don’t have to. Omitted when unset.
Organisation domain, lowercased, scheme + path stripped. Omitted when unset. Different concept from
site.domain — this is the publisher organisation’s domain (sellers.json target once Wave 4 ships); site.domain is where the ad runs.IAB Content Taxonomy 3.0 Tier 1 Unique ID. Always paired with
site.cattax: 7. IDs are mostly numeric (e.g. "1" Automotive, "483" Sports, "596" Technology & Computing) but six are short alphanumeric extension IDs ("JLBCU7" Entertainment, "8VZQHL" Events, "SPSHQ5" Genres, "1KXCLD" Holidays, "v9i3On" Sensitive Topics). Sub-tiers are not currently signalled.Always
7 (IAB Content Taxonomy 3.0). Present alongside site.cat.LLM-rephrased conversational query. Primary intent signal.
Comma-separated topical keywords.
app block (in-app inventory only)
Same id / publisher / cat / cattax / search / keywords semantics as site. Additionally:iOS bundle ID (
com.example.app) or Android package name. Required for in-app inventory.App Store / Play Store listing URL.
App marketing site domain — reuses the publisher organisation’s domain (same value as
app.publisher.domain).device
End-user User-Agent.
End-user IPv4. Omitted when the user is on IPv6 (see
device.ipv6).End-user IPv6. Sent instead of
device.ip when applicable.2=desktop, 4=phone, 5=tablet, 0 for unknown.Always
1. Thrad’s chatbot widget is JS-rendered — noscript fallbacks are never needed.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.ISO-3 country code.
Region/state, when available.
City, when available.
Always
2 (IP-based) when the geo block is present. Thrad does not collect GPS-grade geolocation.OS string, UA-parsed.
Advertising id (IDFA/GAID). In-app only.
1 if Do Not Track.1 if Limit Ad Tracking.user
Anonymous Thrad user id.
DSP cookie-match value, when available via cookie sync.
Mirrors
imp[].ext.thrad.keywords.IAB TCF v2.x consent string. Present when
regs.gdpr=1.regs
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 wired — full TCF v2 forwarding lives on the Wave 4 roadmap. 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.CCPA string, when supplied by the publisher. Not yet wired — Wave 4.
GPP string, when supplied by the publisher. Not yet wired — Wave 4.
1 if user is flagged under-13. Not yet wired — Wave 4.source
Always
0. SSP is the entity making the auction decision.Transaction id. Echoes
BidRequest.id.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
Blocked IAB categories. Only present when set.
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.