Ads Manager commands for the Adapty Developer CLI

This article lists every Ads Manager command in the Adapty CLI, with its arguments, flags, and accepted values. Ads Manager commands live under the adapty asa topic.

These commands need a connected Apple Ads account and an active Ads Manager subscription. Run adapty asa whoami to check both. For the rest of the CLI, see the command reference.

Global flags

These flags are available on all Ads Manager commands.

FlagDescription
--jsonOutput as JSON instead of formatted text
--helpShow command help

All list commands also accept pagination flags:

FlagDefaultDescription
--page1Page number
--page-size100Items per page (max: 1000)

Ads Manager pages are larger than in the rest of the CLI. Prefer one large page over a loop of small ones.

All commands that change your account accept these flags:

FlagDescription
--yes, -yApply without asking for confirmation. Required when the output is piped or --json is used
--idempotency-keyFixed key for this write. A repeat with the same key and body within 24 hours returns the stored result instead of applying the change again

Ads Manager commands take no --app flag. The scope is the company that your token belongs to. --app exists on some list commands as a filter only.

List filters

Filters narrow the query itself, not the printed page. An unfiltered keywords list pages through every keyword in the account, so scope each read to the level you need.

FilterAccepted by
--campaign-groupcampaigns, ad-groups, keywords, negative-keywords, search-terms, ads, creatives, product-pages
--appcampaigns, ad-groups, keywords, negative-keywords, search-terms, creatives, product-pages
--campaignad-groups, keywords, negative-keywords, search-terms, ads
--ad-groupkeywords, negative-keywords, search-terms, ads
--statuscampaigns, ad-groups, ads (ENABLED or PAUSED), keywords (ACTIVE or PAUSED)
--searchcampaigns, ad-groups, keywords, negative-keywords, search-terms, ads. Case-insensitive substring match on the name

adapty asa apps list, orgs list, automations list, and automations runs take no filters. They accept pagination flags only.

--campaign-group, --app, --campaign, and --ad-group take the UUIDs printed by the matching list command, and each one is repeatable:

adapty asa keywords list --ad-group <ad-group-id> --ad-group <other-ad-group-id>

An ID that belongs to another company matches nothing, so the page comes back empty instead of returning an error.

Account

adapty asa whoami

Show the company, how Ads Manager access was granted, and whether Apple Ads is connected.

adapty asa whoami

Run this command first. It reports whether the two prerequisites for every other command are met.

adapty asa connect

Link an Apple Ads account to Adapty.

adapty asa connect

The command prints an Apple authorization link and waits until Apple reports the account as connected.

FlagDefaultDescription
--wait / --no-wait--waitWait until Apple Ads reports as connected. --no-wait returns immediately
--timeout300Seconds to wait for the browser step

adapty asa orgs list

List the campaign groups (Apple Ads organizations) available to your company.

adapty asa orgs list

Each row carries two identifiers, and they are not interchangeable:

FieldUsed as
internal_idThe UUID that --org takes on campaigns create, and that --campaign-group takes as a list filter
org_idApple’s numeric organization ID, taken by --org-id on campaigns bulk-create. --org and --campaign-group reject it

--org exists only on campaigns create. No list command accepts it.

Each row also carries a payment_model. When it is LOC, the organization bills by line of credit, and every campaign in it needs the --invoice-* flags.

Accepts pagination flags.

adapty asa apps list

List the apps promoted in Apple Ads.

adapty asa apps list

Each row carries two identifiers, and they are not interchangeable:

FieldUsed as
internal_idThe UUID that --app takes as a list filter
adam_idApple’s numeric App Store ID, taken by --adam-id on campaigns create and product-pages sync

Accepts pagination flags.

Campaigns

adapty asa campaigns list

List campaigns. Returns metadata only — read performance numbers with asa metrics.

adapty asa campaigns list --app <app-id> --status PAUSED

Accepts pagination flags and the --campaign-group, --app, --search, and --status list filters.

adapty asa campaigns get

Get details for a specific campaign.

