← Back to Posts

App Store APIs vs. Developer Portals: What Apple and Google Let You Automate (and What They Force by Hand)

TL;DR: While both Apple and Google provide extensive REST APIs for release automation, neither platform lets you take an app from zero to live without manual steps in their web consoles. Initial app creation, legal agreements, IARC rating surveys, EU trader declarations, and reviewer access credentials are hard portal gates. Understanding this boundary, what our cross-platform reconcile engine appyshippy calls "the console residue", is the key to building reliable CI/CD pipelines without brittle hacks.

flowchart TD subgraph AUTO["AUTOMATED VIA REST APIS (App Store Connect & Publisher)"] A1["Localized Titles & Descriptions"] A2["Screenshots & Video Previews"] A3["Bundle / Binary Ingest & Tracks"] A4["IAP & Subscriptions Catalog"] A5["Game Center Progression"] A6["Review Submission Staging"] end subgraph GATES["MANDATORY WEB CONSOLE GATES (App Store Connect & Play Console)"] G1["Initial App Record Creation"] G2["Developer Agreements & Tax/Bank"] G3["IARC Content Rating Survey"] G4["EU DSA Trader Status Check"] G5["Play Games Achievement Icons"] G6["Review Access Credentials Setup"] end
┌────────────────────────────────────────────────────────────────────────┐
│                     THE STORE AUTOMATION BOUNDARY                      │
├───────────────────────────────────┬────────────────────────────────────┤
│   AUTOMATED VIA REST APIS         │   MANDATORY WEB CONSOLE GATES      │
│   (App Store Connect & Publisher) │   (App Store Connect & Play Store) │
├───────────────────────────────────┼────────────────────────────────────┤
│ • Localized Titles & Descriptions │ • Initial App Record Creation      │
│ • Screenshots & Video Previews    │ • Developer Agreements & Tax/Bank  │
│ • Bundle / Binary Ingest & Tracks │ • IARC Content Rating Survey       │
│ • IAP & Subscriptions Catalog     │ • EU DSA Trader Status Check       │
│ • Game Center Progression         │ • Play Games Achievement Icons     │
│ • Review Submission Staging       │ • Review Access Credentials Setup  │
└───────────────────────────────────┴────────────────────────────────────┘

The Initial App Creation Paradox

The single most common surprise for mobile release engineers is that neither Apple nor Google allows you to spawn a brand new public app record purely via their official REST APIs.

Apple App Store Connect: The Missing POST /v1/apps

The official App Store Connect API (authenticated via ES256 JWT using an API Key .p8) provides rich CRUD endpoints for almost every version-scoped resource. However, there is no public endpoint to create an app record from scratch.

  • Why Fastlane produce Works (and Its Hidden Cost): Tools like Fastlane's produce historically automated app creation by scraping Apple's internal portal session using the Ruby spaceship gem. This requires an interactive Apple ID username, password, and two-factor authentication (2FA) session cookie. In automated CI/CD environments, this creates severe security liabilities: storing root Apple ID credentials, risking session expiration, and violating least-privilege security boundaries.
  • The Official Reality: In modern secure setups, the initial App record must be allocated either manually in the App Store Connect web portal or through the Xcode Organizer UI. Once the app entity exists and its immutable Apple ID is assigned, the REST API can manage every subsequent lifecycle event.

Google Play Console: Edit Sessions Require an Existing Package

The Google Play Developer Publishing API (androidpublisher v3) operates through atomic edit transactions (edits.insert → mutate → edits.commit).

  • Every edit transaction requires an existing packageName already registered to the developer account.
  • You cannot issue a REST call to claim a package name and create an app record for public consumer distribution. You must first click "Create app" in Google Play Console, declaring the app name, default language, application vs. game classification, and free vs. paid commercial model.
  • (Note: Google provides a specialized "Custom App Publishing API", but that is restricted strictly to enterprise private distribution in managed Google Play domains, not consumer Play Store distribution).

