10.3 — App Store Connect
Opening scenario
Your app finally builds, signs, and uploads. You navigate to App Store Connect to submit for review and discover you need: a privacy nutrition label, screenshots in five required sizes, a 4000-character description in two languages, an age rating from a 30-question questionnaire, export compliance documentation, the URL of a working support page, and a marketing icon at exactly 1024×1024 with zero alpha. Each missing field is a separate “Submit” button blocker. You ship two days late.
App Store Connect is where your engineering work meets Apple’s distribution machinery. Knowing what it demands before you build saves you from “we built the app, now we have to invent the screenshots” panic.
Context taxonomy
| Section | What it controls | Required at submission | Editable after release |
|---|---|---|---|
| App Information | Name, primary language, bundle ID, category, content rights | Yes | Some fields locked |
| Pricing & Availability | Price tier, regions, pre-order, custom B2B | Yes | Yes (phased) |
| App Privacy | Data collection nutrition labels | Yes (since iOS 14.5) | Yes (re-review for changes) |
| Version (1.0, 1.1, …) | Build, what’s new, screenshots, description, keywords | Yes | Until “Ready for Sale” |
| TestFlight | Beta groups, builds, tester invites | No (for App Store) | Always |
| App Store Connect Users & Access | Team roles, App Store Connect API keys | n/a | Always |
| App Analytics | Impressions, downloads, sessions, crashes | n/a | Always |
| Sales and Trends | Revenue, units, refund data | n/a | Always |
Concept → Why → How → Code
Concept. App Store Connect is two things at once: the product catalog (one record per app) and the operational dashboard (analytics, finance, users).
Why. Splitting the dev portal (signing) from App Store Connect (distribution) lets non-engineering roles (marketing, finance) operate without code signing access.
How — create an app record.
- App Store Connect → My Apps → “+”.
- Platforms: iOS (or macOS, tvOS, visionOS — same record can hold multiple).
- Name — appears under the icon on devices. 30 chars max. Cannot be edited during a review.
- Primary Language — locks your default localization.
- Bundle ID — picks from registered IDs in the dev portal; cannot be changed after a build is uploaded.
- SKU — internal identifier you choose. Used in reports.
- User Access — Full Access vs Limited Access (granular per-app).
Screenshots — required sizes (2026).
| Device class | Required size | Notes |
|---|---|---|
| iPhone 6.9“ (iPhone 16 Pro Max) | 1290 × 2796 | Apple uses these for the marketing page first |
| iPhone 6.5“ (iPhone XS Max generation) | 1284 × 2778 | Optional if 6.9“ provided |
| iPhone 5.5“ | 1242 × 2208 | Still required for some older app categories |
| iPad Pro 13“ (M4) | 2064 × 2752 | Required for iPad apps |
| iPad Pro 12.9“ (3rd gen) | 2048 × 2732 | Often shared across iPad classes |
| App Preview video | 30 seconds max, .mov/.mp4 | Optional but high-converting |
Up to 10 screenshots per device class, up to 3 app preview videos.
App Privacy — the nutrition label. You must declare:
- What data you collect (Contact Info, Health, Location, Browsing History, Identifiers, Purchases, Usage Data, Diagnostics, Other).
- For each: linked to user identity vs not, used for tracking vs not, purpose (Analytics, Functionality, Personalization, Ads, etc.).
Misrepresentation here is the #2 cause of post-launch removal (after IAP violations). Treat it like a legal document.
Automating with the App Store Connect API.
# Generate a JWT (App Store Connect API uses ES256)
KEY_ID="ABC1234567"
ISSUER_ID="69a6de70-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
PRIVATE_KEY=$(cat AuthKey_$KEY_ID.p8)
# Use a helper like asc-jwt or write your own with openssl + base64
TOKEN=$(asc-jwt --key-id $KEY_ID --issuer-id $ISSUER_ID --key "$PRIVATE_KEY")
# List apps in your account
curl -H "Authorization: Bearer $TOKEN" \
"https://api.appstoreconnect.apple.com/v1/apps?limit=10" | jq '.data[].attributes.name'
# Get the current version info for an app
curl -H "Authorization: Bearer $TOKEN" \
"https://api.appstoreconnect.apple.com/v1/apps/$APP_ID/appStoreVersions?limit=5"
Every field in the App Store Connect UI maps to an API endpoint. Anything you do twice should be scripted.
In the wild
- Spotify localizes to 30+ languages with separate screenshots per locale, all uploaded via Fastlane
deliverfrom their CI. - Duolingo uses phased release (gradual rollout over 7 days) on every version so a regression hits 1% of users on day one, not 100%.
- Notion uses the
Promote Appsfeature to cross-promote their Mac/Web offerings on their App Store iOS listing. - Many indie devs use Sandvox/MyAppPreview/RocketSim for screenshot mockups, then upload via Fastlane
snapshot+frameitfor repeatable, localized screenshots.
Common misconceptions
- “I can change the bundle ID later.” No. Once a build is uploaded, the bundle ID is permanent for that app record. To change it you ship as a new app.
- “App name and Subtitle are keyword-searchable equally.” Both are searchable, but the Subtitle + Keywords field (100 chars hidden from users) carry the most ASO weight. The marketing Description carries very little.
- “Screenshots show actual app content.” They can be marketing-styled — adding text overlays and lifestyle imagery is allowed. The screenshot doesn’t need to be a raw simulator capture.
- “Once submitted, I have to wait for review to update screenshots.” You can update screenshots, description, keywords, and metadata without a new binary review via “Submit for Review with metadata-only changes.”
- “Phased release is for major updates only.” Use it on every release. It’s free insurance.
Seasoned engineer’s take
Treat App Store Connect like a database your marketing team and your CI write to concurrently. Anything humans do twice should be automated; anything automation does should be auditable.
TIP. Build a “metadata as code” repo: a
fastlane/metadata/folder containingdescription.txt,keywords.txt,name.txt, etc. per locale.fastlane deliversyncs them on every release. You get version control on your store listing — invaluable for compliance audits.
WARNING. The App Store Connect API has aggressive rate limits and silently throttles. Build retry-with-backoff into any script that touches it; treat 429s as expected.
The hidden game-changer: App Store Connect users with the Marketing role can edit screenshots and copy without ever seeing your source code. Use it to keep your engineers out of the metadata business.
Interview corner
Junior — “What goes into a basic App Store submission?” A build (signed, uploaded via Xcode/Transporter/Fastlane), screenshots in required sizes, description, keywords, category, age rating, privacy nutrition label, support URL, and a 1024 icon. Then submit and wait for review.
Mid — “How would you support 10 locales for screenshots and description?” Use Fastlane deliver with a metadata/ folder per locale, generate screenshots via snapshot (Xcode UI tests across simulator/locale combinations) plus frameit for device frames. Wire it into CI so each release pushes both binary and updated metadata.
Senior — “How would you implement automatic pricing changes — e.g., a 25% discount in Brazil for one week?” Use the App Store Connect API: read current price schedule via GET /appPriceSchedules, write a new schedule with a sale tier scoped to the BRL territory, then schedule another schedule to revert at end-of-sale. Wrap in a CI job with a dry-run flag; alert on 4xx/5xx; never trust the API to be eventually consistent — verify with a follow-up GET.
Red flag — “We just have one engineer who knows how to upload to App Store Connect.” That’s a bus factor of 1 for shipping. The fix is automation + role distribution, not promoting that engineer.
Lab preview
Lab 10.3 wires metadata-as-code and binary upload into a single GitHub Actions pipeline that promotes a tagged commit all the way from green tests to App Store-submitted in under 15 minutes.
Next: 10.4 — TestFlight