asc metadata sync
Use this skill to keep App Store metadata in sync with App Store Connect. Prefer the canonical asc metadata workflow for app-info and version localization fields. Use the lower-level asc localizations and asc migrate commands only when the user specifically needs .strings files or legacy fastlane-format metadata.
Current canonical workflow
1. Pull canonical metadata
asc metadata pull --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata"
If the app has multiple app-info records, resolve the app-info ID first and pass it explicitly:
asc apps info list --app "APP_ID" --output table
asc metadata pull --app "APP_ID" --app-info "APP_INFO_ID" --version "1.2.3" --platform IOS --dir "./metadata"
2. Edit local files
Canonical files are written under:
metadata/app-info/<locale>.jsonfor app-level fields:name,subtitle,privacyPolicyUrl,privacyChoicesUrl,privacyPolicyTextmetadata/version/<version>/<locale>.jsonfor version fields:description,keywords,marketingUrl,promotionalText,supportUrl,whatsNew
Copyright is not a localization field. Manage it with:
asc versions update --version-id "VERSION_ID" --copyright "2026 Your Company"
3. Validate before upload
asc metadata validate --dir "./metadata" --output table
For subscription apps, include the extra Terms of Use / EULA heuristic:
asc metadata validate --dir "./metadata" --subscription-app --output table
4. Preview and apply
Run a dry run first:
asc metadata push --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata" --dry-run --output table
Apply after the plan looks correct:
asc metadata push --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata"
Use asc metadata apply when the user wants the apply-named command shape for the same canonical files:
asc metadata apply --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata" --dry-run
asc metadata apply --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata"
Keyword-only workflow
Use this when only the version-localization keywords field should change:
asc metadata keywords diff --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata"
asc metadata keywords apply --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata" --confirm
For importing keyword research:
asc metadata keywords import --dir "./metadata" --version "1.2.3" --locale "en-US" --input "./keywords.csv"
asc metadata keywords sync --app "APP_ID" --version "1.2.3" --platform IOS --dir "./metadata" --input "./keywords.csv"
Quick field updates
For one-off version-localization edits, pass an explicit version selector. Use --version-id for deterministic updates when you already have it, or --version plus --platform when working from a version string.
asc apps info edit --app "APP_ID" --version-id "VERSION_ID" --locale "en-US" --whats-new "Bug fixes and improvements"
asc apps info edit --app "APP_ID" --version "1.2.3" --platform IOS --locale "en-US" --description "Your app description here"
asc apps info edit --app "APP_ID" --version "1.2.3" --platform IOS --locale "en-US" --keywords "keyword1,keyword2,keyword3"
asc apps info edit --app "APP_ID" --version "1.2.3" --platform IOS --locale "en-US" --support-url "https://support.example.com"
For app-info fields, prefer the post-create setup command:
asc app-setup info set --app "APP_ID" --primary-locale "en-US" --privacy-policy-url "https://example.com/privacy"
asc app-setup info set --app "APP_ID" --locale "en-US" --name "Your App Name" --subtitle "Your subtitle"
Lower-level localization files
Use .strings files when the user specifically wants import/export files instead of canonical JSON:
asc localizations list --version "VERSION_ID" --output table
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"
For app-info localizations:
asc apps info list --app "APP_ID" --output table
asc localizations list --app "APP_ID" --type app-info --app-info "APP_INFO_ID" --output table
asc localizations download --app "APP_ID" --type app-info --app-info "APP_INFO_ID" --path "./app-info-localizations"
asc localizations upload --app "APP_ID" --type app-info --app-info "APP_INFO_ID" --path "./app-info-localizations" --dry-run
asc localizations upload --app "APP_ID" --type app-info --app-info "APP_INFO_ID" --path "./app-info-localizations"
Legacy fastlane metadata
Use this only for existing fastlane-format trees:
asc migrate export --app "APP_ID" --version-id "VERSION_ID" --output-dir "./fastlane"
asc migrate validate --fastlane-dir "./fastlane"
asc migrate import --app "APP_ID" --version-id "VERSION_ID" --fastlane-dir "./fastlane" --dry-run
asc migrate import --app "APP_ID" --version-id "VERSION_ID" --fastlane-dir "./fastlane"
Character limits
| Field | Limit |
|---|---|
| Name | 30 |
| Subtitle | 30 |
| Keywords | 100 comma-separated characters |
| Description | 4000 |
| What's New | 4000 |
| Promotional Text | 170 |
Agent behavior
- Start with
asc metadata pullunless the user specifically asks for.stringsor fastlane metadata. - Always run
asc metadata validatebefore remote writes. - Preview remote changes with
--dry-runwhen the command supports it. - For quick edits, always pass
--version-idor--versionplus--platform; do not rely on ambiguous latest-version behavior. - Keep app-info fields and version fields separate.
- Use
--output tablefor human verification and JSON for automation.