Manage Ads Manager from the CLI

The Adapty CLI can manage your Ads Manager account from the terminal, under the adapty asa topic. It covers campaigns, ad groups, keywords, ads, product pages, automation rules, metrics, and competitor research.

Use it for the work that a browser makes slow: giving an AI agent live access to your ad performance, adding several hundred keywords from a file, and running the same setup across several campaigns. For everything else, the dashboard remains faster.

Warning

The CLI cannot delete anything. Campaigns, ads, and automation rules can be created, updated, and paused from the terminal, but deleting them is only possible in the dashboard.

Before you start

Ads Manager commands use the same installation and login as the rest of the CLI. If you have not set that up, follow steps 1 and 2 of the quickstart guide.

Prerequisites

Two further conditions apply to every adapty asa command:

  • A connected Apple Ads account: Connect it with adapty asa connect, or in the dashboard as described in Get started with Adapty Ads Manager.
  • An active Ads Manager subscription: Without one, every command fails with 402 ads_manager_subscription_required.

One command reports both:

adapty asa whoami

Differences from the rest of the CLI

  • There is no --app flag: The scope is the company your token belongs to. --app exists on some list commands as a filter only.
  • Writes reach Apple directly: Each command that changes your account prints the request body and asks for confirmation before sending it. There is no staging step.
  • Reads are cheap, writes are not: Run list commands and --dry-run freely. Treat everything else as irreversible.

To skip the confirmation prompt in a script, pass --yes. Under --json or in a pipe, a write command refuses instead of waiting for an answer that will never arrive, so --yes is required there.

Find the IDs you need

Every command takes UUIDs, and every UUID comes from a list command. Work down the hierarchy:

adapty asa orgs list
adapty asa campaigns list --campaign-group <campaign-group-id>
adapty asa ad-groups list --campaign <campaign-id>

Scope each read with a filter. Filters narrow the query rather than the printed page, so a scoped read is cheap while an unscoped one pages through the whole account. adapty asa keywords list without --ad-group is the widest read in the topic.

These lists return metadata only. Performance numbers come from asa metrics.

Add keywords in bulk

Adding keywords one at a time is the main reason to leave the dashboard. Put one keyword per line in a text file:

adapty asa keywords add --ad-group <ad-group-id> --from-file keywords.txt --bid 1.20 --match-type EXACT

Keywords are applied as a batch of at most 100 per call. Split larger lists across several calls.

Two kinds of failure are possible, and they behave differently. An invalid ID fails the whole batch before Apple is called, so nothing is applied. Apple can also reject individual keywords — the rest are still added, and each rejection is reported with its reason. Check the summary line rather than the exit code alone.

Start with a handful of keywords and check the result before sending a full file.

Create a Max Conversions campaign

A campaign that bids with MAX_CONVERSIONS serves only once it owns an automated ad group, so create the two together:

adapty asa campaigns create --org <campaign-group-id> --name "Max Conv" --adam-id 123456 --country US --daily-budget 50 --bidding-strategy MAX_CONVERSIONS
adapty asa ad-groups create --campaign <campaign-id> --name "Automated Max Conv" --automated

Until that ad group exists, the campaign reports serving_status: NOT_RUNNING with AUTOMATED_KEYWORDS_REQUIRED_AD_GROUP_MISSING among its serving_state_reasons, and campaigns create prints both the reason and the command that resolves it.

--automated is what satisfies the requirement — a regular ad group with --automated-keywords does not. Apple schedules and runs the automated ad group itself, so it takes no --start-time, --default-bid is optional, and it stays enabled: to stop the spend, pause the campaign.

On the campaign, keep --target-cpa lower than --daily-budget.

Set Invoicing Options for a line of credit

Apple requires Invoicing Options on every campaign in an organization that bills by line of credit. adapty asa orgs list reports each organization’s payment_modelLOC means the five --invoice-* flags apply:

adapty asa campaigns create --org <campaign-group-id> --name "LOC push" --adam-id 123456 --country US --daily-budget 50 --invoice-advertiser "Acme Inc" --invoice-order-number PO-42 --invoice-contact-name "Jane Doe" --invoice-contact-email jane@acme.com --invoice-billing-email billing@acme.com

Pass all five in one call — a partial set is rejected before the request reaches Apple. Without them, the campaign is created but reports serving_status: NOT_RUNNING with MISSING_BO_OR_INVOICING_FIELDS.

The same five flags on adapty asa campaigns update set the Invoicing Options on a campaign that already exists. They replace the stored set as a whole, so pass all five even to change one of them.