Master Comparison: API Automation vs. Portal Gates

Workflow Area Platform What the API Automates What the Portal Forces by Hand
Initial Registration Apple Bundle IDs (bundleIds), provisioning profiles, certificates App record creation, initial SKU, default primary locale
Initial Registration Google Play Nothing prior to console registration App creation, package claiming, app vs game classification
Legal & Financial Apple None (read-only finance/sales reports via API) Apple Developer Agreement (PLA), Paid Apps Contract, Bank/W-8BEN
Legal & Financial Google Play None (reporting only) Developer Distribution Agreement (DDA), Google Payments Merchant Center
Store Metadata Apple Name/subtitle (appInfos), description/keywords (appStoreVersions) Primary category change (requires portal in certain review states)
Store Metadata Google Play Title (30c), short desc (80c), full desc (4000c) via edits.listings Selecting store category tags (managed via console checklist)
Screenshots & Media Apple Reserve → chunked PUT → commit MD5 (appScreenshots) None (fully automatable across all device display types)
Screenshots & Media Google Play Phone, 7-inch, 10-inch, promo graphics (edits.images.upload) None (fully automatable via Publishing API)
Binary Ingest Apple Build queries, testflight assignment (builds) Binary ingest itself uses Transporter / xcrun altool (not REST API)
Binary Ingest Google Play Direct Android App Bundle upload (edits.bundles.upload) None (fully automatable over REST)
Compliance / Ratings Apple 29 age rating attributes (ageRatingDeclarations) App Privacy Nutrition Labels initial setup & questionnaire
Compliance / Ratings Google Play Data Safety CSV import (applications.dataSafety) IARC Content Rating Questionnaire (No API exists)
Regulatory Gates Apple Export compliance flags in Info.plist / builds EU Digital Services Act (DSA) Trader Status Declaration
Regulatory Gates Google Play Target API level validation feedback Personal Account 20-tester / 14-day closed testing verification
Game Services Apple Game Center leaderboards, achievements, localized sets None (fully exposed in ASC API)
Game Services Google Play Leaderboard / achievement rules (gamesconfiguration v1) Achievement & Leaderboard icons (512×512) - Permanently Console Only
Review Submission Apple Three-call flow (reviewSubmissions + reviewSubmissionItems) Demo reviewer credentials, resolving rejections, appeals
Review Submission Google Play Commit edit to track (edits.commit) triggers review App Access reviewer login declaration & manual credentials

Both store ecosystems enforce legal accountability that strictly requires human authorization:

flowchart TD LOGIN["ACCOUNT HOLDER LOGIN"] --> APPLE["APPLE APP STORE"] LOGIN --> GOOGLE["GOOGLE PLAY"] subgraph APPLE["APPLE APP STORE"] AP1["Paid Apps Contract"] AP2["Banking IBAN / Routing"] AP3["W-8BEN / Tax Forms"] AP4["EU DSA Trader Status"] end subgraph GOOGLE["GOOGLE PLAY"] GP1["Payments Merchant"] GP2["D-U-N-S Org Verify"] GP3["20 Testers (14 Days)"] GP4["Target Audience / Ads"] end
                                  ┌────────────────────────┐
                                  │  ACCOUNT HOLDER LOGIN  │
                                  └───────────┬────────────┘
                                              │
                    ┌─────────────────────────┴─────────────────────────┐
                    ▼                                                   ▼
      ┌───────────────────────────┐                       ┌───────────────────────────┐
      │      APPLE APP STORE      │                       │        GOOGLE PLAY        │
      ├───────────────────────────┤                       ├───────────────────────────┤
      │ • Paid Apps Contract      │                       │ • Payments Merchant       │
      │ • Banking IBAN / Routing  │                       │ • D-U-N-S Org Verify      │
      │ • W-8BEN / Tax Forms      │                       │ • 20 Testers (14 Days)    │
      │ • EU DSA Trader Status    │                       │ • Target Audience / Ads   │
      └───────────────────────────┘                       └───────────────────────────┘
  1. Contractual Acceptance: When Apple updates the Apple Developer Program License Agreement (PLA) or Google amends the Developer Distribution Agreement (DDA), the account holder must log in with hardware or SMS 2FA to accept the terms. API token generation is often suspended or blocked from submitting updates until the legal agreement is signed.
  2. Financial Merchant Setup: Configuring bank accounts, currency settlement options, tax withholding forms, and digital merchant registrations cannot be touched via API to prevent automated account takeover attacks.
  3. EU Digital Services Act (DSA): Developers distributing in the European Union must declare whether they operate as a "Trader". If classified as a trader, physical addresses, phone numbers, and official emails must be verified through the portal and displayed publicly on the store page.
  4. Google's Personal Developer 20-Tester Hurdle: Since late 2023, newly created personal Google Play accounts cannot release an app to production via API until they complete a mandatory closed testing track with at least 20 opted-in testers for 14 continuous days, followed by a subjective console application questionnaire.

