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

SectionWhat it controlsRequired at submissionEditable after release
App InformationName, primary language, bundle ID, category, content rightsYesSome fields locked
Pricing & AvailabilityPrice tier, regions, pre-order, custom B2BYesYes (phased)
App PrivacyData collection nutrition labelsYes (since iOS 14.5)Yes (re-review for changes)
Version (1.0, 1.1, …)Build, what’s new, screenshots, description, keywordsYesUntil “Ready for Sale”
TestFlightBeta groups, builds, tester invitesNo (for App Store)Always
App Store Connect Users & AccessTeam roles, App Store Connect API keysn/aAlways
App AnalyticsImpressions, downloads, sessions, crashesn/aAlways
Sales and TrendsRevenue, units, refund datan/aAlways

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.

  1. App Store Connect → My Apps → “+”.
  2. Platforms: iOS (or macOS, tvOS, visionOS — same record can hold multiple).
  3. Name — appears under the icon on devices. 30 chars max. Cannot be edited during a review.
  4. Primary Language — locks your default localization.
  5. Bundle ID — picks from registered IDs in the dev portal; cannot be changed after a build is uploaded.
  6. SKU — internal identifier you choose. Used in reports.
  7. User Access — Full Access vs Limited Access (granular per-app).

Screenshots — required sizes (2026).

Device classRequired sizeNotes
iPhone 6.9“ (iPhone 16 Pro Max)1290 × 2796Apple uses these for the marketing page first
iPhone 6.5“ (iPhone XS Max generation)1284 × 2778Optional if 6.9“ provided
iPhone 5.5“1242 × 2208Still required for some older app categories
iPad Pro 13“ (M4)2064 × 2752Required for iPad apps
iPad Pro 12.9“ (3rd gen)2048 × 2732Often shared across iPad classes
App Preview video30 seconds max, .mov/.mp4Optional 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 deliver from 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 Apps feature 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 + frameit for repeatable, localized screenshots.

Common misconceptions

  1. “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.
  2. “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.
  3. “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.
  4. “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.”
  5. “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 containing description.txt, keywords.txt, name.txt, etc. per locale. fastlane deliver syncs 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