Create a campaign structure in one operation

campaigns bulk-create replaces a script that loops over campaigns create and ad-groups create. It submits a whole campaign structure — campaigns with their ad groups, keywords, negative keywords, and ads — as one operation:

adapty asa campaigns bulk-create --file structure.json

The input is a JSON description of the structure — see the structure format for the fields. JSON is the natural path for an AI agent: it generates the structure and pipes it in:

cat structure.json | adapty asa campaigns bulk-create --file -

A native Apple Ads bulk template works as input too — the server converts Campaign_And_Adgroup_Template.xlsx or a keywords .csv into a structure. --org-id takes the numeric org_id from adapty asa orgs list. To review the conversion before anything is created, add --preview:

adapty asa campaigns bulk-create --from-file Campaign_And_Adgroup_Template.xlsx --org-id 1234567 --preview

Conversion issues are reported with their sheet, row, and column. When the printed structure looks right, drop --preview to submit it.

The --preview output is also the fastest way to get a starting structure file: save it, edit it, and submit it with --file — the same way automations get provides a rule template.

The whole structure is validated before anything is created, and a rejection lists every invalid node. Once accepted, the objects are created on the server while the command reports progress. The final report is success, partial, or failed — a partial result lists each object that was not created, with Apple’s error.

For a large structure, pass --no-wait to get the operation ID back immediately and read the progress later:

adapty asa campaigns bulk-status <operation-id>

Query metrics from agents and scripts

asa metrics reports on any level of the account over a date range. Add --json so an AI agent or a script can consume the result directly:

adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --metric spend --metric roas --json

--metric takes the names that Ads Manager tracks. See Metrics for the full list.

Cohort metrics work differently from the rest. There is no ltv metric, because lifetime value is read at a renewal window rather than on a date. Ask for the window instead:

adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --metric roas --by-days 7 --by-days 90 --order-by-day 90

This returns your campaigns ranked by day-90 ROAS. Up to 16 windows fit in one call.

Each row is one entity, already aggregated and sorted on the server. A “top five campaigns by spend” question is therefore one call, not a pass over every page:

adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --order-by spend --page-size 5

Metrics and the search terms list share one analytics budget per company: 5 calls per minute, and at most 2 in any 10 seconds. Ask a narrow question once rather than polling. The reporting period is also capped by how finely you group it — 90 days by day, 180 by week, 365 by month — so widen a report by coarsening --group-by, not by splitting it into more calls.

Check competitor keywords

One command returns the keywords that competing apps bid on, for up to five App Store apps at a time:

adapty asa competitors summary --app-ids 1668337467,6503873027 --json

The period and the countries are fixed on the server — the last full month, across every country — so the command has no flags beyond the app IDs. The first call for a set of apps can take tens of seconds.

Use this to pull competitor keyword data into a report on a schedule. To filter the results, compare countries side by side, or add the keywords you find straight to a campaign, use Market Intelligence in the dashboard instead.

Run automation rules

The CLI does not build automation rules — it stores the JSON you give it. The fastest way to get a valid rule file is to build one rule in the dashboard, then read it back:

adapty asa automations get <automation-id> --json > rule.json

Edit that file and use it as the template for new rules:

adapty asa automations create --file rule.json

When you pass a file to automations update, remove the internal_id field first — the update is rejected if it is present.

Test a rule before letting it change bids:

adapty asa automations run <automation-id> --dry-run

A dry run evaluates the conditions and logs what the rule would do without touching Apple Ads. Runs are queued rather than performed immediately, so the command prints a run ID and the outcome appears in adapty asa automations runs.

Re-run scripts safely

Every write sends an idempotency key. The CLI generates one per invocation and retries once after a network error, so a request that failed in transit is never applied twice.

In a script, pin the key yourself so the whole pipeline can be re-run:

adapty asa campaigns create --org <campaign-group-id> --name "Winter push" --adam-id 123456 --country US --daily-budget 50 --idempotency-key winter-push-2026 --yes

Re-running the same command within 24 hours returns the stored result and prints Already applied earlier instead of creating a second campaign. The same key with a different body fails with 422, which catches an edited script that reuses a key by mistake.

What’s next

  • Manage Apple Ads with an AI coding tool — install the Apple Ads plugin so Claude Code, Copilot CLI, Codex, or Gemini CLI can run these commands for you.
  • Ads Manager commands — every command with its arguments, flags, and accepted values.
  • Automations — what each rule type does and which actions it can take.
  • Metrics — the metric names accepted by --metric and how each one is calculated.