Skip to main content
POST
v1 is deprecated. New integrations should use v2.

Authorizations

string
required
Your API key for authentication. The key’s environment (staging or production) determines how ads are served — see Staging vs. Production.
string
required
Must be application/json

End-User Headers

These headers identify the real end-user behind the request. They are required on every bid request and every view URL ping.
string
required
The end-user’s original IP address. Must be the real client IP, not your server’s IP.
string
required
The end-user’s original device/browser string exactly as received from the client.

Geolocation & Device Headers

The server resolves the user’s location and device from request headers. These are optional but strongly recommended for server-side integrations — sending them skips the server-side IP lookup and reduces latency.
string
ISO 3166-1 alpha-2 country code (e.g. "US", "DE"). When present, X-User-Device and X-User-Timezone are required.
string
User’s device type: "mobile" or "desktop". Required when X-User-Country is present. This is critical for device-targeted campaigns — without it, targeting will not work correctly.
string
IANA timezone (e.g. "America/Los_Angeles"). Required when X-User-Country is present. Used for time-of-day pacing.
string
Region or state (e.g. "CA", "Bavaria"). Optional but recommended for regional targeting.
string
City name (e.g. "San Francisco"). Optional but recommended for city-level targeting.
If you send X-User-Country without X-User-Device and X-User-Timezone, the request will be rejected with a 400 Bad Request. These three headers must always be sent together.
If none of the above headers are sent, the server falls back to IP-based geolocation using X-Forwarded-For. For direct calls (browser or mobile app → our API), this is handled automatically by the load balancer. If you’re proxying requests through your own backend, you must forward the user’s IP via X-Forwarded-For — otherwise the server sees your server’s IP and geo will be wrong.
If unsure about which headers to send, contact marco@thrads.ai and we’ll help you set it up.

Body

string
Optional anonymous user identifier (e.g. a UUID like user_a1b2c3d4-...). If supplied, 1–100 characters and not blank. Keep it stable for user-based ad controls. Do not use email, name, or other PII. On web, store in localStorage; on mobile, use the platform’s persistent storage (e.g. UserDefaults on iOS, SharedPreferences on Android).
string
contextual only Optional conversation identifier. At most 100 characters. An empty chat_id is treated as no chat ID. One unique ID per conversation, not per user. Reset when the user starts a new chat. Without it, matching still works, but stored chat pacing, chat repeat checks, experiment cooldowns, and transcript storage are skipped. User daily campaign limits and click cooldowns still apply when user_id is supplied.
array
contextual only Conversation history. Required when request_type is "contextual". Each message must have a role ("user" or "assistant") and content. PII (names, emails, addresses, etc.) should be masked or removed before sending.At least one user message is required. A single user message is valid on its own — send it to request an ad mid-turn, while your model is still generating its reply. A conversation containing only assistant messages has no user intent to match against and returns "bid": null.
object
Publisher configuration for pacing, contextual serving, creative constraints, and analytics. All fields are optional — omitted fields fall back to defaults set on your publisher in the platform dashboard.
string
default:"contextual"
Pipeline selector. Determines which ad pipeline runs and what fields are required.
  • "contextual" (default) — in-chat ads. Requires context: messages, a summary, or keywords. chat_id is optional.
  • "opener" — pre-chat ads (e.g. sponsored prompts, banners). chat_id and messages are not required. Sponsored polls are not opener inventory.
array
Ad formats the publisher can render. The server picks the best match from this list.
  • Contextual: any combination of card (default), poll, and carousel — e.g. ["card", "carousel"].
  • Opener: ["card"]. Always declare it explicitly. Do not include poll or carousel on opener requests. (sponsored_prompt is coming soon.)
The legacy spellings sponsored_message and sponsored_poll remain accepted for backward compatibility. Responses currently echo the legacy names in ad_format for the card and poll ("sponsored_message", "sponsored_poll"); carousel returns "carousel".When contextual requests include both sponsored_message and sponsored_poll, Thrad selects the campaign through the normal contextual auction, then uses campaign delivery settings to choose whether the returned creative is a message or poll.
integer
contextual only Current turn number in the conversation. Used for ad offset pacing and analytics. Must be >= 0. Only needed if you’re not calling the endpoint on every user-assistant exchange — if you are, the system derives this from the message count.
string
contextual only Publisher-provided conversation summary. Useful when you already have a summary from your chatbot and want to reduce latency.
object
User metadata for targeting and compliance. All fields are optional. Extra fields are accepted and stored for future use.
A 200 OK response with "bid": null is not an error - it means the auction ran successfully but no DSP submitted a winning bid. This is normal behavior.

Response

string
Unique request identifier used in logs and tracing.
string
ISO 8601 timestamp of when the response was generated.
float
Total processing time for this request in seconds.
string
Response status: "success" or "error".
string
Human-readable message describing the result.
object
Response data payload.
object|null
Error details when status = "error" (otherwise null).

Status Codes