X Ads API campaigns: the limits its docs state twice
X Ads API campaigns have two documented ceilings each, and the two objects every campaign depends on cannot be created outside the sandbox.
The short version
- ▸The default ceiling is 200 active campaigns per ads account. One X page says an account manager can raise it to 4,000; the reference page for the endpoint that creates campaigns says 8,000. Each number appears exactly once in X's entire 4.86 MB documentation corpus.
- ▸Active line items are capped at 256 across all campaigns according to the POST line_items reference, and at 4,000 according to the hierarchy page. Both numbers also appear exactly once. The 100-per-campaign limit is the only line item ceiling the docs agree on.
- ▸A campaign needs an ads account and a funding instrument, and neither can be created through the API in production. Six of the 87 Campaign Management endpoints are marked SANDBOX ONLY, and those six are exactly the create and delete paths for accounts, account features and funding instruments.
- ▸POST campaigns defaults entity_status to ACTIVE. X's own Ads MCP server always creates campaigns and line items PAUSED. Two official front doors to the same endpoint, opposite safety defaults.
- ▸The step-by-step campaign walkthrough on X's docs calls /8/, /9/ and /5/. Version 9 reached end of life on 31 March 2022. The reference pages next to it are all on /12/, current since 27 October 2022.
Quick answer
X Ads API campaigns are created with POST accounts/:account_id/campaigns, and the two objects that call depends on - an ads account and a funding instrument - cannot be created through the API in production. Six of the 87 Campaign Management endpoints are marked SANDBOX ONLY, and they are exactly those create paths. Worse for anyone building quota logic: the campaign ceiling and the line item ceiling are each documented twice with different numbers. 4,000 or 8,000 campaigns. 256 or 4,000 active line items. Pick wrong and your integration either refuses work it could do or promises work the API will reject.
Last updated: November 2026
Everything below was read on 14 November 2026 against X's own documentation and the flattened corpus at docs.x.com/llms-full.txt, which is 4,858,201 bytes of every doc page in one file and therefore the cheapest way to prove how many times X says something.
The two objects you cannot create
Campaign structure is four objects deep: funding instrument, campaign, line item, promoted post. Budget and schedule live on the campaign. Targeting, bidding, objective and creative live on the line item. Nothing serves until a creative is attached.
Only the bottom two of those four are yours to create.
Funding instruments are explicit about it: "Funding Instruments can not be created via the Ads API, they have to be already established by the advertiser's account manager at X (for credit lines) or via ads.x.com (for credit cards)." The ads account is the same story by omission. POST accounts exists in the reference, and it carries a SANDBOX ONLY banner and a resource URL on ads-api-sandbox.x.com.
Six endpoints carry that banner, and the set is revealing:
| Endpoint | Production |
|---|---|
POST accounts | Sandbox only |
DELETE accounts/:account_id | Sandbox only |
POST accounts/:account_id/features | Sandbox only |
DELETE accounts/:account_id/features | Sandbox only |
POST accounts/:account_id/funding_instruments | Sandbox only |
DELETE accounts/:account_id/funding_instruments/:id | Sandbox only |
In production you can rename an ads account with PUT accounts/:account_id. You cannot create one, delete one, grant it a beta feature, or give it money. That is deliberate and sensible - these are billing objects - but it changes the shape of any onboarding flow you build. An agency tool cannot provision an advertiser. It can only attach to an advertiser who has already been provisioned by a human at X or through the Ads UI.
Against that, the sandbox is genuinely useful here. Call POST accounts on ads-api-sandbox.x.com, mint a funding instrument of type CREDIT_LINE with whatever credit limit you like, and build the whole integration while your X Ads API access application is still in review. X notes there is no risk of incurring costs on a sandbox funding instrument, and sandbox campaigns never serve to users.
Every ceiling, stated twice
Here is what X publishes about how much one ads account can hold.
| Limit | Hierarchy page | Campaign Management overview | Endpoint reference |
|---|---|---|---|
| Active campaigns, default | 200 | 200 | 200 |
| Active campaigns, raised | "can be elevated" | 4,000 | 8,000 |
| Line items per campaign | 100 | 100 | 100 |
| Active line items, all campaigns | 4,000 | not stated | 256 |
Two of those rows are straight contradictions, and they are not typos buried in an old changelog. I grepped the full corpus: 4,000 active campaigns appears once, 8,000 active campaigns appears once, 256 active line items appears once, 4,000 active line items appears once. Four load-bearing numbers, four single mentions, two disagreements.
The 256 figure is the one that matters most, because it is 15 times smaller than the alternative and it lives on POST accounts/:account_id/line_items - the page you read while writing the call. If 256 is real, a single campaign at the 100-line-item maximum consumes 39% of your account's entire line item budget. If 4,000 is real, line items are effectively unlimited for most advertisers. There is no way to tell from the documentation which is true, and the API returns no quota endpoint to ask.
What makes this expensive rather than merely untidy is the definition of "active". The glossary says a paused campaign is still active for limit purposes. The overview says paused campaigns count as active until their designated end times. The endpoint reference says there is no limit to the number of inactive campaigns. Combine them and you get the rule nobody writes down: a paused campaign with a null end_time never stops counting. If your tool pauses campaigns instead of deleting them, which is the safe-looking choice, you will walk into the 200 ceiling and the error will not explain why.
Practical advice: treat 200 campaigns and 256 active line items as your real budget, delete what you will not reuse rather than leaving it paused forever, and ask the advertiser's X account manager to confirm their account's actual raised limit in writing before you design around either published number.
The walkthrough runs on dead versions
Ads API endpoints are versioned in the URL path, and version 12 has been current since 27 October 2022. Two versions are accepted at a time, so /11/ and /12/ work and everything older does not.
"Creating a Campaign - Step-by-Step", the single page a new integrator follows end to end, calls /8/ fourteen times, /9/ seven times and /5/ once. Not one example in that narrative is on a live version. Per X's own version table, /9/ reached end of life on 31 March 2022, /8/ on 31 August 2021, and /5/ on 3 March 2020.
Its reference page, one click away, uses ads-api.x.com/12 in 159 places. So the facts are current and the copy-pasteable commands are not. Read the guide for the sequence, take the paths from the reference, and if you want to see the version that actually works in a guide, the Dynamic Product Ads walkthrough is on /12/ throughout.
Fields with exactly one legal value
Three parameters on the campaign write path are vestigial, and knowing which saves a day of integration guesswork.
budget_optimization is documented with a default of LINE_ITEM and possible values of, in full, LINE_ITEM. There is one legal value. It exists because there used to be more.
standard_delivery is now explicitly "deprecated at the campaign level", because budget optimization is always LINE_ITEM, so standard versus accelerated pacing is set on the line item instead. X's own MCP documentation confirms the practical consequence: create_campaign does not accept standard_delivery at all.
entity_status is the one to be careful with. Its default on POST campaigns is ACTIVE. The MCP server, by contrast, always creates campaigns and line items PAUSED and requires an explicit activate_campaign call. Same company, same underlying endpoint, opposite default. If you write directly against REST and omit entity_status, you get a live campaign. It cannot serve yet - the response returns servable: false with reasons_not_servable: ["INCOMPLETE"] until a line item and creative exist - but the moment those attach, it spends. Send entity_status=PAUSED on every create and activate deliberately.
One more asymmetry worth knowing before you build an edit screen: the goal enum on POST line_items has 16 values and the enum on PUT line_items/:line_item_id has 15. The missing one is SITE_VISITS, which is the default goal for WEBSITE_CLICKS - and the PUT page's own pay_by description still says "The SITE_VISITS goal supports IMPRESSION values." A documented value absent from the enum on the same page that discusses it.
The limit that stops you first
Ads API rate limits have no programmatic index. You read them from x-rate-limit-* and x-account-rate-limit-* response headers, and X states plainly that it generally cannot raise them.
Core entity reads - campaigns, line items - get 10,000 per 15 minutes at ad account level, which is generous. Writes get 450 per minute as a category. The number that bites is global reads, meaning any GET without an :account_id in the path: 5 per 15 minutes. Twenty-one of the 87 Campaign Management endpoints are shaped that way, including every targeting discovery call and, critically, GET accounts - the first request in both official walkthroughs.
Call GET accounts in a debug loop and you are locked out in under a minute for reasons the error will not make obvious. Fetch the account list once, cache the account_id, and never ask again.
Targeting discovery sits in an awkward spot here too. The rate limit chart lists both a "Targeting Criteria" category at 400 per 15 minutes and the 5-per-15-minutes global read bucket, and endpoints like GET targeting_criteria/locations qualify for both descriptions with no statement of which applies. Treat them as global reads, cache the results - locations, interests, devices and TV markets barely change - and you never have to find out.
What this means if you are not building a campaign tool
Most people reading about X Ads API campaigns are weighing paid reach against organic reach, not writing an integration. Two things from the above are worth carrying over.
First, the objective list is the shape of the product. Eight values, priced per objective: CPE for ENGAGEMENTS, CPF for FOLLOWERS, CPM for REACH, CPLC for WEBSITE_CLICKS. You are buying one action type per campaign, and you cannot mix objectives inside a campaign, which is why real X ads costs vary so much by goal. Promoted Trends are not purchasable through the API at all.
Second, spend is not spend for three days. X says billing metrics should be treated as speculative until roughly 72 hours after the event, and that the final number is always lower because it is corrected for spam and low-quality traffic. Any dashboard that reconciles same-day is reconciling a number that will shrink.
If you want the paid side automated end to end, the sanctioned route is this API plus X custom audiences for targeting and OAuth 2.0 for auth - and the clock on that auth matters, since X API OAuth 1.0a user authentication stops working on 31 January 2027 while the Ads API fundamentals pages still instruct you to sign with it. The lowest-effort way to drive it today is X's own hosted server, covered in our X MCP server walkthrough, which wraps all of this in 74 tools and defaults to paused writes.
For the organic half of the same account, X-Autopilot runs on your own Mac with your own session and residential IP instead of a shared cloud pool, which lowers the detection surface compared with cloud schedulers without eliminating it. Browser-driven automation of your own account is a gray area X has never endorsed, and no tool can honestly tell you otherwise. The Ads API is the opposite: approved, documented, rate limited in writing, and billed to a funding instrument you set up by hand.
The bottom line
The X Ads API campaign surface works, and it is better specified than most ad APIs - 87 endpoints, real enums, a free sandbox that mints fake money. What it does not have is a single authoritative statement of how much one account can hold. Two pages claim different raised campaign ceilings, two pages claim line item caps 15 times apart, and three pages disagree about whether a paused campaign counts.
Until X reconciles them, build against the smaller number in every pair, delete rather than pause, cache GET accounts on first call, and send entity_status=PAUSED on every create. None of those choices costs you anything if the generous numbers turn out to be the real ones.
Frequently asked
Answers indexed by Google + AI assistants.
How many campaigns can one X ads account have?+
200 active campaigns by default, and X documents the raised ceiling twice with different values. The Campaign Management overview says the limit 'can be raised to 4,000 active campaigns manually by the advertiser's X Account Manager upon request'. The reference entry for POST accounts/:account_id/campaigns says it 'can be raised to 8,000 active campaigns'. Both statements were live on 14 November 2026. Plan for 200 and ask your account manager what your own ceiling actually is.
Do paused campaigns count toward the X Ads API campaign limit?+
Depends which page you read, which is the problem. The hierarchy glossary says a paused campaign is still an active campaign for the purposes of campaign limits. The Campaign Management overview says paused campaigns are considered active until their designated end times. The POST campaigns reference says there is no limit to the number of inactive campaigns. Safest reading: a paused campaign with no end_time counts against you indefinitely, so delete what you will not reuse.
Can I create an X ads account or a funding instrument through the API?+
Not in production. Funding instruments must already exist, set up by an account manager for credit lines or through ads.x.com for a credit card. POST accounts and POST accounts/:account_id/funding_instruments are both marked SANDBOX ONLY and resolve against ads-api-sandbox.x.com, where X notes there is no risk of incurring costs. In production you can rename an ads account with PUT, but you cannot create one.
What objective values does the X Ads API accept?+
Eight: APP_ENGAGEMENTS, APP_INSTALLS, FOLLOWERS, ENGAGEMENTS, REACH, VIDEO_VIEWS, PREROLL_VIEWS and WEBSITE_CLICKS. The objective is set on the line item, not the campaign, and every line item inside one campaign must share the same objective and the same product_type. Mixed-objective campaigns are rejected, so an account structure that mirrors the Ads UI needs one campaign per objective.
Does the X Ads API create campaigns paused?+
The REST endpoint does not. POST accounts/:account_id/campaigns documents entity_status with a default of ACTIVE and possible values ACTIVE, DRAFT and PAUSED. A freshly created campaign with no line item cannot serve, and the response proves it by returning servable false with reasons_not_servable including INCOMPLETE, but the campaign itself is live the moment a servable line item and creative attach to it. X's hosted Ads MCP server behaves differently and always creates both objects PAUSED.
Why do my X ads spend numbers keep changing?+
They are not final for three days. X states that billing metrics may not be finalised until three days after the event and should be treated as speculative before that, and that the final billable number will always be lower than the speculative one because it is corrected for spam and low-quality traffic. Build reconciliation around a 72-hour lag rather than reconciling same-day totals.
- X developer docs, Ads API 'Campaign Management': the 200 active campaign default with a stated raise to 4,000 by account manager request, paused campaigns counted as active until their end times, the eight objective values and their pricing models, the funding instrument types, and the three-day billing finalisation window (accessed 14 November 2026)
- X developer docs, 'Campaign Management API Reference': 87 endpoints, the POST campaigns note stating the limit can be raised to 8,000, entity_status defaulting to ACTIVE, budget_optimization with LINE_ITEM as its only value, the POST line_items note capping active line items at 256 across all campaigns, and the SANDBOX ONLY markings on the account, feature and funding instrument write paths (accessed 14 November 2026)
- X developer docs, Ads API 'hierarchy and terminology': the 200 active campaign limit with no stated raised value, a paused campaign counted as active for campaign limits, up to 100 line items per campaign with 4,000 active line items per account, and one FULL promotable user per ads account (accessed 14 November 2026)
- X developer docs, Ads API 'Versions': version 12 introduced 27 October 2022 with deprecation and end of life both TBD, version 9 end of life 31 March 2022, version 8 end of life 31 August 2021, version 5 end of life 3 March 2020, and the two-concurrent-version policy (accessed 14 November 2026)
- X developer docs, Ads API 'Sandbox': the ads-api-sandbox.x.com host, campaigns created there never serving to users, and the six sandbox-only endpoints for accounts, features and funding instruments (accessed 14 November 2026)
- X developer docs, Ads API 'Rate limiting': the full chart including 5 requests per 15 minutes for global reads, 450 writes per minute as a category, 10,000 core entity reads per endpoint at ad account level, and the statement that there is no programmatic index of per-endpoint limits (accessed 14 November 2026)
- X developer docs, 'X Ads MCP': 74 tools at ads-api.x.com/mcp, and the statement that campaigns and line items are always created PAUSED so nothing spends until explicitly activated (accessed 14 November 2026)
- X developer docs, 'llms-full.txt', the flattened documentation corpus at 4,858,201 bytes: one occurrence each of '4,000 active campaigns', '8,000 active campaigns', '256 active line items' and '4,000 active line items' (fetched and grepped 14 November 2026)
Product designer and indie hacker. Runs the agent on his own X account every day and writes up what the data shows, including when it's inconvenient.
Follow on X →