Going Live
Metadata & Submitting with asc
You have a processed build in App Store Connect (see Build & TestFlight with asc). The manual checklist walks the App Store Connect web UI to fill out the listing and hit Submit. This page is the automation layer over that same final stretch: set the listing text, localizations, screenshots, and pricing; attach the build; run readiness checks; and submit for review — every step a deterministic asc command you can script, diff, and re-run.
Everything here uses the same authenticated asc from The asc CLI. All commands were verified against asc v2.2.0; document only what --help confirms.
asc submits the build — it does not make the app compliant
asc automates the mechanics of submission. It does not check that you deployed the delete-account Edge Function, that your shipped paywall has a Restore Purchases button, that NSCameraUsageDescription is present, or that you supplied working demo credentials. Those review traps are detailed in Shipping to the App Store — clear them before you add --submit, or the reviewer will reject a perfectly uploaded build.
Resolve your app id once
Most commands below take --app. It accepts the numeric App Store Connect app id, the bundle id, or the exact app name. Set it once and let every command inherit it:
export ASC_APP_ID="123456789" # or app.shipthat.demo → your real bundle id
With ASC_APP_ID set you can drop --app from the commands. The examples keep it explicit for clarity.
Metadata: the listing text
asc metadata manages localizable listing fields with a deterministic, file-based workflow — the same model as Fastlane's deliver, but git-friendly. The canonical fields are the version-localization copy (description, keywords, marketingUrl, promotionalText, supportUrl, whatsNew) and the app-info copy (name, subtitle, privacy URLs).
The flow is pull → edit files → push (a --dry-run preview is built in). Start by pulling whatever is already live into canonical JSON files:
asc metadata pull --app "$ASC_APP_ID" --version "1.0.0" --dir "./metadata"
That writes ./metadata/version/1.0.0/<locale>.json files. Edit them in your editor (or commit them so the listing copy lives in your repo). Preview the diff before touching App Store Connect:
asc metadata push --app "$ASC_APP_ID" --version "1.0.0" --dir "./metadata" --dry-run
When the plan looks right, push for real:
asc metadata push --app "$ASC_APP_ID" --version "1.0.0" --dir "./metadata"
Starting from nothing instead of an existing listing? Scaffold blank templates with asc metadata init, fill them in, then validate offline before you push:
asc metadata init --dir "./metadata" --version "1.0.0" --locale "en-US"
asc metadata validate --dir "./metadata"
push vs. apply
asc metadata push and asc metadata apply both write your canonical files to App Store Connect. Omitted fields are treated as no-ops — they are never interpreted as deletions. To actually remove remote locales that are missing locally, you must opt in with --allow-deletes --confirm. Without that flag, a missing locale falls back to your default.json rather than being deleted.
Localizations: adding locales
asc metadata edits the copy for locales that already exist. To add a locale to a version, or to update a single field directly without the file workflow, use asc localizations. Note these commands key off the App Store version id, not the version string — list them to find the id:
# Discover existing locales (and their localization ids) for a version
asc localizations list --version "VERSION_ID"
# Add a new locale to the version
asc localizations create --version "VERSION_ID" --locale "ja"
# Update a single field directly, no files involved
asc localizations update --version "VERSION_ID" --locale "ja" --description "..."
For bulk locale work you can round-trip .strings files instead:
asc localizations download --version "VERSION_ID" --path "./localizations"
asc localizations upload --version "VERSION_ID" --path "./localizations" --dry-run
asc localizations upload --version "VERSION_ID" --path "./localizations"
Screenshots
Screenshots upload per version-localization (the locale's resource id, not the locale code). First get the version-localization id from the list above, then upload a folder of images for a device type. For most iOS submissions one iPhone set (IPHONE_65) and one iPad set (IPAD_PRO_3GEN_129) are enough:
# Find the version-localization id (data[].id in the JSON output)
asc localizations list --version "VERSION_ID" --output json --locale "en-US"
# Validate the assets locally before spending an upload
asc screenshots validate --path "./screenshots/iphone" --device-type "IPHONE_65"
# Upload one localization's iPhone set
asc screenshots upload \
--version-localization "VERSION_LOCALIZATION_ID" \
--path "./screenshots/iphone" \
--device-type "IPHONE_65"
You can also fan a single run out across every locale by passing --app with --version and a --path whose immediate children are locale directories. Run asc screenshots sizes to see accepted display sizes, and add --dry-run to any upload to preview it.
Pricing & availability
For a free app this is usually a no-op (the manual checklist sets price tier 0 in the UI). To inspect or change pricing from the CLI, asc pricing uses current / schedule / availability subcommands — prefer the view/current verbs to read and create/edit to change:
# What is the app priced at today?
asc pricing current --app "$ASC_APP_ID" --output table
# View the active price schedule
asc pricing schedule view --app "$ASC_APP_ID"
# Read where the app is available
asc pricing availability view --app "$ASC_APP_ID"
# Make it available everywhere (and in new territories Apple adds later)
asc pricing availability edit --app "$ASC_APP_ID" --all-territories \
--available true --available-in-new-territories true
Subscription pricing lives elsewhere
asc pricing covers the app's price and territory availability. ShipThatApp's revenue comes from subscriptions — the products in Config.swift (productIds + subGroupId) — which are managed under asc subscriptions and must be in Ready to Submit and attached to the version you ship. See the subscription notes in Shipping to the App Store.
Prepare a version without submitting
Before you commit to a submission, asc release stage runs a deterministic pre-submit pipeline: ensure/create the version, apply (or copy) metadata, attach the build, and run readiness checks — then stops before creating a review submission. It is the safe way to get a version fully staged and reviewed by a human (or CI) before the irreversible step.
Preview the plan first with --dry-run, then run it with --confirm:
# Dry run: see exactly what staging will do
asc release stage --app "$ASC_APP_ID" --version "1.0.0" --build "BUILD_ID" \
--metadata-dir "./metadata/version/1.0.0" --dry-run
# Stage for real (mutations require --confirm)
asc release stage --app "$ASC_APP_ID" --version "1.0.0" --build "BUILD_ID" \
--metadata-dir "./metadata/version/1.0.0" --confirm
If you are shipping a follow-up release, --copy-metadata-from "0.9.0" copies the previous version's localized copy forward instead of supplying a metadata directory. Add --strict-validate to treat readiness warnings as blocking.
Validate, then submit
asc validate is the canonical readiness report. It checks metadata length limits, required fields and localizations, review-details completeness, primary category, build attached and processed, encryption declaration, content-rights declaration, pricing/availability, screenshots, subscription readiness, and age rating. Its output includes an ordered remediation plan — the first item is the next thing to fix:
asc validate --app "$ASC_APP_ID" --version "1.0.0" --output table
Run it with --strict in CI to make warnings fail the build. When validate is clean, ship with the canonical publish command. This attaches the IPA, ensures the version, optionally applies a metadata directory, and submits for review — --submit requires --confirm:
asc publish appstore --app "$ASC_APP_ID" --ipa app.ipa --version "1.0.0" \
--metadata-dir "./metadata" --submit --confirm
Preview the whole plan without uploading or submitting by adding --dry-run:
asc publish appstore --app "$ASC_APP_ID" --ipa app.ipa --version "1.0.0" \
--submit --dry-run
--submit is the irreversible step
Everything up to asc release stage is reversible. asc publish appstore --submit --confirm creates a real App Store review submission. Run asc validate until it is clean, and confirm the review traps are handled, before you add --submit.
Monitor the review
Once submitted, watch the pipeline from the terminal. asc status aggregates build, TestFlight, App Store, submission, and review signals into one payload — add --watch to poll until something changes:
asc status --app "$ASC_APP_ID" --output table
asc status --app "$ASC_APP_ID" --watch --poll-interval 30s
For lower-level submission lifecycle control, asc submit status reports a single submission and asc submit cancel withdraws an active one (it is destructive, so it requires --confirm):
asc submit status --version-id "VERSION_ID"
asc submit cancel --version-id "VERSION_ID" --app "$ASC_APP_ID" --confirm
Automate it in CI
Every command on this page is non-interactive and emits JSON by default, so the whole submit flow drops straight into a pipeline. Authenticate with the environment-variable fallback documented in The asc CLI — ASC_KEY_ID, ASC_ISSUER_ID, and ASC_PRIVATE_KEY_PATH (or ASC_PRIVATE_KEY_B64) — instead of the keychain, and set ASC_APP_ID so commands inherit the app:
export ASC_KEY_ID="..." ASC_ISSUER_ID="..." ASC_PRIVATE_KEY_B64="..."
export ASC_APP_ID="123456789"
asc metadata push --version "1.0.0" --dir "./metadata"
asc validate --version "1.0.0" --strict
asc publish appstore --ipa app.ipa --version "1.0.0" --submit --confirm
asc status --watch --poll-interval 30s
Gating the pipeline on asc validate --strict (non-zero exit on warnings) means a metadata gap or missing screenshot fails the job before it reaches the irreversible --submit. It still cannot vouch for the human-judgment review traps — keep those in your release checklist.
Related
- The asc CLI — install, authenticate (keychain or env vars), and the shared
ascidioms. - Build & TestFlight with asc — produce the IPA and get a processed build before you submit.
- Shipping to the App Store — the manual/GUI checklist and the review traps
asccannot enforce for you.