| name | asc-release-flow |
| description | Determine whether an app is ready to submit, then drive the current App Store release flow with asc, including validation, staging, review submission, first-time availability, versioned subscriptions and IAPs, Game Center, and App Privacy checks. |
Release flow (readiness-first)
Use this skill when the question is "Can my app be submitted now?" or when the user wants to prepare and submit an App Store version with the current asc command surface.
Preconditions
- Resolve
APP_ID, version string, VERSION_ID when needed, and BUILD_ID up front.
- Ensure auth is configured with
asc auth login or ASC_* environment variables.
- Have canonical metadata in
./metadata when using metadata-driven staging.
- Treat
asc web ... commands as optional web-session fallbacks for flows not covered by the public API.
Answer order
- Say whether the app is ready right now.
- Name the blocking issues.
- Separate public-API fixes from web-session or manual fixes.
- Give the next exact command to run.
Blockers usually fall into:
- API-fixable: build validity, metadata, screenshots, review details, content rights, encryption, version/build attachment, IAP readiness, Game Center version and review-submission items.
- Web-session-fixable: first-review subscription attachment and App Privacy publish state.
- Manual fallback: first-time IAP selection on the app-version page when no CLI attach flow exists, or any flow the user does not want to run through web-session commands.
Canonical current path
1. Readiness check
Use asc validate; the old submit-preflight shortcut is not part of the current CLI.
asc validate --app "APP_ID" --version "1.2.3" --platform IOS --output table
Use strict mode when warnings should block automation:
asc validate --app "APP_ID" --version "1.2.3" --platform IOS --strict --output table
For apps selling digital goods, run the product readiness checks too:
asc validate iap --app "APP_ID" --output table
asc validate subscriptions --app "APP_ID" --output table
2. Stage without submitting
Use asc release stage when the user wants to prepare the version, apply/copy metadata, attach the build, and validate, while stopping before review submission.
asc release stage \
--app "APP_ID" \
--version "1.2.3" \
--build "BUILD_ID" \
--metadata-dir "./metadata/version/1.2.3" \
--dry-run \
--output table
Apply the staging mutations after the plan looks correct:
asc release stage \
--app "APP_ID" \
--version "1.2.3" \
--build "BUILD_ID" \
--metadata-dir "./metadata/version/1.2.3" \
--confirm
Use --copy-metadata-from "1.2.2" instead of --metadata-dir when carrying metadata forward from an existing version.
3. Submit an already prepared version
Use asc review submit for explicit App Store review submission. It wraps build attachment plus review submission creation.
asc review submit --app "APP_ID" --version "1.2.3" --build "BUILD_ID" --dry-run --output table
asc review submit --app "APP_ID" --version "1.2.3" --build "BUILD_ID" --confirm
Use --version-id "VERSION_ID" instead of --version when you already resolved the exact version ID.
4. One-command upload and submit
Use asc publish appstore when upload/build/local-build and submission should be one high-level flow.
asc publish appstore --app "APP_ID" --ipa "./App.ipa" --version "1.2.3" --submit --dry-run --output table
asc publish appstore --app "APP_ID" --ipa "./App.ipa" --version "1.2.3" --submit --confirm
Add --wait when the command should wait for build processing before attaching/submitting.
5. Monitor and cancel
asc status --app "APP_ID"
asc submit status --version-id "VERSION_ID"
asc submit status --id "SUBMISSION_ID"
asc submit cancel --id "SUBMISSION_ID" --confirm
First-time submission blockers
Initial app availability does not exist
Symptoms:
asc pricing availability view --app "APP_ID" reports no availability.
asc pricing availability edit ... cannot update because there is no existing availability record.
Check:
asc pricing availability view --app "APP_ID"
Bootstrap the first availability record through the public API:
asc pricing availability create \
--app "APP_ID" \
--territory "USA,GBR" \
--available true \
--available-in-new-territories true
After bootstrap, use the public API for ongoing changes:
asc pricing availability edit \
--app "APP_ID" \
--territory "USA,GBR" \
--available true \
--available-in-new-territories true
Subscriptions are ready but not attached to first review
Check subscription readiness first:
asc validate subscriptions --app "APP_ID" --output table
If diagnostics report missing metadata, fix those prerequisites before attaching. Common misses are broad pricing coverage, review screenshots, promotional images, and app/build evidence.
List first-review subscription state:
asc web review subscriptions list --app "APP_ID"
Attach a group for first review:
asc web review subscriptions attach-group \
--app "APP_ID" \
--group-id "GROUP_ID" \
--confirm
Attach one subscription instead:
asc web review subscriptions attach \
--app "APP_ID" \
--subscription-id "SUB_ID" \
--confirm
The product-scoped asc subscriptions review submit shortcut is deprecated.
Do not build new workflows around it.
The API 4.4.1 versioned workflow below is for a subsequent review or another
existing review submission. It does not replace the web-session flow above for
attaching a subscription or group to its first review. Prepare the
version-scoped metadata and add that version—not the subscription product—to
the existing submission:
asc subscriptions versions list --subscription-id "SUB_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
Branch on the number of returned versions before any write:
- Zero: create one version and capture
.data.id as
SUBSCRIPTION_VERSION_ID.
- One: reuse
.data[0].id as SUBSCRIPTION_VERSION_ID; do not create.
- More than one: stop and require the user to choose an explicit version ID.
Run this only in the zero-result branch:
asc subscriptions versions create --subscription-id "SUB_ID" --output json
Resolve the intended locale before writing:
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output json
If en-US is absent, create it:
asc subscriptions versions localizations create --version-id "SUBSCRIPTION_VERSION_ID" --locale "en-US" --name "Premium" --description "Premium access"
If the single resolved en-US localization exists but differs, update that
resolved ID. If it already matches, reuse it and do nothing. Stop if locale
resolution is ambiguous.
asc subscriptions versions localizations update --id "SUBSCRIPTION_LOC_ID" --name "Premium" --description "Premium access"
Resolve images before writing:
asc subscriptions versions images list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output json
If the intended image is already present, reuse it and do nothing. If no image
is present, upload it:
asc subscriptions versions images upload --version-id "SUBSCRIPTION_VERSION_ID" --file "./promotional.png"
If a different image must be replaced, make that a separate, explicitly
confirmed branch using its resolved ID, then upload the replacement:
asc subscriptions versions images delete --id "SUBSCRIPTION_IMAGE_ID" --confirm
asc subscriptions versions images upload --version-id "SUBSCRIPTION_VERSION_ID" --file "./promotional.png"
Inspect the resolved version and children before adding the version to the
existing review submission:
asc subscriptions versions view --id "SUBSCRIPTION_VERSION_ID" --output table
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output table
asc subscriptions versions images primary --version-id "SUBSCRIPTION_VERSION_ID" --output table
asc subscriptions versions images list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output table
asc review items add --submission "SUBMISSION_ID" --item-type subscriptionVersions --item-id "SUBSCRIPTION_VERSION_ID"
Subscription group versions follow the same existing-submission model:
asc subscriptions groups versions list --group-id "GROUP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
Branch on the number of returned group versions before any write:
- Zero: create one version and capture
.data.id as GROUP_VERSION_ID.
- One: reuse
.data[0].id as GROUP_VERSION_ID; do not create.
- More than one: stop and require the user to choose an explicit version ID.
Run this only in the zero-result branch:
asc subscriptions groups versions create --group-id "GROUP_ID" --output json
Resolve the intended locale before writing:
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output json
If en-US is absent, create it:
asc subscriptions groups versions localizations create --version-id "GROUP_VERSION_ID" --locale "en-US" --name "Premium"
If the single resolved en-US localization exists but differs, update that
resolved ID. If it already matches, reuse it and do nothing. Stop if locale
resolution is ambiguous.
asc subscriptions groups versions localizations update --id "GROUP_LOC_ID" --name "Premium"
Inspect the resolved group version and localizations before adding it to the
existing review submission:
asc subscriptions groups versions view --version-id "GROUP_VERSION_ID" --output table
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output table
asc review items add --submission "SUBMISSION_ID" --item-type subscriptionGroupVersions --item-id "GROUP_VERSION_ID"
In-app purchases need review readiness or first-version inclusion
asc validate iap --app "APP_ID" --output table
Upload missing review screenshots:
asc iap review-screenshots create --iap-id "IAP_ID" --file "./review.png"
The product-scoped asc iap submit shortcut is deprecated. Use the versioned
workflow below for new review submissions.
For an API 4.4.1 IAP version, use its version ID throughout the v2 metadata,
image, and review flow:
asc iap versions list --iap-id "IAP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
Branch on the number of returned IAP versions before any write:
- Zero: create one version and capture
.data.id as IAP_VERSION_ID.
- One: reuse
.data[0].id as IAP_VERSION_ID; do not create.
- More than one: stop and require the user to choose an explicit version ID.
Run this only in the zero-result branch:
asc iap versions create --iap-id "IAP_ID" --output json
Resolve the intended locale before writing:
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output json
If en-US is absent, create it:
asc iap versions localizations create --version-id "IAP_VERSION_ID" --locale "en-US" --name "Premium" --description "Unlock premium features"
If the single resolved en-US localization exists but differs, update that
resolved ID. If it already matches, reuse it and do nothing. Stop if locale
resolution is ambiguous.
asc iap versions localizations update --localization-id "IAP_LOC_ID" --name "Premium" --description "Unlock premium features"
Resolve images before writing:
asc iap versions images list --version-id "IAP_VERSION_ID" --paginate --output json
If the intended image is already present, reuse it and do nothing. If no image
is present, create it:
asc iap versions images create --version-id "IAP_VERSION_ID" --file "./review.png"
If a different image must be replaced, make that a separate, explicitly
confirmed branch using its resolved ID, then create the replacement:
asc iap versions images delete --image-id "IAP_IMAGE_ID" --confirm
asc iap versions images create --version-id "IAP_VERSION_ID" --file "./review.png"
Inspect the resolved version and children before adding it to the existing
review submission:
asc iap versions view --version-id "IAP_VERSION_ID" --output table
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output table
asc iap versions image --version-id "IAP_VERSION_ID" --output table
asc iap versions images list --version-id "IAP_VERSION_ID" --paginate --output table
asc iap versions submit --version-id "IAP_VERSION_ID" --submission "SUBMISSION_ID" --confirm
For the first IAP on an app, or the first time adding a new IAP type, Apple may require selecting the IAP from the app version's "In-App Purchases and Subscriptions" section before submitting the app version. Prepare the IAP with localization, pricing, and review screenshot data first.
For non-renewing IAPs that must be attached to the next app version review, the public API may reject the review item path. The CLI exposes a web-session fallback that mirrors the App Store Connect web flow:
asc web review iaps attach --app "APP_ID" --iap-id "IAP_ID" --confirm
Use this only for the web-only first-version selection gap, and call out that it requires an authenticated Apple web session.
Game Center needs app-version and review-submission items
asc game-center app-versions list --app "APP_ID"
asc game-center app-versions create --app-store-version-id "VERSION_ID"
If Game Center component versions must ship with the app version, use the explicit review-submission API so all items can be added before submission:
asc review submissions-create --app "APP_ID" --platform IOS
asc review items add --submission "SUBMISSION_ID" --item-type appStoreVersions --item-id "VERSION_ID"
asc review items add --submission "SUBMISSION_ID" --item-type gameCenterLeaderboardVersions --item-id "GC_LEADERBOARD_VERSION_ID"
asc review items add --submission "SUBMISSION_ID" --item-type inAppPurchaseVersions --item-id "IAP_VERSION_ID"
asc review items add --submission "SUBMISSION_ID" --item-type subscriptionVersions --item-id "SUBSCRIPTION_VERSION_ID"
asc review items add --submission "SUBMISSION_ID" --item-type subscriptionGroupVersions --item-id "GROUP_VERSION_ID"
asc review submissions-submit --id "SUBMISSION_ID" --confirm
asc review items add also supports gameCenterAchievementVersions, gameCenterActivityVersions, gameCenterChallengeVersions, and gameCenterLeaderboardSetVersions.
App Privacy is still unpublished
The public API can surface privacy advisories, but it cannot fully verify App Privacy publish state.
asc web privacy pull --app "APP_ID" --out "./privacy.json"
asc web privacy plan --app "APP_ID" --file "./privacy.json"
asc web privacy apply --app "APP_ID" --file "./privacy.json"
asc web privacy publish --app "APP_ID" --confirm
If the user avoids web-session commands, confirm App Privacy manually in App Store Connect:
https://appstoreconnect.apple.com/apps/APP_ID/appPrivacy
Review details are incomplete
asc review details-for-version --version-id "VERSION_ID"
Create or update details:
asc review details-create \
--version-id "VERSION_ID" \
--contact-first-name "Dev" \
--contact-last-name "Support" \
--contact-email "dev@example.com" \
--contact-phone "+1 555 0100" \
--notes "Explain the reviewer access path here."
asc review details-update \
--id "DETAIL_ID" \
--notes "Updated reviewer instructions."
Only set demo-account fields when App Review truly needs demo credentials.
Ready checklist
An app is effectively ready when:
asc validate --app "APP_ID" --version "VERSION" --platform IOS has no blocking issues.
asc release stage --dry-run produces the expected plan, or asc release stage --confirm has successfully prepared the target version.
- The build is
VALID and attached to the target version.
- Metadata, screenshots, app info, content rights, encryption, age rating, and review details are complete.
- App availability exists.
- Digital goods have localization, pricing, review screenshots, and any first-review attachments or manual selections handled.
- Game Center app-version and component review items are included when needed.
- App Privacy is confirmed or published.
Notes
- Do not use the legacy submit-preflight, submit-create, or release-run shortcuts; they are not part of the current CLI.
- Use
asc validate for readiness.
- Use
asc release stage for pre-submit preparation.
- Use
asc review submit for explicit App Store review submission.
- Use
asc publish appstore --submit --confirm for high-level upload plus submission.
- Use
asc status and asc submit status after submission.