The Questionnaire Barrier: IARC & Privacy Labels

The most common point of failure in headless publishing pipelines is hitting a compliance gate that has no automated answer channel.

Google Play: The IARC Content Rating Dead End

Google Play requires every app to obtain a rating certificate from the International Age Rating Coalition (IARC).

  • The IARC survey asks nuanced questions about violence, profanity, crude humor, simulated gambling, controlled substances, and user interaction.
  • There is no programmatic API for this survey. The Google Play Developer API does not expose any endpoint to take survey parameters or apply an existing rating hash. A human must click through the questionnaire in the Play Console to generate the IARC license.

Apple: App Privacy Nutrition Labels

While Apple's OpenAPI surface has added endpoints to inspect privacy declarations (appInfos / appPrivacyDeclarations), declaring data collection categories (Financial Info, Contact Info, User Identifiers, Diagnostics, Tracking Domains) for third-party SDKs is designed as an interactive multi-step wizard. An incomplete privacy declaration prevents any new version from advancing to App Review.


Binary Ingest Architecture: .ipa vs. .aab

Even delivering the compiled binary reveals a fundamental divergence in design philosophy between the two platforms:

flowchart TD BIN["COMPILED APP BINARIES"] --> IOS["iOS (.ipa)"] BIN --> ANDROID["Android (.aab)"] subgraph IOS["iOS (.ipa)"] I1["Transporter CLI / xcrun altool"] I2["Aspera / WebDAV Ingest Stream"] I3["Dedicated App-Specific Password / Key"] end subgraph ANDROID["Android (.aab)"] A1["Google Publisher REST API"] A2["Direct HTTP PUT Upload"] A3["Unified Service Account OAuth2"] end
                      ┌─────────────────────────────────┐
                      │      COMPILED APP BINARIES      │
                      └────────────────┬────────────────┘
                                       │
                   ┌───────────────────┴───────────────────┐
                   ▼                                       ▼
        ┌─────────────────────┐                 ┌─────────────────────┐
        │      iOS (.ipa)     │                 │    Android (.aab)   │
        ├─────────────────────┤                 ├─────────────────────┤
        │ • Transporter CLI   │                 │ • Google Publisher  │
        │ • xcrun altool      │                 │   REST API          │
        │ • Aspera / WebDAV   │                 │ • Direct HTTP PUT   │
        │ • Separate Auth     │                 │ • Service Account   │
        └─────────────────────┘                 └─────────────────────┘
  • Apple's Transporter Seam: The App Store Connect REST API does not ingest .ipa files. Apple handles binary packages via its legacy Transporter protocol (Aspera / Signiant / WebDAV). When automated in modern CI/CD, engineers must call xcrun altool --upload-app or the standalone Java iTMSTransporter package. Once ingested and processed, the build becomes visible in the REST API under GET /v1/builds.
  • Google's Unified REST Stream: Google Play accepts Android App Bundles directly through the standard Publisher REST API (POST /upload/androidpublisher/v3/applications/{packageName}/edits/{editId}/bundles). The same OAuth2 Service Account token that edits metadata uploads the binary payload.