adapty asa campaigns get <campaign-id>
ArgumentDescription
campaign-idCampaign ID (UUID)

adapty asa campaigns create

Create a campaign.

adapty asa campaigns create --org <campaign-group-id> --name "Winter push" --adam-id 123456 --country US --daily-budget 50
FlagRequiredDescription
--orgYesCampaign group ID (UUID). See orgs list
--nameYesCampaign name
--adam-idYesApp Store app ID (adam_id)
--countryYesCountry or region code. Repeat for several: --country US --country CA
--daily-budgetYesDaily budget as a plain amount, for example 50 or 12.50
--budgetNoLifetime budget
--target-cpaNoTarget cost per acquisition. Must be lower than --daily-budget
--currencyNoCurrency code for the amounts in this call. Default: USD
--bidding-strategyNoMANUAL_CPT or MAX_CONVERSIONS. Apple defaults to MANUAL_CPT
--ad-channel-typeNoSEARCH or DISPLAY. Default: SEARCH
--billing-eventNoTAPS or IMPRESSIONS. Default: TAPS
--supply-sourceNoSupply source, repeatable. Default: APPSTORE_SEARCH_RESULTS
--statusNoInitial status: ENABLED or PAUSED
--invoice-advertiserLine of creditInvoicing Options: advertiser name
--invoice-order-numberLine of creditInvoicing Options: order number
--invoice-contact-nameLine of creditInvoicing Options: buyer contact name
--invoice-contact-emailLine of creditInvoicing Options: buyer contact email
--invoice-billing-emailLine of creditInvoicing Options: billing contact email

An organization whose payment_model is LOC bills by line of credit, and Apple requires Invoicing Options on each of its campaigns. Pass all five --invoice-* flags in one call — a partial set is rejected before the request is sent. See Set Invoicing Options for a line of credit.

The response carries serving_status and serving_state_reasons. A campaign can be created and still not serve: a MAX_CONVERSIONS campaign waits for an automated ad group, and a line-of-credit campaign waits for its Invoicing Options. In both cases the command prints the reason and the command that resolves it.

adapty asa campaigns update

Update an existing campaign.

adapty asa campaigns update <campaign-id> --daily-budget 80 --status PAUSED
ArgumentDescription
campaign-idCampaign ID (UUID)
FlagDescription
--nameNew campaign name
--statusENABLED or PAUSED
--countryReplaces the country list. Repeat for several
--daily-budgetNew daily budget
--budgetNew lifetime budget
--target-cpaNew target cost per acquisition
--bidding-strategyMANUAL_CPT or MAX_CONVERSIONS
--currencyCurrency code for the amounts in this call. Default: USD
--invoice-advertiserInvoicing Options: advertiser name
--invoice-order-numberInvoicing Options: order number
--invoice-contact-nameInvoicing Options: buyer contact name
--invoice-contact-emailInvoicing Options: buyer contact email
--invoice-billing-emailInvoicing Options: billing contact email

At least one flag is required.

The five --invoice-* flags go together and replace the stored Invoicing Options as a set, so pass all five even to change one of them. A partial set is rejected before the request is sent.

adapty asa campaigns bulk-create

Create a whole campaign structure — campaigns with nested ad groups, keywords, negative keywords, and ads — in one operation.

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

Convert a native Apple Ads bulk template instead of writing the JSON:

adapty asa campaigns bulk-create --from-file Campaign_And_Adgroup_Template.xlsx --org-id 1234567
FlagDefaultDescription
--fileJSON file with the campaign structure, or - to read from standard input
--from-fileApple Ads bulk template to convert on the server: Campaign_And_Adgroup_Template.xlsx or a keywords .csv
--org-idApple’s numeric organization ID (org_id). See orgs list. Required with --from-file
--previewWith --from-file: print the converted structure and stop. Nothing is created
--wait / --no-wait--waitPoll the operation until it finishes. --no-wait prints the operation ID and returns
--poll-interval5Seconds between progress polls
--timeout900Maximum seconds to wait for the operation to finish

Exactly one of --file and --from-file is required.

