openai/campaigns/ directory (or wherever your account root points via imports). A single file can contain multiple [[campaigns]] entries. Adjar reads these files to understand your current campaign setup and writes changes back in the same format — making your entire campaign structure readable and editable by both humans and AI agents.
An OpenAI Ads campaign holds ad groups, and each ad group holds ads. Budget lives on the campaign; the bid lives on the ad group.
Full Example
[[campaigns]] Fields
string
required
The campaign’s display name. 3–1000 characters. A clear convention (e.g.
<Topic> | CHATGPT) helps AI agents identify campaigns unambiguously.string
required
Controls whether the campaign is actively serving.
active and paused are the only values you set in config. To remove a campaign, delete its block from TOML — the next apply archives the live campaign. (Adjar writes OpenAI’s archived state during that archive; it is never something you author.)string
An optional free-text internal description for the campaign. Not shown to users — it’s a note for you and your AI agent. Omit for none.
string
default:"impressions"
What the campaign pays for.
number
The campaign’s daily spend cap, in US dollars. Set exactly one of
daily_budget_usd or lifetime_budget_usd — not both.number
The campaign’s lifetime spend cap, in US dollars — the total the campaign may spend over its whole run. Set exactly one of
lifetime_budget_usd or daily_budget_usd.Budgets are expressed in dollars in config; Adjar converts to and from the API’s micros (1 USD = 1,000,000 micros) on your behalf.
string
When the campaign begins serving, as an ISO 8601 timestamp (e.g.
2026-01-01T00:00:00Z). Omit for no fixed start. Adjar stores the human-readable ISO form and converts to the API’s Unix timestamp on write.string
When the campaign stops serving, as an ISO 8601 timestamp. Omit for an open-ended campaign.
array of strings
An inclusion list of location IDs to target (the API’s
targeting.locations.include). Ads are eligible only in these locations; an empty or omitted list means no location restriction.Location IDs are OpenAI’s numeric identifiers — e.g. "1000232" is the United States. Read them off an imported campaign or the OpenAI Ads dashboard; Adjar passes them through as-is.array of strings
IDs of the conversion events associated with this campaign (the API’s
conversion_event_setting_ids). Reference conversion event settings — declared as [[conversions]] or created in the dashboard — by their ID. Order-insensitive.[[campaigns.ad_groups]]
Ad groups sit inside a campaign and contain ads. Each [[campaigns.ad_groups]] entry must appear after the [[campaigns]] entry it belongs to. Unlike Google Ads, the bid lives here, on the ad group, not on the campaign.
string
required
The ad group’s display name. 3–1000 characters, unique within the parent campaign.
string
required
Whether the ad group is eligible to serve.As with campaigns,
active and paused are the only values you set; remove the ad-group block to archive it.string
An optional free-text internal description for the ad group. Not shown to users. Omit for none.
string
default:"impression"
The billing event for the ad group’s bid (the API’s
bidding_config.billing_event_type).number
required
The ad group’s maximum bid, in US dollars — the most you’ll pay per
billing_event. Converted to the API’s micros on write.array of strings
Optional free-text hints describing the audience and conversations this ad group should target inside ChatGPT. Each entry is a natural-language description of intent, topics, and signals. Omit for none.
[[campaigns.ad_groups.ads]]. See Creatives for those fields.
Related Pages
- Account Root — how campaigns are imported via
openai.toml - Creatives — the
chat_cardads nested inside ad groups - Conversions — the event settings
conversion_event_idsreferences - OpenAI Ads API access — producing the
openai.jsoncredentials file