Skip to main content
An ad is a single creative inside an ad group. Every ad belongs to exactly one ad group, and its creative type must match the ad group’s type — an ad group is either all chat cards or all polls, never a mix. Two creative types are supported:
  • chat_card — an in-chat sponsored message (title, body, CTA, image).
  • poll — a Thrad-only sponsored poll (question + 2–4 options + click-through URL).
All paths are relative to the base URL https://api.thrad.ai/v1. Authenticate every request with Authorization: Bearer ak_.... See Authentication.

The ad object

id
string
The ad’s unique identifier (UUID).
ad_group_id
string
The UUID of the ad group this ad belongs to.
name
string
Human-readable ad name. When omitted on create, it defaults to the creative title (card headline or poll question).
status
string
One of active, paused, or archived. Change it through /activate, /pause, and /archive, or by sending status in an update body.
Thrad ads have no separate archived state. Sending status: archived (or calling /archive) deactivates the ad, so it reads back as paused. A newly created ad is active.
review_status
string
Read-only review state inherited from the parent campaign: approved, in_review, or rejected. You cannot set this — it reflects where the campaign sits in Thrad’s approval flow.
creative
object
The ad creative. Shape depends on type.

List ads

GET /v1/ads Lists the ads in a single ad group. ad_group_id is required — there is no all-ads listing.
ad_group_id
string
required
The UUID of the ad group whose ads to list.
limit
integer
default:"20"
Number of ads to return, 1500.
before
string
Cursor for the previous page — pass a prior response’s first_id. Mutually exclusive with after.
after
string
Cursor for the next page — pass a prior response’s last_id. Mutually exclusive with before.
order
string
default:"desc"
Sort order by creation time: asc or desc.
curl https://api.thrad.ai/v1/ads?ad_group_id=ag_8f1c2d3e \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "ad_4a9b6c1d",
      "ad_group_id": "ag_8f1c2d3e",
      "name": "Premium Running Shoes",
      "status": "active",
      "review_status": "approved",
      "creative": {
        "type": "chat_card",
        "title": "Premium Running Shoes",
        "body": "Lightweight and built for marathon training.",
        "cta": "Shop Now",
        "image_url": "https://cdn.thrad.ai/assets/abc123.jpg"
      }
    }
  ],
  "count": 1,
  "first_id": "ad_4a9b6c1d",
  "last_id": "ad_4a9b6c1d",
  "has_more": false
}

Create an ad

POST /v1/ads Adds an ad to an existing ad group. The creative type must match the ad group’s type, or the request is rejected with 400 invalid_value on creative.type.
ad_group_id
string
required
The UUID of the ad group to add this ad to.
name
string
Ad name. Defaults to the creative title (card headline or poll question) when omitted.
auto_generate
boolean
default:"false"
Chat cards only. When true, Thrad’s AI generates the card copy, so creative.title and creative.body become optional. Setting auto_generate on a poll creative is rejected with poll_cannot_be_ai.
creative
object
required
The ad creative. Its type must match the ad group.
Provide a card image with either file_id (from POST /v1/upload) or image_url. Polls do not take an image.
curl https://api.thrad.ai/v1/ads \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ad_group_id": "ag_8f1c2d3e",
    "name": "Premium Running Shoes",
    "creative": {
      "type": "chat_card",
      "title": "Premium Running Shoes",
      "body": "Lightweight and built for marathon training.",
      "cta": "Shop Now",
      "file_id": "file_7d2a1b9c"
    }
  }'
{
  "id": "ad_4a9b6c1d",
  "ad_group_id": "ag_8f1c2d3e",
  "name": "Premium Running Shoes",
  "status": "active",
  "review_status": "in_review",
  "creative": {
    "type": "chat_card",
    "title": "Premium Running Shoes",
    "body": "Lightweight and built for marathon training.",
    "cta": "Shop Now",
    "image_url": "https://cdn.thrad.ai/assets/abc123.jpg"
  }
}

Retrieve an ad

GET /v1/ads/{ad_id}
ad_id
string
required
The UUID of the ad to retrieve.
curl https://api.thrad.ai/v1/ads/ad_4a9b6c1d \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "id": "ad_4a9b6c1d",
  "ad_group_id": "ag_8f1c2d3e",
  "name": "Premium Running Shoes",
  "status": "active",
  "review_status": "approved",
  "creative": {
    "type": "chat_card",
    "title": "Premium Running Shoes",
    "body": "Lightweight and built for marathon training.",
    "cta": "Shop Now",
    "image_url": "https://cdn.thrad.ai/assets/abc123.jpg"
  }
}

