Skip to main content
Ad groups live under a campaign. Each ad group carries the context hints that steer where its ads serve and the max bid the auction may pay, and it holds one or more ads that all share a single creative type. You can create ad groups inline when you create a campaign (see Campaigns), or add them to an existing campaign with the endpoints below.
All paths are relative to the base URL https://api.thrad.ai/v1. Authenticate every request with Authorization: Bearer ak_.... See Authentication for how to create your key.

The ad group object

id
string
Unique identifier for the ad group (a UUID).
campaign_id
string
The parent campaign’s id.
name
string
Display name for the ad group.
context_hints
string[]
The hints that tell Thrad which conversations this ad group’s ads are relevant to. Returned as an array of strings.
status
string
One of active, paused, or archived. Ad groups have no distinct archived state on Thrad, so an archived ad group reads back as paused. Change status with the dedicated /activate, /pause, and /archive actions, or by sending status in an update body.
bidding_config
object
Bidding settings for the ad group.
created_at
integer
Unix timestamp (seconds) when the ad group was created.
updated_at
integer
Unix timestamp (seconds) when the ad group was last updated.
{
  "id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
  "name": "Runners — focus playlists",
  "context_hints": [
    "marathon training",
    "running shoes",
    "endurance"
  ],
  "status": "active",
  "bidding_config": {
    "billing_event_type": "impression",
    "max_bid_micros": 700000
  },
  "created_at": 1775088000,
  "updated_at": 1775174400
}

List ad groups

GET /v1/ad_groups Returns the ad groups for one campaign, most recent first. campaign_id is required — listing across all campaigns is not supported.
campaign_id
string
required
The campaign whose ad groups to list.
limit
integer
default:"20"
Number of ad groups to return, 1500.
order
string
default:"desc"
Sort direction by creation time: asc or desc.
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.
curl "https://api.thrad.ai/v1/ad_groups?campaign_id=1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901&limit=20" \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
      "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
      "name": "Runners — focus playlists",
      "context_hints": ["marathon training", "running shoes"],
      "status": "active",
      "bidding_config": {
        "billing_event_type": "impression",
        "max_bid_micros": 700000
      },
      "created_at": 1775088000,
      "updated_at": 1775174400
    }
  ],
  "count": 1,
  "first_id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "last_id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "has_more": false
}

Create an ad group

POST /v1/ad_groups Adds an ad group to an existing campaign. The ad group must include at least one ad, and all ads in the ad group must share one creative type (all chat_card, or all poll).
campaign_id
string
required
The campaign to add this ad group to.
name
string
required
Display name for the ad group. Max 255 characters.
context_hints
string[]
required
Hints that steer where the ad group’s ads serve. Each array entry is one hint. Must be a non-empty array.
bidding_config
object
Bidding settings for the ad group.
ads
array
required
The ads in this ad group. At least one is required, and all ads must share one creative type.
curl -X POST "https://api.thrad.ai/v1/ad_groups" \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
    "name": "Runners — focus playlists",
    "context_hints": ["marathon training", "running shoes"],
    "bidding_config": { "max_bid_micros": 700000 },
    "ads": [
      {
        "name": "Marathon shoes card",
        "creative": {
          "type": "chat_card",
          "title": "Premium Running Shoes",
          "body": "Lightweight and built for marathon training.",
          "cta": "Shop Now",
          "image_url": "https://cdn.example.com/nike-shoes.jpg"
        }
      }
    ]
  }'
{
  "id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
  "name": "Runners — focus playlists",
  "context_hints": ["marathon training", "running shoes"],
  "status": "active",
  "bidding_config": {
    "billing_event_type": "impression",
    "max_bid_micros": 700000
  },
  "created_at": 1775088000,
  "updated_at": 1775088000
}

Retrieve an ad group

GET /v1/ad_groups/{id}
id
string
required
The ad group’s id.
curl "https://api.thrad.ai/v1/ad_groups/9a1f2c3d-4e5f-6789-abcd-ef0123456789" \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
  "name": "Runners — focus playlists",
  "context_hints": ["marathon training", "running shoes"],
  "status": "active",
  "bidding_config": {
    "billing_event_type": "impression",
    "max_bid_micros": 700000
  },
  "created_at": 1775088000,
  "updated_at": 1775174400
}

Update an ad group

POST /v1/ad_groups/{id} Patch the mutable fields. Only the fields you send are changed.
id
string
required
The ad group’s id.
name
string
New display name.
context_hints
string[]
Replacement set of context hints.
bidding_config
object
Bidding settings. Send max_bid_micros to change the max bid.
status
string
Optionally set active, paused, or archived directly. archived deactivates the ad group, so it reads back as paused. You can also use the dedicated /activate, /pause, and /archive actions below.
curl -X POST "https://api.thrad.ai/v1/ad_groups/9a1f2c3d-4e5f-6789-abcd-ef0123456789" \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Runners — focus playlists (v2)",
    "bidding_config": { "max_bid_micros": 850000 }
  }'
{
  "id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
  "name": "Runners — focus playlists (v2)",
  "context_hints": ["marathon training", "running shoes"],
  "status": "active",
  "bidding_config": {
    "billing_event_type": "impression",
    "max_bid_micros": 850000
  },
  "created_at": 1775088000,
  "updated_at": 1775260800
}

Activate, pause, or archive an ad group

POST /v1/ad_groups/{id}/activate
POST /v1/ad_groups/{id}/pause
POST /v1/ad_groups/{id}/archive
These are the recommended way to change an ad group’s status. Each returns the updated ad group object.
id
string
required
The ad group’s id.
Status actions require the parent campaign to be approved. If the parent campaign is still pending approval, the action returns 400 campaign_pending_status_locked; if it has been completed or blocked, it returns 400 campaign_terminal.
Thrad ad groups have no separate archived state, so /archive deactivates the ad group and it reads back with status: "paused" — the same result as a PATCH with status: "archived". Use /activate to bring it back.
curl -X POST "https://api.thrad.ai/v1/ad_groups/9a1f2c3d-4e5f-6789-abcd-ef0123456789/pause" \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY"
{
  "id": "9a1f2c3d-4e5f-6789-abcd-ef0123456789",
  "campaign_id": "1b2c3d4e-5f60-7182-93a4-b5c6d7e8f901",
  "name": "Runners — focus playlists",
  "context_hints": ["marathon training", "running shoes"],
  "status": "paused",
  "bidding_config": {
    "billing_event_type": "impression",
    "max_bid_micros": 700000
  },
  "created_at": 1775088000,
  "updated_at": 1775347200
}

Errors

Errors use the bare error shape:
{
  "error": {
    "message": "`bidding_config.max_bid_micros` exceeds the allowed maximum.",
    "type": "invalid_request_error",
    "param": "bidding_config.max_bid_micros",
    "code": "invalid_value"
  }
}
StatuscodeWhen
400requiredcampaign_id, name, context_hints, ads, or another required field is missing or empty
400invalid_valuemax_bid_micros is non-integer or outside 1100000000, the ads do not share one creative type, or a creative is missing or not an object
400string_too_longA creative title exceeds its limit (30 for cards, 120 for polls)
400poll_cannot_be_aiA poll ad was sent with auto_generate: true
400campaign_pending_status_lockedA status action was attempted while the parent campaign is still pending approval
400campaign_terminalA status action was attempted while the parent campaign is completed or blocked
401auth_requiredThe Authorization header is missing
401invalid_api_keyThe Authorization header is malformed, unknown, or revoked
404not_foundThe ad group or its campaign does not exist or belongs to another organization
429rate_limit_exceededPer-key rate limit (1000/hour) exceeded