| name | ascelerate |
| description | Use when working with App Store Connect tasks — app submissions, localizations, screenshots, builds, provisioning, in-app purchases, subscriptions, or release workflows. Triggers on App Store, App Store Connect, asc, ascelerate, app review, provisioning profiles, screenshots, localizations, IAP, subscriptions. |
ascelerate
A command-line tool for the App Store Connect API. Use ascelerate for all App Store Connect operations instead of the web interface.
Quick Reference
App aliases
Use aliases instead of full bundle IDs:
ascelerate alias add myapp
ascelerate apps info myapp
Any argument without a dot is treated as an alias. Real bundle IDs work unchanged.
Version management
ascelerate apps create-version <app> <version>
ascelerate apps copyright <app> --set "2026 Your Name"
ascelerate apps build attach-latest <app>
ascelerate apps build attach <app>
ascelerate apps build detach <app>
--version targets a specific version. Without it, commands prefer the latest editable version (Prepare for Submission or Waiting for Review).
Universal-purchase apps (one app record, several platforms) can hold the same version per platform. Version-scoped commands (localizations, media, build attach, review, builds list/await-processing) accept --platform ios|macos|tvos|visionos to disambiguate; without it they prompt when ambiguous. apps create-version and apps review submit default to iOS — pass --platform macos for the Mac version/submission.
Localizations
Two layers: version-level (description, what's new, keywords) and app-level (name, subtitle, privacy URL).
ascelerate apps localizations export <app>
ascelerate apps localizations import <app> --file localizations.json
ascelerate apps app-info export <app>
ascelerate apps app-info import <app> --file app-infos.json
Version localization JSON format
{
"en-US": {
"description": "App description.",
"whatsNew": "- Bug fixes",
"keywords": "keyword1,keyword2",
"promotionalText": "Promo text",
"marketingURL": "https://example.com",
"supportURL": "https://example.com/support"
}
}
App info localization JSON format
{
"en-US": {
"name": "My App",
"subtitle": "Best app ever",
"privacyPolicyURL": "https://example.com/privacy",
"privacyChoicesURL": "https://example.com/choices"
}
}
Only fields present in the JSON get updated — omitted fields are left unchanged. Import commands create missing locales automatically with confirmation.
Screenshots & App Previews
ascelerate apps media download <app>
ascelerate apps media upload <app> media/
ascelerate apps media upload <app> screenshots.zip
ascelerate apps media upload <app>
ascelerate apps media upload <app> media/ --replace
ascelerate apps media verify <app>
ascelerate apps media verify <app> media/
ascelerate apps media prune <app> media/
Folder structure
media/
├── en-US/
│ ├── APP_IPHONE_67/
│ │ ├── 01_home.png
│ │ └── 02_settings.png
│ └── APP_IPAD_PRO_3GEN_129/
│ └── 01_home.png
└── de-DE/
└── APP_IPHONE_67/
└── 01_home.png
Required display types: APP_IPHONE_67 (iPhone) and APP_IPAD_PRO_3GEN_129 (iPad). Files sorted alphabetically = upload order. Images become screenshots, videos become previews.
Review submission
ascelerate apps review preflight <app>
ascelerate apps review submit <app>
ascelerate apps review status <app>
ascelerate apps review resolve-issues <app>
ascelerate apps review cancel-submission <app>
ascelerate apps review info <app>
ascelerate apps review info <app> [--contact-email X] [--demo-account-name X] [--demo-account-password X] [--demo-account-required true|false] [--notes X]
ascelerate apps review attachment list <app> [--version X]
ascelerate apps review attachment upload <app> [--version X] <file>
ascelerate apps review attachment delete <attachment-id>
preflight checks build attachment, localizations, app info, screenshots across all locales, plus IAP/subscription state and pricing (warns when an IAP has no price schedule or a sub has no prices). Exits non-zero on failures.
When submitting, the tool detects IAPs and subscriptions and offers to submit them alongside the app version.
In-app purchases
ascelerate iap list <app>
ascelerate iap info <app> <product-id>
ascelerate iap promoted list <app>
ascelerate iap promoted add <app> <product-id> [--visible-for-all true|false] [--enabled true|false]
ascelerate iap promoted remove <app> <product-id>
ascelerate iap promoted reorder <app> <product-id,product-id,...>
ascelerate iap promoted toggle <app> <product-id> --enabled true|false
ascelerate iap create <app> --name "Name" --product-id <id> --type CONSUMABLE
ascelerate iap update <app> <product-id> --name "New Name"
ascelerate iap delete <app> <product-id>
ascelerate iap submit <app> <product-id>
ascelerate iap localizations view <app> <product-id>
ascelerate iap localizations export <app> <product-id>
ascelerate iap localizations import <app> <product-id> --file iap-de.json
ascelerate iap pricing show <app> <product-id>
ascelerate iap pricing tiers <app> <product-id> --territory USA
ascelerate iap pricing set <app> <product-id> --price 4.99 [--base-territory USA] [--remove-all-overrides]
ascelerate iap pricing override <app> <product-id> --price 5.99 --territory FRA
ascelerate iap pricing remove <app> <product-id> --territory FRA
ascelerate iap availability <app> <product-id> [--add CHN,RUS] [--remove ITA] [--available-in-new-territories true]
ascelerate iap offer-code list <app> <product-id>
ascelerate iap offer-code info <app> <product-id> <offer-code-id>
ascelerate iap offer-code create <app> <product-id> --name X --eligibility NON_SPENDER,ACTIVE_SPENDER --price 0.99 [--territory USA] [--equalize-all-territories]
ascelerate iap offer-code toggle <app> <product-id> <offer-code-id> --active true
ascelerate iap offer-code gen-codes <app> <product-id> <offer-code-id> --count 100 --expires 2026-12-31
ascelerate iap offer-code add-custom-codes <app> <product-id> <offer-code-id> --code PROMO2026 --count 1000 --expires 2026-12-31
ascelerate iap offer-code view-codes <one-time-use-batch-id> [--output codes.txt]
ascelerate iap images list/upload/delete <app> <product-id> [<file>|<image-id>]
ascelerate iap review-screenshot view/upload/delete <app> <product-id> [<file>]
IAP types: CONSUMABLE, NON_CONSUMABLE, NON_RENEWING_SUBSCRIPTION. Offer code eligibilities: NON_SPENDER, ACTIVE_SPENDER, CHURNED_SPENDER.
Pricing notes:
set preserves per-territory overrides by default; interactive menu offers to drop them, or --remove-all-overrides for non-interactive wipe.
override and remove only operate on non-base territories.
- One-time-use offer codes generate asynchronously —
gen-codes returns a batch ID; use view-codes <batch-id> to fetch values once ready.
Subscriptions
ascelerate sub list <app>
ascelerate sub groups <app>
ascelerate sub info <app> <product-id>
ascelerate sub create <app> --name "Monthly" --product-id <id> --period ONE_MONTH --group-id <gid>
ascelerate sub update <app> <product-id> --name "New Name"
ascelerate sub delete <app> <product-id>
ascelerate sub submit <app> <product-id>
ascelerate sub submit-group <app>
ascelerate sub localizations export <app> <product-id>
ascelerate sub localizations import <app> <product-id> --file sub-de.json
ascelerate sub create-group <app> --name "Premium"
ascelerate sub update-group <app> --name "Premium Plus"
ascelerate sub delete-group <app>
ascelerate sub group-localizations export <app>
ascelerate sub group-localizations import <app> --file group-de.json
ascelerate sub pricing show <app> <product-id>
ascelerate sub pricing tiers <app> <product-id> --territory USA
ascelerate sub pricing set <app> <product-id> --price 4.99 [--territory USA] [--equalize-all-territories]
[--preserve-current | --no-preserve-current]
[--confirm-decrease]
ascelerate sub availability <app> <product-id> [--add CHN,RUS] [--remove ITA] [--available-in-new-territories true]
ascelerate sub intro-offer list <app> <product-id>
ascelerate sub intro-offer create <app> <product-id> --mode FREE_TRIAL --duration ONE_WEEK --periods 1
ascelerate sub intro-offer create <app> <product-id> --mode PAY_AS_YOU_GO --duration ONE_MONTH --periods 3 --territory USA --price 0.99
ascelerate sub intro-offer update <app> <product-id> <offer-id> --end-date 2026-12-31
ascelerate sub intro-offer delete <app> <product-id> <offer-id>
ascelerate sub promo-offer list/info/delete <app> <product-id> [<offer-id>]
ascelerate sub promo-offer create <app> <product-id> --name X --code LOYALTY50 --mode PAY_AS_YOU_GO --duration ONE_MONTH --periods 3 --price 4.99 --territory USA --equalize-all-territories
ascelerate sub promo-offer update <app> <product-id> <offer-id> --price 5.99 --equalize-all-territories
ascelerate sub offer-code list/info <app> <product-id> [<offer-code-id>]
ascelerate sub offer-code create <app> <product-id> --name X --eligibility NEW --offer-eligibility STACK_WITH_INTRO_OFFERS --mode FREE_TRIAL --duration ONE_MONTH --periods 1 --price 0 --territory USA --equalize-all-territories
ascelerate sub offer-code toggle <app> <product-id> <offer-code-id> --active true
ascelerate sub offer-code gen-codes <app> <product-id> <offer-code-id> --count 500 --expires 2026-12-31
ascelerate sub offer-code add-custom-codes <app> <product-id> <offer-code-id> --code SUBPROMO --count 1000 --expires 2026-12-31
ascelerate sub offer-code view-codes <one-time-use-batch-id> [--output codes.txt]
ascelerate sub images list/upload/delete <app> <product-id> [<file>|<image-id>]
ascelerate sub review-screenshot view/upload/delete <app> <product-id> [<file>]
Subscription pricing safety:
- Price increase in any territory requires
--preserve-current (grandfather existing subs at old price) OR --no-preserve-current (push new price after Apple's notification period). Errors if neither set.
- Price decrease prompts interactively; under
--yes, requires --confirm-decrease to acknowledge revenue impact.
--equalize-all-territories aggregates the analysis: if any territory in the fan-out is an increase, the preserve flag is required for all.
Offer code eligibilities for subs: NEW, EXISTING, EXPIRED. Offer eligibility: STACK_WITH_INTRO_OFFERS or REPLACE_INTRO_OFFERS. Modes: FREE_TRIAL, PAY_AS_YOU_GO, PAY_UP_FRONT.
NOT YET IMPLEMENTED: sub win-back-offer is blocked on asc-swift codegen (the inline price create type is missing required relationships). Custom product page search-keyword linkages are blocked by the same kind of codegen gap (the AppKeyword entity exposes no keyword text). iap hosted-content is intentionally skipped.
Customer reviews
ascelerate reviews list <app> [--rating 1-5] [--territory USA] [--sort recent|oldest|critical|best] [--unanswered] [--limit 50]
ascelerate reviews info <review-id>
ascelerate reviews respond <review-id> --body "..."
ascelerate reviews delete-response <review-id>
Reviews are read-only; only the developer response is writable. Review IDs come from reviews list.
The App Store Connect API does not expose aggregate rating counts or the star-rating average/histogram — only individual reviews (above). For download/unit numbers and revenue, use reports (below).
Reports (downloads, proceeds, analytics)
ascelerate reports sales [--frequency DAILY|WEEKLY|MONTHLY|YEARLY] [--date X] [--type SALES] [--sub-type SUMMARY] [--bundle-id <app>] [--vendor-number X] [--output report.tsv] [--raw]
ascelerate reports finance --date YYYY-MM --region US [--type FINANCIAL|FINANCE_DETAIL] [--vendor-number X] [--output X] [--raw]
ascelerate reports analytics <app> [--category APP_STORE_ENGAGEMENT|APP_USAGE|COMMERCE|FRAMEWORK_USAGE|PERFORMANCE] [--granularity DAILY|WEEKLY|MONTHLY] [--report-name X] [--processing-date YYYY-MM-DD] [--ongoing] [--output dir/] [-y]
- Vendor number is required for
sales/finance (App Store Connect → Payments and Financial Reports). Save it once with ascelerate configure, or pass --vendor-number.
sales/finance default to a parsed summary; add --raw to print the TSV or --output PATH to save it. --date defaults to the most recent completed period for sales; for finance it's a fiscal period YYYY-MM (not a calendar month) and is required along with --region.
analytics reuses an existing report request or prompts to create one (a one-time snapshot by default; --ongoing for recurring). A freshly created snapshot isn't ready immediately — re-run the command after a few minutes to download the segments.
In-app events
ascelerate events list <app> [--state PUBLISHED]
ascelerate events info <app> <ref-or-id>
ascelerate events create <app> --reference-name X [--badge SPECIAL_EVENT] [--purpose ATTRACT_NEW_USERS] [--priority HIGH] [--deep-link URL] [--primary-locale en-US] [--territories USA,GBR --publish-start 2026-07-01 --event-start 2026-07-05 --event-end 2026-07-12]
ascelerate events update <app> <ref-or-id> [--badge NONE]
ascelerate events delete <app> <ref-or-id>
ascelerate events localizations view <app> <ref-or-id>
ascelerate events localizations export <app> <ref-or-id>
ascelerate events localizations import <app> <ref-or-id> --file event-locales.json
ascelerate events media list <app> <ref-or-id>
ascelerate events media upload <app> <ref-or-id> --locale en-US --asset-type EVENT_CARD|EVENT_DETAILS_PAGE <file> [--preview-frame 00:00:03]
ascelerate events media delete <app> <ref-or-id> <media-id>
Badges: LIVE_EVENT, PREMIERE, CHALLENGE, COMPETITION, NEW_SEASON, MAJOR_UPDATE, SPECIAL_EVENT. Purposes: APPROPRIATE_FOR_ALL_USERS, ATTRACT_NEW_USERS, KEEP_ACTIVE_USERS_INFORMED, BRING_BACK_LAPSED_USERS. Schedule dates: ISO8601 or yyyy-MM-dd. Event localization locales must match the app's locales (e.g. tr, not tr-TR).
Event localization JSON format
{ "en-US": { "name": "Summer Sale", "shortDescription": "...", "longDescription": "..." } }
Custom product pages
ascelerate product-pages list <app>
ascelerate product-pages info <app> <name-or-id>
ascelerate product-pages create <app> --name X --locale en-US [--promotional-text "..."]
ascelerate product-pages update <app> <name-or-id> [--name X] [--visible true|false]
ascelerate product-pages delete <app> <name-or-id>
ascelerate product-pages localizations view <app> <name-or-id>
ascelerate product-pages localizations export <app> <name-or-id>
ascelerate product-pages localizations import <app> <name-or-id> --file page-locales.json
ascelerate product-pages media list <app> <name-or-id>
ascelerate product-pages media upload <app> <name-or-id> --locale en-US --display-type APP_IPHONE_67 shot.png
ascelerate product-pages media upload <app> <name-or-id> --locale en-US --preview-type APP_IPHONE_67 clip.mp4 [--preview-frame 00:00:03]
ascelerate product-pages media delete <app> <name-or-id> <media-id>
Pages are referenced by name or ID. create issues a compound POST (page + version + localization linked via ${local-id} inline references).
Custom product page localization JSON format
{ "en-US": { "promotionalText": "Limited-time offer" } }
Screenshots (Simulator Capture)
Capture App Store screenshots from simulators using UI tests. Replaces fastlane snapshot.
ascelerate screenshot init
ascelerate screenshot create-helper
ascelerate screenshot run
ascelerate screenshot run -l en-US,tr-TR
ascelerate screenshot frame
ascelerate screenshot doctor
Config (ascelerate/screenshot.yml)
project: MyApp.xcodeproj
scheme: AppUITests
devices:
- simulator: iPhone 17 Pro Max
- simulator: iPad Pro 13-inch (M5)
languages: [en-US, de-DE]
outputDirectory: ./screenshots
clearPreviousScreenshots: true
localizeSimulator: true
overrideStatusBar: true
Supports dark mode capture, animation disabling, automatic retries (erases simulator, re-localizes, reboots), custom test plans, Xcode build configurations, and arbitrary xcodebuild arguments.
Device framing
Frame screenshots with Apple device bezels (from Apple Design Resources). Per-device: set frameDevice: true and deviceBezel path to the bezel PNG. Framing runs automatically after capture, or standalone via screenshot frame. Output goes to framedOutputDirectory (defaults to {outputDirectory}/framed). Use screenshot doctor to validate config, simulators, bezels, and environment.
UITest usage
override func setUp() {
setupScreenshots(app)
app.launch()
}
func testScreenshots() {
screenshot("01-home")
app.buttons["Settings"].tap()
screenshot("02-settings")
}
Builds once, runs tests concurrently across devices per language. Output: screenshots/{language}/{device}-{name}.png. Errors skip and continue with summary table.
Builds
ascelerate builds archive
ascelerate builds upload MyApp.ipa
ascelerate builds await-processing <app>
ascelerate builds list --bundle-id <app>
Provisioning
All provisioning commands support interactive mode (run without arguments for guided prompts):
ascelerate devices list
ascelerate devices register
ascelerate certs create --type DISTRIBUTION
ascelerate certs revoke
ascelerate bundle-ids register --name "My App" --identifier com.example.MyApp --platform IOS
ascelerate bundle-ids enable-capability com.example.MyApp --type PUSH_NOTIFICATIONS
ascelerate profiles create --name "My Profile" --type IOS_APP_STORE --bundle-id com.example.MyApp --certificates all
ascelerate profiles reissue --all-invalid
Note: provisioning commands (devices, certs, bundle-ids, profiles) do NOT support aliases.
App configuration
ascelerate apps app-info view <app>
ascelerate apps app-info update <app> --primary-category UTILITIES
ascelerate apps app-info age-rating <app>
ascelerate apps app-info age-rating export <app>
ascelerate apps app-info age-rating import <app> --file age-rating.json
ascelerate apps availability <app> --add CHN,RUS
ascelerate apps encryption <app> --create --description "Uses HTTPS"
ascelerate apps eula <app> --file eula.txt
ascelerate apps phased-release <app> --enable
ascelerate apps subscription-grace-period <app>
ascelerate apps subscription-grace-period <app> --opt-in true --duration SIXTEEN_DAYS --renewal-type ALL_RENEWALS
ascelerate apps subscription-grace-period <app> --sandbox-opt-in true
Grace period durations: THREE_DAYS, SIXTEEN_DAYS, TWENTY_EIGHT_DAYS. Renewal types: ALL_RENEWALS, PAID_TO_PAID_ONLY.
Workflow files
Automate multi-step releases with a plain text file:
# release.workflow
apps create-version com.example.MyApp 2.1.0
builds archive --scheme MyApp
builds upload --latest --bundle-id com.example.MyApp
builds await-processing com.example.MyApp
apps localizations import com.example.MyApp --file localizations.json
apps build attach-latest com.example.MyApp
apps review preflight com.example.MyApp
apps review submit com.example.MyApp
ascelerate run-workflow release.workflow
ascelerate run-workflow release.workflow --yes
Commands are one per line, without the ascelerate prefix. Lines starting with # are comments. builds upload automatically passes the build version to subsequent commands.
Adding a new language to an app
When the user asks to add a new language/locale to an app, translate all of these:
- App info localizations (name, subtitle, privacy URLs) — always
- Version localizations (description, what's new, keywords, promo text) — always
- In-app purchases — ask the user: translate all IAPs, or specific ones?
- Subscription groups — ask the user: translate all groups, or specific ones?
- Subscriptions — ask the user: translate all subscriptions, or specific ones?
Workflow
- Export existing localizations to see the source text:
ascelerate apps app-info export <app>
ascelerate apps localizations export <app>
ascelerate iap localizations view <app> <product-id>
ascelerate sub group-localizations export <app>
ascelerate sub localizations export <app> <product-id>
- Ask the user which IAPs, subscription groups, and subscriptions to translate (or all).
- Translate the source text into the new locale.
- Import the translations (use
-y to skip confirmation prompts):
ascelerate apps app-info import <app> --file app-infos.json -y
ascelerate apps localizations import <app> --file localizations.json -y
ascelerate iap localizations import <app> <product-id> --file iap.json -y
ascelerate sub group-localizations import <app> --file group.json -y
ascelerate sub localizations import <app> <product-id> --file sub.json -y
Tips
- Add
--yes / -y to skip confirmation prompts (for scripting/CI)
- Use
ascelerate rate-limit to check API quota (3600 requests/hour)
- Run
ascelerate install-completions after updates for tab completion
- Only editable versions (Prepare for Submission / Waiting for Review) accept updates
promotionalText can be updated on any version state
- Export JSON → edit → import is the fastest way to update localizations across locales