The structure names the campaign group at the top level and nests everything else:

{
  "campaign_group_id": 555777,
  "campaigns": [
    {
      "payload": {
        "name": "US Search",
        "adam_id": 123456,
        "countries_or_regions": ["US"],
        "daily_budget_amount": { "amount": "100", "currency": "USD" },
        "status": "ENABLED",
        "ad_channel_type": "SEARCH",
        "billing_event": "TAPS",
        "supply_sources": ["APPSTORE_SEARCH_RESULTS"]
      },
      "ad_groups": [
        {
          "payload": { "name": "Brand", "start_time": "2026-08-01T00:00:00Z", "status": "ENABLED" },
          "keywords": [{ "text": "meditation app", "match_type": "BROAD" }]
        }
      ]
    }
  ]
}

campaign_group_id takes Apple’s numeric organization ID; use campaign_group_internal_id to pass the UUID instead. A node with a payload is created. A node that names an existing entity by its id is an anchor — use one to add ad groups to an existing campaign, and add update_payload to change the entity in the same operation. Each campaign nests ad_groups, and each ad group nests keywords, negative_keywords, and ads. A campaign also takes negative_keywords directly for campaign-level ones.

The whole structure is validated before anything is created, and a rejection lists every invalid node. With --from-file, conversion issues are reported with their sheet, row, and column; conversion warnings do not stop the submission, but conversion errors abort it. Before sending, the command reports how many campaigns, ad groups, keywords, negative keywords, and ads the structure contains and asks for confirmation.

The command then polls the operation and prints progress until one of three final statuses:

StatusMeaning
successEvery object was created
partialSome objects were not created. Each failure is printed with Apple’s error
failedThe operation failed, and the command exits non-zero

If the operation has not finished after --timeout seconds, the command returns and prints the bulk-status call to run later.

adapty asa campaigns bulk-status

Show the progress of one bulk operation: the status, the object counts, and the per-object log.

adapty asa campaigns bulk-status <operation-id>
ArgumentDescription
operation-idOperation ID (UUID) printed by campaigns bulk-create

The status field is pending, running, success, partial, or failed. The counts block reports how many objects are applied, failed, and pending out of the total.

Accepts pagination flags.

Ad groups

adapty asa ad-groups list

List ad groups. Returns metadata only — read performance numbers with asa metrics.

adapty asa ad-groups list --campaign <campaign-id>

Accepts pagination flags and the --campaign-group, --app, --campaign, --search, and --status list filters.

adapty asa ad-groups get

Get details for a specific ad group.

adapty asa ad-groups get <ad-group-id>
ArgumentDescription
ad-group-idAd group ID (UUID)

adapty asa ad-groups create

Create an ad group in a campaign.

adapty asa ad-groups create --campaign <campaign-id> --name "Brand terms" --default-bid 1.20
FlagRequiredDescription
--campaignYesCampaign ID (UUID)
--nameYesAd group name
--default-bidUnless --automatedDefault bid as a plain amount, for example 1.20
--cpa-goalNoCost per acquisition goal
--pricing-modelNoCPC or CPM. Apple requires one on every ad group. Default: CPC
--start-timeNoSchedule start (YYYY-MM-DD). Defaults to today
--end-timeNoSchedule end (YYYY-MM-DD)
--automated-keywords / --no-automated-keywordsNoLet Apple add keywords automatically
--automatedNoCreate the automated ad group that a MAX_CONVERSIONS campaign needs
--currencyNoCurrency code for the amounts in this call. Default: USD
--statusNoInitial status: ENABLED or PAUSED

--automated opts the ad group into automated keywords, so it cannot be combined with --automated-keywords. Apple schedules an automated ad group itself and keeps it enabled, so --start-time and --status PAUSED are rejected — pause the campaign instead. See Create a Max Conversions campaign.

adapty asa ad-groups update

Update an existing ad group.

