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.
┌────────────────────────────────────────────────────────────────────────┐
│ 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
produceWorks (and Its Hidden Cost): Tools like Fastlane'sproducehistorically automated app creation by scraping Apple's internal portal session using the Rubyspaceshipgem. 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
packageNamealready 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 |
Legal, Financial, and Regulatory Moats
Both store ecosystems enforce legal accountability that strictly requires human authorization:
┌────────────────────────┐
│ 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 │
└───────────────────────────┘ └───────────────────────────┘
- 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.
- 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.
- 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.
- 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:
┌─────────────────────────────────┐
│ 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
.ipafiles. Apple handles binary packages via its legacy Transporter protocol (Aspera / Signiant / WebDAV). When automated in modern CI/CD, engineers must callxcrun altool --upload-appor the standalone JavaiTMSTransporterpackage. Once ingested and processed, the build becomes visible in the REST API underGET /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:
┌────────────────────────────────────────────────────────────────────────┐
│ 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.