Update an ad

POST /v1/ads/{ad_id} Patches the ad’s name, creative, and/or status. Only the fields you send are changed.
ad_id
string
required
The UUID of the ad to update.
name
string
New ad name.
status
string
Optionally set active, paused, or archived. active activates the ad; paused and archived both deactivate it, so it reads back as paused. (Unlike campaigns, ads accept status in the update body — the dedicated /activate, /pause, and /archive actions are equivalent shortcuts.)
creative
object
A replacement creative. It must match the ad group’s type and follow the same field rules as on create (card title ≤ 30; poll title ≤ 120 with 2–4 options and a target_url). For card creatives, send a new file_id or image_url to swap the image.
curl https://api.thrad.ai/v1/ads/ad_4a9b6c1d \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium Trail Shoes",
    "creative": {
      "type": "chat_card",
      "title": "Premium Trail Shoes",
      "body": "Grip for any terrain.",
      "cta": "Shop Now",
      "image_url": "https://cdn.example.com/trail.jpg"
    }
  }'
{
  "id": "ad_4a9b6c1d",
  "ad_group_id": "ag_8f1c2d3e",
  "name": "Premium Trail Shoes",
  "status": "active",
  "review_status": "approved",
  "creative": {
    "type": "chat_card",
    "title": "Premium Trail Shoes",
    "body": "Grip for any terrain.",
    "cta": "Shop Now",
    "image_url": "https://cdn.thrad.ai/assets/def456.jpg"
  }
}

Activate an ad

POST /v1/ads/{ad_id}/activate Reactivates a paused ad. The parent campaign must be approved.
ad_id
string
required
The UUID of the ad to activate.
curl -X POST https://api.thrad.ai/v1/ads/ad_4a9b6c1d/activate \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "id": "ad_4a9b6c1d",
  "ad_group_id": "ag_8f1c2d3e",
  "name": "Premium Running Shoes",
  "status": "active",
  "review_status": "approved",
  "creative": {
    "type": "chat_card",
    "title": "Premium Running Shoes",
    "body": "Lightweight and built for marathon training.",
    "cta": "Shop Now",
    "image_url": "https://cdn.thrad.ai/assets/abc123.jpg"
  }
}

Pause an ad

POST /v1/ads/{ad_id}/pause Deactivates the ad.
ad_id
string
required
The UUID of the ad to pause.
curl -X POST https://api.thrad.ai/v1/ads/ad_4a9b6c1d/pause \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "id": "ad_4a9b6c1d",
  "ad_group_id": "ag_8f1c2d3e",
  "name": "Premium Running Shoes",
  "status": "paused",
  "review_status": "approved",
  "creative": {
    "type": "chat_card",
    "title": "Premium Running Shoes",
    "body": "Lightweight and built for marathon training.",
    "cta": "Shop Now",
    "image_url": "https://cdn.thrad.ai/assets/abc123.jpg"
  }
}

Archive an ad

POST /v1/ads/{ad_id}/archive
Thrad ads have no distinct archived state, so /archive deactivates the ad and it reads back as paused — the same result as /pause. This is a deliberate divergence from OpenAI’s surface.
ad_id
string
required
The UUID of the ad to archive.
curl -X POST https://api.thrad.ai/v1/ads/ad_4a9b6c1d/archive \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "id": "ad_4a9b6c1d",
  "ad_group_id": "ag_8f1c2d3e",
  "name": "Premium Running Shoes",
  "status": "paused",
  "review_status": "approved",
  "creative": {
    "type": "chat_card",
    "title": "Premium Running Shoes",
    "body": "Lightweight and built for marathon training.",
    "cta": "Shop Now",
    "image_url": "https://cdn.thrad.ai/assets/abc123.jpg"
  }
}

Errors

Errors use the bare shape { "error": { "message", "type", "param", "code" } }.
CodeHTTPWhen
required400A required field is missing (e.g. card title when not auto-generated, poll title / target_url).
invalid_value400creative.type doesn’t match the ad group’s type, a missing or non-object creative, an unknown creative.type, or poll options not a list of 2–4.
string_too_long400Card title over 30 characters, or poll title over 120 characters.
poll_cannot_be_ai400auto_generate set on a poll creative — AI polls are not supported.
not_found404The ad or ad group doesn’t exist or belongs to another organization.
rate_limit_exceeded429Over the 1000-requests/hour per-key limit.