adapty asa ad-groups update <ad-group-id> --default-bid 1.50 --status PAUSED
ArgumentDescription
ad-group-idAd group ID (UUID)
FlagDescription
--nameNew ad group name
--statusENABLED or PAUSED
--default-bidNew default bid
--cpa-goalNew cost per acquisition goal
--start-timeSchedule start (YYYY-MM-DD)
--end-timeSchedule end (YYYY-MM-DD)
--automated-keywords / --no-automated-keywordsLet Apple add keywords automatically
--currencyCurrency code for the amounts in this call. Default: USD

At least one flag is required. The parent campaign is resolved on the server and is never passed.

Keywords

Keyword commands are applied as a batch of at most 100 items per call. See Manage keywords for the dashboard equivalent.

adapty asa keywords list

List targeting keywords. Returns metadata only — read performance numbers with asa metrics.

adapty asa keywords list --ad-group <ad-group-id> --status ACTIVE

Accepts pagination flags and the --campaign-group, --app, --campaign, --ad-group, --search, and --status list filters. Filter by --ad-group — without a filter, this is the widest read in the topic.

adapty asa keywords add

Add targeting keywords to an ad group.

adapty asa keywords add --ad-group <ad-group-id> --text "running shoes" --text "trail shoes" --bid 1.20

Read the keywords from a file instead, one per line:

adapty asa keywords add --ad-group <ad-group-id> --from-file keywords.txt
FlagRequiredDescription
--ad-groupYesAd group ID (UUID). The campaign is resolved from it
--textYes, unless --from-file is usedKeyword text. Repeat for several
--from-fileNoFile with one keyword per line. Combined with any --text values
--bidNoBid per keyword as a plain amount
--match-typeNoBROAD or EXACT. Default: BROAD
--currencyNoCurrency code for the amounts in this call. Default: USD
--statusNoACTIVE or PAUSED. Default: ACTIVE

One invalid ID fails the whole batch before Apple is called. Apple can still reject individual keywords, and each rejection is reported with its reason.

adapty asa keywords update

Change the bid, status, text, or match type of one or more keywords.

adapty asa keywords update <keyword-id> <keyword-id> --bid 2.00 --status PAUSED
ArgumentDescription
keyword-idKeyword ID (UUID). Pass several as extra arguments
FlagDescription
--bidNew bid
--statusACTIVE or PAUSED
--match-typeBROAD or EXACT
--textNew keyword text. Only meaningful for a single keyword
--currencyCurrency code for the amounts in this call. Default: USD

One change is applied to every ID passed.

Negative keywords

adapty asa negative-keywords list

List negative keywords. Rows with an empty ad_group_id are campaign-level.

adapty asa negative-keywords list --campaign <campaign-id>
FlagDescription
--campaign-level-onlyKeep only campaign-level rows

Accepts pagination flags and the --campaign-group, --app, --campaign, --ad-group, and --search list filters.

adapty asa negative-keywords add

Add negative keywords to an ad group or a campaign.

adapty asa negative-keywords add --ad-group <ad-group-id> --text free

Apply them to every ad group of a campaign instead:

adapty asa negative-keywords add --campaign <campaign-id> --all-ad-groups --text free
FlagRequiredDescription
--ad-groupOne of --ad-group or --campaignAd group ID (UUID). The campaign is resolved from it
--campaignOne of --ad-group or --campaignCampaign ID (UUID)
--textYesKeyword text. Repeat for several
--all-ad-groupsNoApply to every ad group of the campaign instead of the campaign itself. Requires --campaign
--match-typeNoBROAD or EXACT. Default: EXACT
--statusNoACTIVE or PAUSED. Default: ACTIVE

--ad-group and --campaign are mutually exclusive. Pass exactly one.

Search terms

adapty asa search-terms list

List the search terms that triggered your ads. Use it to find new keywords and new negative keywords.

adapty asa search-terms list --ad-group <ad-group-id> --date-from 2026-07-01 --date-to 2026-07-31
FlagDefaultDescription
--date-fromTodayStart of the reporting period (YYYY-MM-DD)
--date-toTodayEnd of the reporting period (YYYY-MM-DD)

Accepts pagination flags and the --campaign-group, --app, --campaign, --ad-group, and --search list filters.

