For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Primary navigation

Ad Groups

Create, list, retrieve, update, and change ad group state.

List ad groups

List ad groups for a campaign.

GET /ad_groups

ParameterTypeRequiredNotes
campaign_idstringYesParent campaign ID.
limitintegerNoBetween 1 and 500. Default 20.
afterstringNoCursor for the next page.
beforestringNoCursor for the previous page.
orderstringNoasc or desc.
curl -X GET "https://api.ads.openai.com/v1/ad_groups?campaign_id=cmpn_101&limit=10" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "adgrp_301",
      "created_at": 1735689700,
      "updated_at": 1735776100,
      "name": "US English",
      "description": "Primary English-speaking audience.",
      "context_hints": ["productivity", "team collaboration"],
      "status": "active",
      "bidding_config": {
        "billing_event_type": "impression",
        "max_bid_micros": 60000
      }
    }
  ],
  "first_id": "adgrp_301",
  "last_id": "adgrp_301",
  "has_more": false
}

Create an ad group

Create an ad group for a campaign.

POST /ad_groups

FieldTypeRequiredNotes
campaign_idstringYesParent campaign ID.
namestringYes3 to 1000 chars and must include a non-space character.
descriptionstringNoAd group description.
context_hintsstring[]NoFree-form audience or placement hints.
statusstringYesactive or paused.
bidding_config.billing_event_typestringYesimpression for impression campaigns; click for click and conversion campaigns.
bidding_config.max_bid_microsintegerYesMinimum 1; the maximum depends on campaign bidding type and account currency.
product_setobjectNoInherits the campaign’s feed when omitted. Include only to specify product filters.
product_set.product_feed_idstringYes, in product_setMust match the campaign’s product feed.
product_set.filtersobject[]NoProduct filters. Don’t repeat the same field within one product set.
product_set.filters[].fieldstringYes, in each filterFeed attribute to filter.
product_set.filters[].operatorstringYes, in each filterin, gt, gte, lt, or lte.
product_set.filters[].valuesstring[]Yes, in each filterMatch values. Send numeric comparison values as strings, such as "4.5".

Field notes

Product-set filters support title, body, item_id, offer_id, price, target_url, image_url, product_category, brand, seller_name, external_seller_id, star_rating, condition, and age_group. Use gt, gte, lt, and lte only with price or star_rating.

Context hints provide extra information on when you think your ads might be useful, and help guide when they appear. Provide a list of descriptions or keywords for when the product or service might be useful to show.

Micros are millionths of the main currency unit (e.g., Dollars). The max_bid field is per event, so a $60CPM ($0.06 per impression) is passed as 60,000 to the API. Note that currency fields respect your ad account’s default currency.

For a conversion-optimized campaign (oCPC), set bidding_config.billing_event_type to click. max_bid_micros is the CPA bid even though the billing event is a click. For example, 100000000 is a $100.00 CPA bid for a USD account. For a beta-enabled product-feed oCPC campaign, use the same POST /ad_groups endpoint. The ad group automatically inherits the campaign’s product feed. Include product_set only when you want to specify product filters; its product_feed_id must match the campaign’s feed. For the full setup and reporting workflow, see Conversion-optimized campaigns and Product feeds.

curl -X POST "https://api.ads.openai.com/v1/ad_groups" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "cmpn_101",
    "name": "US English",
    "description": "Primary English-speaking audience.",
    "context_hints": ["productivity", "team collaboration"],
    "status": "active",
    "bidding_config": {
      "billing_event_type": "impression",
      "max_bid_micros": 60000
    }
  }'

Retrieve an ad group

Fetch one ad group by ID.

GET /ad_groups/{ad_group_id}

curl -X GET "https://api.ads.openai.com/v1/ad_groups/adgrp_301" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY"

Update an ad group

Update an ad group with POST.

POST /ad_groups/{ad_group_id}

All fields are optional on update. description can be set to null to clear it. If you include bidding_config, send the full object. status accepts active, paused, or archived. For a product-feed campaign, include the full product_set object to change the feed or its filters. Retrieve the ad group after the update if you need the resulting product_set; the immediate update response can omit it.

curl -X POST "https://api.ads.openai.com/v1/ad_groups/adgrp_301" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "context_hints": ["productivity", "workflow automation"],
    "status": "paused",
    "bidding_config": {
      "billing_event_type": "impression",
      "max_bid_micros": 75000
    }
  }'

Change state with dedicated actions

The Ads API also exposes explicit state transitions. Paused ad groups won’t deliver ads to customers. Only archive objects you have no further use for, as archiving isn’t reversible.

  • POST /ad_groups/{ad_group_id}/activate
  • POST /ad_groups/{ad_group_id}/pause
  • POST /ad_groups/{ad_group_id}/archive
curl -X POST "https://api.ads.openai.com/v1/ad_groups/adgrp_301/archive" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY"
{
  "id": "adgrp_301",
  "created_at": 1735689700,
  "updated_at": 1735948800,
  "name": "US English",
  "description": "Primary English-speaking audience.",
  "context_hints": ["productivity", "team collaboration"],
  "status": "archived",
  "bidding_config": {
    "billing_event_type": "impression",
    "max_bid_micros": 60000
  }
}