Game Services: The 144-Icon Reality

When building games with achievements and leaderboards, the divide between APIs becomes acute.

In our production engine appyshippy, we discovered a permanent limitation in Google's Play Games Services configuration API (gamesconfiguration v1configuration):

Google Play Games Configuration API:
├── Achievement Configurations (name, points, description) ──► API Supported
├── Leaderboard Configurations (score format, ordering)      ──► API Supported
└── Achievement & Leaderboard Icons (512×512 PNG)           ──► ⚠ PERMANENTLY CONSOLE ONLY

While Apple's App Store Connect API cleanly supports uploading Game Center achievement and leaderboard images via gameCenterAchievementImages and gameCenterLeaderboardImages, Google's API does not expose image upload endpoints for Play Games configurations.

For a game with 132 achievements and 12 leaderboards, that means 144 icons must be uploaded by hand in the Google Play Console UI, forever. Filing that as an API bug in your internal backlog sends engineers on a wild goose chase; documenting it as permanent console residue allows teams to schedule artwork uploads pragmatically.


Architectural Lessons from appyshippy

When architecting a production-grade store management tool across Apple and Google, we established three core principles to handle this hybrid reality:

flowchart TD M["Authored Manifest (YAML/JSON)"] --> V["Validation & Injectivity Check"] V --> P["Plan / Diff Three-Way"] P --> S["Automated REST Sync\n(Adopt-Before-Create)"] P --> R["Console Residue\n(Human Action Checklist)"] S --> L["Live Store Platform"] R --> D["Developer Web Portal"]
┌────────────────────────────────────────────────────────────────────────┐
│                     THE APPYSHIPPY RECONCILE LOOP                      │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   Authored Manifest (YAML/JSON) ──► Validation & Injectivity Check     │
│                                                │                       │
│                                                ▼                       │
│                                      Plan / Diff Three-Way             │
│                                                │                       │
│                         ┌──────────────────────┴─────────────────────┐ │
│                         ▼                                            ▼ │
│                Automated REST Sync                    Console Residue  │
│               (Adopt-Before-Create)                 (Human Action List)│
│                         │                                            │ │
│                         ▼                                            ▼ │
│                Live Store Platform                   Developer Portal  │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

1. Adopt-Before-Create

When an app or in-app purchase has already been configured manually in a store console, naive automation scripts attempt to recreate it and fail with 409 Conflict.

  • The Solution: A true reconcile loop inspects the remote store first, matches existing entities by unique canonical identifiers (like Bundle ID or SKU), adopts the remote reference, and writes the platform-assigned ID back to the local manifest before ever issuing a create call.

2. "Residue" as a First-Class Output

Instead of treating un-automatable steps as pipeline failures, our CLI outputs a dedicated command: shippy residue <app>.

  • Residue lists every outstanding human task:
    • "Play Games achievement icons need manual upload (144 items)"
    • "EU DSA Trader Declaration unverified"
    • "IARC content rating survey pending completion"
  • By treating manual tasks as structured residue rather than unexpected errors, CI/CD pipelines report clean statuses for automated work and clear action items for human managers.

3. Avoid Private Web Scrapers

Resist the temptation to bypass portal gates using headless browser automation or private session cookies for tasks like app creation. Session cookies expire, CAPTCHAs break unattended runners, and authenticating with full admin Apple IDs in CI violates modern credential boundaries.

The clean pattern is clear: Let the human do the 10-minute setup once in the portal, adopt the result, and let the API handle the thousands of releases that follow.

← Back to All Posts