OpenAI Ads Is Live in Cogny: Run and Audit Your ChatGPT Ads From an Agent
OpenAI Ads Is Live in Cogny: Run and Audit Your ChatGPT Ads From an Agent
Ads in ChatGPT are the newest paid channel with a real API, and until today your agent could not touch them. Now it can. OpenAI Ads is a live MCP integration in Cogny, built directly on the OpenAI Ads Advertiser API (api.ads.openai.com/v1).
It is an API-key connection, not OAuth: you create a key in Ads Manager, paste it once, and every tool works — from the Cogny chat, from the Cogny CLI, or from any MCP client pointed at app.cogny.com/mcp.
TL;DR
- OpenAI Ads is live now. Connect it with an Ads API key from ads.openai.com → Settings → API keys, under your warehouse Settings → Cogny Managed MCPs. One key = one ad account, so there is no account picker.
- 32 tools across six areas: the account (
tool_get_ad_account), campaigns, ad groups, ads and creative uploads, insights, geo lookup, custom audiences, and conversion setup (pixels, pixel events, event settings). - Insights come back at account, campaign, ad group or ad level, bucketed hourly / daily / monthly, with an optional country or device segment — the six metrics the API exposes: impressions, clicks, spend, ctr, cpc, cpm.
- Two scheduled templates: OpenAI Ads (ChatGPT) Optimization Audit turns the data into weekly performance tickets, and OpenAI Ads Launch & Scaling Playbook checks the account against OpenAI's own structural guidance (ads per ad group, context-hint shape, card character bands, bid band, per-ad UTMs) and drafts the changes.
- Read tools are auto-approved; writes (create, update, pause, archive) ask first, like every other ads MCP in Cogny.
What is different about this channel
An OpenAI Ads campaign has no keywords and no interest graph. The targeting is a campaign-level geo block plus context hints on each ad group — free-text phrases that describe the conversations the ad should appear in. The ad itself is a chat card: a title of at most 50 characters, a body of at most 100, an image, and a target URL.
So the audit questions are new too. Are the hints describing conversations where someone is about to buy, or just conversations about the topic? Which cards earn the click? Is the pixel actually receiving events? Those are exactly the questions the template asks — see below.
Two API conventions worth knowing before you script anything, because the tools pass them through unchanged:
- Budgets and bids are micros of the account currency (
25000000= 25.00). Insight metrics are not:spend,cpcandcpmare plain currency units, andctris a fraction (0.0226= 2.26 %). - An insights
end_datemust be a completed day in the account timezone. The API rejects a range that ends today withtime_ranges.end cannot be in the future, so "month to date" means through yesterday.
The tools
Account — tool_get_ad_account returns id, name, url, currency, timezone and review.status. Call it first; it is the connection test.
Campaigns — tool_get_campaigns, tool_get_campaign, tool_create_campaign, tool_update_campaign, tool_update_campaign_status. Create defaults to paused and needs a daily and/or lifetime budget in micros, a bidding_type (impressions, clicks or conversions) and, for conversions, the conversion_event_setting_ids to optimize toward. Targeting takes country codes or location ids.
Ad groups — tool_get_ad_groups, tool_get_ad_group, tool_create_ad_group, tool_update_ad_group, tool_update_ad_group_status. This is where context_hints, the billing event (impression or click) and the bid live — a fixed max_bid_micros or a strategy such as maximize_clicks.
Ads — tool_get_ads, tool_get_ad, tool_upload_image (a public image URL in, a file_id out), tool_create_ad, tool_update_ad, tool_update_ad_status, tool_preview_ad (a 24-hour preview link of the rendered card). Every ad carries a review_status; only approved ads serve.
Insights — tool_get_insights and tool_get_conversion_insights. Pass an entity_id to scope a campaign, ad group or ad; pick the row level with aggregation_level; add a segment (country, device or product — one per query).
Geo — tool_search_geo_locations resolves "Stockholm" to the location ids the targeting block expects (countries, regions, DMAs, postal codes).
Audiences and conversions — tool_list_custom_audiences, tool_get_custom_audience, tool_create_custom_audience, tool_add_custom_audience_members, tool_remove_custom_audience_members, tool_archive_custom_audience, tool_list_pixels, tool_get_pixel_events (the last 15 minutes of events on a pixel — the fastest "is the tag firing?" check), tool_list_conversion_event_settings, tool_create_pixel, tool_create_conversion_event_setting.
The tool names are the same on every surface. In the CLI:
cogny tools call mcp__OpenAI_Ads__tool_get_insights --input '{
"aggregation_level": "campaign",
"start_date": "2026-08-01",
"end_date": "2026-08-31",
"segment": "country"
}'
The audit template
Enable OpenAI Ads (ChatGPT) Optimization Audit on the Reports page and Cogny runs it weekly. It works straight from the MCP tools (there is rarely a warehouse export for this channel yet) and grades the account on:
- Context-hint relevance — hints classified as intent, topic or brand and crossed with CTR; ad groups with impressions and no clicks get rewritten hint sets.
- Chat-card copy — every ad over 2,000 impressions and under 1 % CTR is flagged, rejected ads are surfaced, and UTM tagging on target URLs is checked.
- Geo and device fit — country and device segments against the service footprint.
- Bidding type, bids and delivery — impression bidding on accounts with conversion data, fixed bids that cannot win, budgets that never deliver.
- Conversion tracking — pixel events, event settings, click-through vs view-through, and a GA4 cross-check when GA4 is connected.
Each finding names the campaign, ad group or ad id, so the ticket it becomes can be executed through the same MCP after you approve it.
The playbook template
The audit asks how the account is performing. OpenAI Ads Launch & Scaling Playbook asks whether it is built the way the relevance model rewards. ChatGPT ads match on conversation context, and the model reads the ad group's context hints and the card's copy together — so breadth of specific creative is the targeting, not a nice-to-have. The template encodes OpenAI's Creative Launch and Scaling Guide and Context Hints Guidance as checks:
- One intent area per ad group, ~10 ads per group, ~100 per campaign. Mixed groups get a proposed split; thin groups get a build-out plan by angle (offer, outcome, question, objection, proof, process, comparison, local).
- 5–10 context hints per group, each 3–6 words in the shape
[product or category] + [use case] + [qualifier]. Persona sentences, near-duplicate hints and hints in the wrong language for the targeted market are rewritten, and every hint is checked for a card that echoes it. - Cards inside the 16–24 / 32–48 character bands. The API allows 50 / 100, but 24 and 48 are the guidance maximums and 16 and 32 are floors. Character counts are shown next to every flagged card.
- Bids inside the CPM-derived band. OpenAI's typical $15–60 CPM at the reported ~0.91 % CTR implies an effective CPC of roughly $1.65–6.59; the template places every ad group's max bid against that band and checks that the highest bids sit on the highest-intent groups.
- A unique
utm_termper ad, landing pages that answer 200 and do not block OpenAI's user agents inrobots.txt, and a dated recommendation per campaign for when to move from Clicks to Conversions bidding.
Every change comes out as a ready tool_update_ad_group or tool_create_ad payload with the drafts left paused, because OpenAI is explicit that passing format validation is not launch approval. The rules come straight from a campaign we built for Growth Hackers Sweden on this channel: one campaign, ten ad groups, 100 ads, 80 hints, with a build script that fails on any card or hint outside the bands.
How it is built
The server lives in the Cogny MCP proxy (services/mcp-proxy/src/servers/openai_ads/) next to the other ads connectors. Two things we deliberately did not paper over: the API's error envelope ({error: {message, code}}) is surfaced verbatim in every tool error, and a 403 is translated to "not enabled for this ad account, ask your OpenAI partner representative", because pixel management and brand updates are switched on per account by OpenAI.
The connection is one credential string in the Supabase vault, the same path as Klaviyo or Plausible. Nothing about your ad account is stored beyond the key.
Connect it from Settings, or run npx @cogny/cli init and let the agent do the rest.