On January 26, 2027, Apple Ads (formerly Apple Search Ads) shuts down its Campaign Management API 5. The Apple Ads Platform API changelog says the old API "will be sunset" then; Platform API 1.0 has been available since August 2026. Plan for every script, dashboard, rule engine or MCP server still on v5 to stop managing campaigns and pulling reports that day.
The sunset retires an API, not your campaigns: expect them to keep serving at their last bids and budgets. Minus the CPA pauses or pacing your scripts used to apply.
The good news: authentication stays the same. The bad news is quieter: the shape of campaign objects, the meaning of the ID you send with each request, and a rule for arrays. A migration that swaps only the base URL and a header can compile, pass a smoke test and still do the wrong thing.
The checklist: what to verify before January 26
Eight checks. Four for everyone, four for anyone who let an agent near the account.
What breaks
- 1. API version and numbers. Nothing in your code, MCP config or scheduled jobs calls the v5 host. Now, while both APIs answer, pull the last full day's campaign report from each in one time zone and diff spend, taps and the same install column, tap-through or total. Check that a campaign, ad group and keyword keep their IDs. On January 28, compare your dashboard's spend for January 27 with the console in one time zone: Apple's reports default to your organization's, and your dashboard may use UTC. (How to find v5 calls, what reports change)
- 2. IDs. Ad account IDs come from
GET /v1/acls, not from an oldorgIdin a config file or anorgIdfield in a v1 response. (Why) - 3. Payloads. Every field your code writes exists in the v1 schema, every PUT that touches an array sends the full array, keyword bid updates never send
null, and dayparting slots match the ad account's time zone. (Details) - 4. Keys, roles and grants. You know where each private key lives, including vendor copies, which role each API user holds, which third-party services each admin has granted under Account Settings > API, and when each pre-signed client secret expires. (OAuth, grants)
While you're in there: what your agent can write and what it can see
- 5. Write access off by default. An agent that only reports runs on a read-only role or grant. Write access is a separate, deliberate step.
- 6. Limits and a log. Writes have a ceiling per change, get read back and leave an auditable record. The agent has its own API user or grant, and Change History is exported on a schedule. (Details)
- 7. Context cost. Count the tool descriptions your agent loads and the tokens they take; the cost repeats on every request. If your client allows it, load only the tools a task needs.
- 8. Revenue and attribution gaps. The agent sees revenue next to Apple's taps and installs, or it can't tell which keywords bring paying users. You know where attribution goes dark: since September 2026, Apple returns
attribution = falsewhere age or gender settings are used (AdServices changelog).
Running your own scripts? Start with what changes in your integration. Using an MCP server or an agent? Go to what to check in the agent.
When does Apple Ads Campaign Management API 5 shut down?
On January 26, 2027. The v5 changelog marks v5 as deprecated. Neither changelog describes a grace period or a read-only mode, so plan as if every v5 call fails that day.
How do you tell whether your stack still calls v5?
v5 is easy to spot. Search for the old host. v5 calls go to api.searchads.apple.com/api/v5/, and most carry X-AP-Context: orgId=… (v5 calling guide). Platform API calls go to api.ads.apple.com/v1/ with X-AP-Context: adAccountId=….
Grep repositories, local MCP and CLI configs and old scheduled jobs for searchads.apple.com and orgId=: code often builds URLs from parts. For tools you don't host, ask the vendor which Apple API their Apple Ads features call, and since when.
What changes if you run your own integration on the API?
Almost everything you touch: the URL, the scoping header and most object shapes. The Platform API is a new resource model, not a v6 with a fresh coat of paint.
| What | Campaign Management API 5 | Apple Ads Platform API 1.0 |
|---|---|---|
| Base URL | api.searchads.apple.com/api/v5/ | api.ads.apple.com/v1/ |
| Request scope | X-AP-Context: orgId=… | X-AP-Context: adAccountId=… |
| Who am I | GET /me returns userId, parentOrgId | GET /v1/me returns userId, orgId |
| Keyword update | PUT …/campaigns/{campaignId}/adgroups/{adgroupId}/targetingkeywords/bulk | PUT /v1/keywords/{id} or bulk endpoints |
| Lookups | …/find endpoints, many nested under a parent | POST /{entity}/query with filters, entities at the top level |
| Campaign owner | orgId | adAccountId |
| App | adamId (integer) | promotedObjectType + promotedObjectId (string) |
| Daily budget | dailyBudgetAmount | dailyBudget.value |
| Countries, placements | countriesOrRegions, supplySources | targeting object |
| Campaign bidding | biddingStrategy, targetCpa | bidStrategy object |
| Ad group default bid | defaultBidAmount, cpaGoal | bidStrategy (type, goal, bid); cpaCap deprecated |
| Keyword bid | bidAmount (null falls back to the ad group bid) | bid (null on update returns an error) |
| Dayparting | daypart.userTime.included (integers) | targeting.daypart.include (strings) |
| Serving state | servingStatus, servingStateReasons | systemStatus, systemStatusReasons |
| Budget orders | budgetOrders | sharedBudgets |
| Impression share | custom report, returns a report ID | POST /v1/insights/apps/impression-share/query, results directly; 400 without a promotedObjectId filter |
| Report rows | row[].total, granularity | rows[].totalMetrics, granularMetrics |
| Report totals | grandTotals | summary.grandTotal |
Sources: Apple's references for campaigns (v5, v1), ad groups (v5, v1), keywords (v5, v1), keyword updates (v5, v1), dayparting, impression share and the v1 calling guide. We matched fields by their descriptions.
Why can a find-and-replace migration still break?
Because the failures don't point at the cause. A permissions glitch. A campaign that shrank to one country. A bid that didn't take.
orgId survived, one level up. In v5, orgId "is the same as your account," says the v5 Campaign reference. In v1 the hierarchy is Org → Ad Accounts → Campaigns, and the orgId that GET /v1/me and /v1/acls still return names the organization (Apple: managing ad accounts). An ad account serves either the App Store or Apple Maps, so an org on both has at least two. Fill adAccountId from orgId, and the likely 403 or 404 won't say the ID is the wrong kind. On one developer's main account the two values matched, "the coincidence that teaches the wrong rule," as the pull request puts it (thevarungrovers on GitHub): that organization had several ad accounts. Take adAccount.id from GET /v1/acls, which needs no X-AP-Context header.
Arrays in a PUT replace the whole list. An array you send in a PUT "replaces the existing values entirely," says v1's calling guide. Add Germany by sending only DE in targeting.countryOrRegion.include, and the campaign runs in Germany alone. On ad groups, omitted targeting dimensions stay put, but a list you send, such as daypart or appDownloader.exclude, is replaced. Read, change, send the full list.
Bids moved into objects. On a keyword update, bid: null now returns an error instead of falling back to the ad group bid. An ad group's default bid lives in bidStrategy, whose type and goal Apple says to send together. Under a Maximize Conversions campaign, ad groups inherit the campaign's strategy and keyword bids aren't used: the developer quoted above saw a keyword-bid change in an ad group on an automated bid strategy accepted with a 200 and discarded.
Dayparting runs on the account clock. v1 evaluates targeting.daypart.include slots in the ad account's time zone. Check which clock your v5 schedule assumed.
The app ID changed type. promotedObjectId is a string where adamId was an integer. A typed client catches this at build time; hand-rolled JSON and spreadsheet joins may not.
Budget-order writes skip the new header. On accounts with a Line of Credit (LOC) payment model, writes to /v1/shared-budgets are organization-level: with an ad account header, Apple returns 403 (Apple: budget orders).
Bulk calls are all-or-nothing by default. Without allowPartialSuccess: true, one failed item rejects the batch. It protects budgets. But one keyword deleted in the console can stop a night's bid run. Alert on rejected batches.
What happens to your Apple Ads reports and dashboards?
After January 26, a report job still on v5 fails, and a job that swallows its errors fails quietly. A spend chart looks quiet, and your ROAS just starts looking great: revenue from your SDK keeps arriving, cost doesn't (check 1). Alert on a report pull that fails, not only on one that comes back empty.
Reports move to the same /query pattern: POST /api/v5/reports/campaigns becomes POST /v1/reports/apps/campaigns/query. Below the campaign level, the campaign ID moves from the path into a required campaignId filter (Apple: App Store reports). Metric names such as localSpend carry over. Pages default to 100 rows, up to 5,000 (Apple: managing reports), so a job that reads one page undercounts without failing: keep requesting pages until one returns fewer rows than your pageSize.
Dashboard filters and rule engines break on values too: a keyword's ACTIVE is now ENABLED, an ad group's CPC pricing model is now CPT, and a campaign's displayStatus gains LIMITED for reduced-capacity serving, which a filter on RUNNING misses.
Diff before you switch: "a port can only be verified while both APIs still answer," wrote the developer quoted above (thevarungrovers on GitHub). That script-by-script diff caught a bug: on a zero-delivery day, v1 omitted localSpend where v5 returned zero, so a quiet day read as missing data.
Totals can also move for a good reason. The maintainer of an open-source Python client ran both versions for a week. By the maintainer's account, without Basic accounts all 35 daily spend rows were identical; with them, v1's total was 2.0% higher, because v5 never listed them (bickster on GitHub).
Does your OAuth setup survive the move?
Mostly, yes. The setup steps carry over. Apple's v1 OAuth guide keeps the v5 sequence: an ES256 key pair, a client secret signed as a JWT, and a token with the scope searchadsorg. The Python client's maintainer reports that the v5 keys worked unchanged.
Test yours in five minutes: request a token, call GET /v1/me and GET /v1/acls, then POST /v1/campaigns/query with X-AP-Context: adAccountId=… for each account. If the campaign count matches v5, the token works; write access depends on the role /v1/acls shows. On a Basic account, a 403 may not mean a bad key: the same maintainer reports v1 refuses campaign queries there.
Watch a second clock if a client secret was pre-signed into a config. A secret must expire less than 180 days after it's issued: one signed for the longest term when Platform API 1.0 launched in August expires between late January and late February 2027. In those weeks, a failed token request or a 401 may be the secret, not the sunset.
How should you handle 429, 500 and 503 responses on the Platform API?
Our advice: retry a 429 with backoff; after a 500, 503 or timeout on a write, read the entity back before you retry, and read back the writes that succeed too. Apple's rate-limit guide says to slow down when RateLimit-Remaining runs low; after a 429, wait Retry-After, then double the wait on each consecutive 429 up to a cap such as 16 seconds. 503 isn't in the v1 error table; treat it like a 500. For a create, query by name. A 200 isn't proof: after the discarded keyword bid described above, the developer who found it now reads back every write (thevarungrovers on GitHub).
What changes if an MCP server or an AI agent manages your account?
An agent changes who calls the API, not what breaks. Everything above applies, plus three questions for whoever set it up.
Which API do its tools call? An MCP server calls Apple itself or through a vendor backend; if either is hardcoded to v5, its tools stop. Grep yours. Ask the vendor of a hosted one.
Whose credentials does it use? Apple's help page on the Platform API describes two mechanisms. Your own API user authenticates with its private key under one of four roles: API Account Manager, API Account Read Only, Limited Access API Read & Write and API Read Only. Match on the role strings /v1/acls returns (Apple: UserAcl). A hosted service either holds a copy of that key or asks you to grant access with Sign in with Apple.
Apple describes that path for campaign management partners and mobile measurement providers, so the rule covers an MMP that connects this way: each Account Admin or Campaign Group Manager can grant "only one third-party service provider per Apple Ads account at a time." As we read it, the limit is per granting admin, and Apple doesn't say what happens to an existing grant when that admin adds a provider. Decide which admin grants which service, and after each new connection, check Account Settings > API.
Who keeps the record? v1 adds Change History: every create, update and delete on campaign entities, with who, when, and the old and new values, logged by Apple rather than the agent. Every API caller is tagged CUSTOMER_API, so give the agent its own API user and filter by its userId; for a hosted grant, make one change and see how it shows up. Lookback is six months: export on a schedule.
Where Qonversion fits
Qonversion's MCP server gives your agent trials, payers and revenue next to Apple's spend, down to the keyword, for installs Apple attributes. The report counts UTC days, so run check 1 against it in UTC; where it shows an Updated label, a sync Apple didn't answer is flagged rather than passed off as a quiet day (data freshness). Pausing runs at once. Resuming, keyword-bid and campaign daily-budget changes need a separate confirmation step: keep your MCP client's permission prompt on for it. Qonversion connects with Sign in with Apple, so the provider check above applies to it too: pick the admin who grants it.
Connect MCP so your agent sees Apple Ads spend next to revenue and can manage your campaigns: pause them, change keyword bids and campaign daily budgets (Qonversion MCP server, Apple Ads tools). No Qonversion project yet? Sign up first.

Vlada
Marketing Manager at Qonversion
Vlada drives marketing initiatives at Qonversion, connecting with the mobile app community.