This command shares an analytics pool with asa metrics. See Errors.

Ads

adapty asa ads list

List ads. The serving_state_reasons field explains why an ad is not running.

adapty asa ads list --ad-group <ad-group-id>

Accepts pagination flags and the --campaign-group, --campaign, --ad-group, --search, and --status list filters. This list has no --app filter, because ads belong to ad groups.

adapty asa ads get

Get details for a specific ad.

adapty asa ads get <ad-id>
ArgumentDescription
ad-idAd ID (UUID)

adapty asa ads create

Create an ad in an ad group.

adapty asa ads create --ad-group <ad-group-id> --creative-id 4321 --name "Summer ad"
FlagRequiredDescription
--ad-groupYesAd group ID (UUID). The campaign is resolved from it
--creative-idYesApple creative ID. See creatives list
--nameYesAd name
--statusNoInitial status: ENABLED or PAUSED

adapty asa ads update

Update an existing ad.

adapty asa ads update <ad-id> --status PAUSED
ArgumentDescription
ad-idAd ID (UUID)
FlagDescription
--nameNew ad name
--statusENABLED or PAUSED

At least one flag is required. The creative and the parent ad group are fixed at creation.

Creatives

adapty asa creatives list

List the creatives available for new ads.

adapty asa creatives list --app <app-id>

The creative_id returned here is the --creative-id value for ads create.

Accepts pagination flags and the --campaign-group and --app list filters.

Product pages

adapty asa product-pages list

List the custom product pages available to your apps.

adapty asa product-pages list --app <app-id>

Accepts pagination flags and the --campaign-group and --app list filters.

adapty asa product-pages sync

Refresh the custom product pages from App Store Connect.

adapty asa product-pages sync --adam-id 123456
FlagDescription
--adam-idLimit the refresh to one app. Omit to cover every app

The refresh is queued rather than performed immediately, and the command confirms with Sync queued. If the same refresh is already in flight, it reports Already running; nothing new was queued. instead.

Automations

The CLI stores the rule JSON you give it — it does not build rules. See Automations for what each rule type does, and Run automation rules for how to produce a rule file.

adapty asa automations list

List automation rules. The status field is 1 for active and 0 for stopped.

adapty asa automations list

Accepts pagination flags.

adapty asa automations get

Get a specific automation rule, including its conditions and actions.

adapty asa automations get <automation-id>
ArgumentDescription
automation-idAutomation rule ID (UUID)

adapty asa automations create

Create an automation rule from a JSON rule file.

adapty asa automations create --file rule.json
FlagDescription
--fileJSON file with the rule body, or - to read from standard input
--run-nowQueue the first run right after the rule is stored

--file is required.

adapty asa automations update

Change an automation rule: stop it, rename it, or replace parts of the rule.

adapty asa automations update <automation-id> --stop
ArgumentDescription
automation-idAutomation rule ID (UUID)
FlagDescription
--startActivate the rule
--stopStop the rule and clear its next run
--nameNew rule name
--fileJSON file with the parts to change, or - to read from standard input

--start and --stop are mutually exclusive. A file passed here must not contain internal_id.

adapty asa automations run

Run an automation rule once, outside its schedule.

adapty asa automations run <automation-id> --dry-run
ArgumentDescription
automation-idAutomation rule ID (UUID)
FlagDescription
--dry-runEvaluate the rule and log the result without changing anything in Apple Ads

The run is queued, and the command prints a run ID. Read the outcome with automations runs.

adapty asa automations runs

List past runs of an automation rule, including dry runs.

adapty asa automations runs <automation-id>
ArgumentDescription
automation-idAutomation rule ID (UUID)

Accepts pagination flags.

Metrics

adapty asa metrics

Query metrics for any level of the account over a date range.

adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31
FlagRequiredDescription
--entityYesWhat to report on: campaign, ad-group, keyword, or ad
--date-fromYesStart of the period (YYYY-MM-DD)
--date-toYesEnd of the period (YYYY-MM-DD)
--metricNoMetric name, repeatable. Omit for every metric
--group-byNoBreak the rows down by country, day, week, month, quarter, or year. Repeatable
--by-daysNoRenewal window in days for cohort metrics, repeatable. Maximum 16 per call. Omit for the dashboard defaults
--order-byNoMetric or field to sort by
--order-by-dayNoRank by a cohort metric at this renewal window. Must be one of the --by-days values
--orderNoasc or desc. Default: desc

Accepts pagination flags. This command takes no list filters — narrow the report by entity level and period, then match the rows against the IDs from a scoped list command.

Each row is one entity, aggregated on the server and sorted by --order-by. A top-N question is therefore a single call — set --order-by and --page-size N rather than paging through the results and adding them up:

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

--metric takes the metric names that Ads Manager tracks, in dashboard nomenclature — for example spend, taps, or gross_roas. See Metrics for the full list and how each one is calculated. A name that does not exist fails with the valid names listed in the error.

The length of the reporting period is capped by the coarsest --group-by value. To report on a longer period, coarsen the grouping rather than splitting the request into several calls:

Coarsest --group-byMaximum period
day, or no period grouping90 days
week180 days
month and coarser365 days

There is no ltv metric. Lifetime value is a cohort metric read at a renewal window, so --by-days is how you ask for the day-7 or day-90 value:

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 ranks the rows by one of those windows, which returns the top campaigns by day-90 ROAS in a single call.

adapty asa metrics overview

Query totals for a period, bucketed by a unit of time.

adapty asa metrics overview --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --period-unit week
FlagRequiredDescription
--entityYesWhat to report on: campaign, ad-group, keyword, or ad
--date-fromYesStart of the period (YYYY-MM-DD)
--date-toYesEnd of the period (YYYY-MM-DD)
--period-unitNoBucket size: day, week, month, quarter, or year. Default: day
--metricNoMetric name, repeatable. Omit for every metric
--by-daysNoRenewal window in days for cohort metrics, repeatable. Maximum 16 per call

This command returns the totals for the whole entity level plus a per-period series, so it answers “how much did I spend or earn overall” in one call. It has no ordering flags and no pagination.

On this command, --metric accepts cohort roots only — revenue, roas, and arpu — not their gross_, proceeds_, or net_ variants.

The length of the reporting period is capped by --period-unit:

--period-unitMaximum period
day90 days
week180 days
month and coarser365 days

Competitors

adapty asa competitors summary

Summarize the Apple Ads keywords that a set of App Store apps bid on. This returns the same competitor data as Market Intelligence in the dashboard.

adapty asa competitors summary --app-ids 1668337467,6503873027
FlagRequiredDescription
--app-idsYesApple App Store IDs (adam_id), comma-separated. Between 1 and 5 values

The reporting period and the country set are fixed on the server — the last full month, across every country. This command has no period, country, or pagination flags.

The command prints three blocks: the totals for the analysis, the top apps by performance, and the most contested terms. Add --json for the full result, which also breaks each app’s terms down by country.

The first call for a set of apps can take tens of seconds while the data is prepared. Later calls for the same apps return faster.

Errors

StatusCodeMeaning
402ads_manager_subscription_requiredThe company has no active Ads Manager subscription
404The entity does not exist, or it belongs to another company
409cli_idempotency_in_progressA write with the same idempotency key is still running
422cli_idempotency_key_reuseThe same idempotency key was used with a different request body
429cli_analytics_busyThe analytics pool is busy. The wait is in the Retry-After header
429cli_cooldown_activeToo many rejected requests put the token into a cool-down

Metrics and the search terms list share one analytics budget per company: 5 calls per minute, and at most 2 in any 10 seconds. A burst of 20 rejected requests within 5 minutes starts an escalating cool-down of 5 minutes, then 30 minutes, then 3 hours. Retrying during the pause does not extend it, but the fix is to correct the failing request rather than repeat it.

The CLI handles short waits for you. On a 429 that is not a cool-down, if Retry-After is 60 seconds or less, the command waits for that long and retries once, reporting the wait on standard error.