How to get your OpenAI Ads API usage, balance and spend programmatically
What the OpenAI Ads API exposes
| Signal | OpenAI Ads |
|---|---|
| Balance | No |
| Spend history | Yes. GET /v1/campaigns/{id}/insights (campaign.spend, campaign.clicks, campaign.impressions) |
| Cost breakdown | No |
| Plan and quota | No |
| Cost on each response | No |
| Rate-limit headers | None |
| Credential | API key |
Call it yourself
Credential. An Advertiser API key (sk-svcacct-…), created in Ads Manager under Settings → General → API Keys. This is not an OpenAI model API key. The key grants full Ads Management access and there is no read-only scope, so create a dedicated key for Argus that you can revoke on its own. Argus only issues GET requests.
Ad account (also the key check)
curl https://api.ads.openai.com/v1/ad_accounts \ -H "Authorization: Bearer $OPENAI_ADS_API_KEY"
{
"object": "list",
"data": [
{
"id": "adacct_6ac9…",
"status": "active",
"name": "Bear Scan",
"currency_code": "USD",
"timezone": "America/Chicago"
}
],
"has_more": false
}Trimmed to the fields Argus reads. Values are examples.
Campaigns
curl "https://api.ads.openai.com/v1/campaigns?limit=500" \ -H "Authorization: Bearer $OPENAI_ADS_API_KEY"
{
"object": "list",
"data": [
{
"id": "cmpn_…",
"status": "active",
"bidding_type": "clicks",
"billing_event_type": "click",
"budget": { "daily_spend_limit_micros": 50000000 },
"start_time": 1760054400
}
],
"has_more": false,
"last_id": "cmpn_…"
}Trimmed to the fields Argus reads. Values are examples.
Daily spend for one campaign
curl -g "https://api.ads.openai.com/v1/campaigns/$CAMPAIGN_ID/insights?time_granularity=daily&fields[]=campaign.spend&fields[]=campaign.clicks&fields[]=campaign.impressions&fields[]=metadata.readable_time" \ -H "Authorization: Bearer $OPENAI_ADS_API_KEY"
{
"object": "list",
"data": [
{ "readable_time": "2026-10-20", "spend": 33.91, "clicks": 13, "impressions": 1404 },
{ "readable_time": "2026-10-21", "spend": 0, "clicks": 6, "impressions": 609 }
],
"has_more": false
}Trimmed to the fields Argus reads. Values are examples.
Gotchas
- Fields are an array parameter: repeat fields[]=…, because repeating fields= is rejected as a duplicate. With no fields you get impressions only.
- Response keys drop the campaign. prefix, so campaign.spend comes back as spend. Spend is in dollars, not micros. Campaign budgets are micros.
- Today's spend is preliminary. Clicks arrive within minutes but spend finalizes after the day ends, so today can read 0.00 with clicks recorded. On the account we checked, the console's billing screen showed $17.96 more than the insights total while the day was open.
- readable_time is a date in the ad account's timezone (America/Chicago on the account we checked). A timezone field inside a date_range is accepted but ignored. Argus requests plain date_ranges and treats each day as the ad account's local day, not a UTC day.
- List endpoints cap limit at 500; a larger value is a 400. Errors come back as type server_error even for a 400, and a bad key is a 401 with code invalid_api_key.
- ads.openai.com/v1/* answers with a Cloudflare challenge. The API host is api.ads.openai.com.
- Billing balance, the automatic charge threshold and promo progress are not in the API. OpenAI's Ads API reference has no billing endpoint.
- Argus supports USD ad accounts only.
How OpenAI Ads charges
Advertiser spend in ChatGPT, billed per click (or per impression on impressions campaigns) within campaign daily budgets. Postpaid: charged automatically at a spend threshold; no balance in the API.
At zero. Postpaid, not prepaid: the card is charged automatically once spend reaches a threshold ($100 on the observed account, console-observed). Delivery is capped by each campaign's daily budget (budget.daily_spend_limit_micros). The threshold, outstanding balance and promo progress are console-only and not in the API.
Or let Argus track it
Paste the key once. Argus keeps the ledger, and your coding agent reads it through the MCP server.
- Pulls OpenAI Ads's daily cost buckets every hour for month-to-date spend and a projected month-end total.
- With the SDK, counts each call to OpenAI Ads. Calls aren't priced individually.
- Emails you on low balance, days to zero, a spend spike, or projected overage.
- Hands all of it to your coding agent over MCP, so it can ask what a run cost or how much runway is left without leaving the editor.
> what has openai_ads cost today, and how long until it runs out?
get_overview → openai_ads: mtd spend, burn per day, days to zero
get_request_costs { "provider": "openai_ads", "limit": 25 }
get_advisories → credits_low, spend_spike, rate_limit_low …Questions
- Does OpenAI Ads have an API for its balance?
- OpenAI Ads (ChatGPT Ads) has no billing-balance API. Daily spend, clicks and impressions come from GET /v1/campaigns/{id}/insights on api.ads.openai.com, one call per campaign. Your balance, charge threshold and promo progress are only in the Ads Manager console.
- Can I get OpenAI Ads spend per day from the API?
- Yes, from GET /v1/campaigns/{id}/insights (campaign.spend, campaign.clicks, campaign.impressions), in daily buckets.
- What happens when OpenAI Ads credits run out?
- Postpaid, not prepaid: the card is charged automatically once spend reaches a threshold ($100 on the observed account, console-observed). Delivery is capped by each campaign's daily budget (budget.daily_spend_limit_micros). The threshold, outstanding balance and promo progress are console-only and not in the API.
- What key does Argus need for OpenAI Ads?
- An Advertiser API key (sk-svcacct-…), created in Ads Manager under Settings → General → API Keys. This is not an OpenAI model API key. The key grants full Ads Management access and there is no read-only scope, so create a dedicated key for Argus that you can revoke on its own. Argus only issues GET requests.
Related
Pricing and limits verified 2026-10-21 against developers.openai.com/ads/bidding-and-budgets (bidding_type clicks | impressions | conversions; billing_event_type click | impression), developers.openai.com/ads/reporting (spend, clicks, impressions; current-day periods are partial), developers.openai.com/ads/api-reference/insights (date_range, pagination; a date_range timezone is ignored, days are account-local), Live account sample, campaigns list and campaign insights, captured 2026-10-21, ads.openai.com console, observed 2026-10-21. Endpoints are the ones the Argus OpenAI Ads connector calls.
Connect a provider key, point Claude Code or Cursor at the Argus MCP server, and ask what the last run cost.