Highlight
In 2020 the App Store Connect API added more than 200 endpoints, opening app version metadata, screenshot and preview upload, review submission, and Xcode Power and Performance metrics to automation—but manual release, in-app purchase, and Game Center configuration still happen on the web.
Core Content
The App Store Connect API first addressed repetitive back-office work: managing team users, creating provisioning profiles, adding or removing beta testers, and downloading sales and financial reports. Once teams scripted those steps, release prep involved far less manual work. But an important slice of the flow stayed on the website: creating new versions, maintaining App Store metadata, uploading screenshots and previews, and submitting versions for review. (00:35)
The 2020 change brought that release path into the API. Apple added more than 200 endpoints—more than double the existing API. The App Metadata API covers app categories, worldwide availability, primary language, license agreements, version creation, platform addition, screenshot and app preview upload, and localized fields such as name, description, and keywords. The full range runs from creating a new version through App Review submission. (01:02)
The demo’s Forest Explorer walks a real release: create a new version, change price, update metadata, associate an uploaded build, then submit for review. That order fits CI/CD or release scripts well—each step returns a clear HTTP response and failures stop on a specific resource. (03:17)
The same session adds the Power and Performance Metrics and Diagnostics API. It exposes the aggregated data behind Xcode Organizer analysis of memory, launch time, hang rate, disk writes, and energy use. Teams can pipe production performance trends into custom dashboards, bug systems, or regression checks. (22:39)
Boundaries are explicit. Manual release still happens on the App Store Connect website or iOS app; in-app purchase and Game Center configuration remain web-based. Price and availability changes affect the live app immediately—do not experiment on a live app. (02:00, 11:06)
Detailed Content
Creating an App Store version
(04:16) Version creation starts at the Apps resource. Each app has App Store Versions; each version has platform and versionString. The demo looks up the App ID by bundle ID, then creates an App Store Version.
GET /v1/apps?filter[bundleID]=com.example.ForestExplorer
200 OK
response data:
app id: {appId}
Key points:
filter[bundleID]in the demo pinpoints the target app.- The app id in the response is the Apple ID used throughout docs; later version, price, and build association steps need it.
- This step only reads a resource and works well as the first validation point in a release script.
POST /v1/appStoreVersions
platform: IOS
versionString: 2.0
app relationship: {appId}
201 CREATED
response data:
app store version id: {versionId}
Key points:
platform,versionString, and the app relationship are the creation fields named in the transcript.201 CREATEDmeans App Store Connect created the version; it appears in the web sidebar after login.- The returned version id is the main resource for localization, build association, and review submission.
Atomically updating a price schedule with one PATCH
(07:17) A price schedule combines App Prices and Price Tier. The current price has startDate null; future prices carry an effective date. The demo reads the current price and includes the related priceTier in the response.
GET /v1/apps/{appId}/prices?include=priceTier
200 OK
response data:
price startDate: null
priceTier: Tier 1
Key points:
startDate: nullmeans the price is currently active.priceTierpoints to read-only reference data matching the All Prices and Currencies page in App Store Connect.- Including priceTier lets the script read the price tier relationship in one response.
(08:24) For a one-week free promotion the demo does not send three create requests—it PATCHes the App once with three new prices as a single change.
PATCH /v1/apps/{appId}
relationships.prices:
- ${new-price-1}
- ${new-price-2}
- ${new-price-3}
included:
- id: ${new-price-1}
startDate: null
priceTier: Tier 1
- id: ${new-price-2}
startDate: 2020-06-29
priceTier: Tier 0
- id: ${new-price-3}
startDate: 2020-07-06
priceTier: Tier 1
200 OK
Key points:
${...}is temporary ID syntax in the demo for resources not yet created in the same request.- The three resources in
includedare created, assigned real IDs, and linked to the app by App Store Connect. - Price and availability changes go live immediately—protect production apps when testing scripts.
Four-step app preview upload
(13:33) Metadata splits into app-level and version-level. Localized name, subtitle, and privacy policy live in App Info Localizations; screenshots, promotional text, keywords, and app previews live in App Store Version Localization. The demo uses a US English 6.5-inch iPhone app preview.
GET /v1/appStoreVersions/{versionId}/appStoreVersionLocalizations
GET {appPreviewSets relationship URL}
POST /v1/appPreviewSets
previewType: IPHONE_65
localization relationship: {localizationId}
Key points:
- Each version has at least one localization—the primary language localization.
- If appPreviewSets returns an empty array, create a preview set first.
IPHONE_65is the previewType in the demo for 6.5-inch iPhone.
(15:45) Uploading the video file uses four steps: create a reservation, upload one or more parts, commit the asset, check for errors.
POST /v1/appPreviews
file name: ForestExplorer.mov
file size in bytes: <bytes>
appPreviewSet relationship: {previewSetId}
response upload operations:
method
url
length in bytes
offset in bytes
request headers
Key points:
- The reservation needs file name and byte size.
- The response lists upload operations; small files may have one operation, large files several.
- The client must slice the file by
lengthandoffsetand use each operation’s method, URL, and headers.
for each upload operation:
read bytes from offset with length
upload that part with the provided method, URL, and headers
retry only the failed part when a part upload fails
Key points:
- Part upload order does not matter; parts can upload in parallel.
- Retry only the failed part; successful parts need not be re-uploaded.
- Always design for multiple operations—the same resource might upload in one part today and several tomorrow.
PATCH /v1/appPreviews/{previewId}
uploaded: true
source file MD5 checksum: <checksum>
Key points:
- Commit sets
uploadedto true and submits the source file MD5 checksum. - App Store Connect reassembles the asset, verifies checksum, checks integrity, video length, dimensions, and audio tracks.
- Processing is async; refetch the asset and wait for
stateCOMPLETE; onFAILED, read the errors array, delete, fix, and re-upload.
Associate a build and submit for review
(19:49) Builds still upload through Xcode or Transporter. The API finds the build id and attaches it to the new version.
GET /v1/builds
filters:
app ID: {appId}
pre-release version number: {preReleaseVersion}
build version number: {buildNumber}
Key points:
- The demo filters by app ID, pre-release version number, and build version number.
- The build id in the response updates the version relationship.
- This step verifies a CI-uploaded build has reached App Store Connect.
PATCH /v1/appStoreVersions/{versionId}/relationships/build
build id: {buildId}
204 NO CONTENT
Key points:
204 NO CONTENTmeans the relationship updated with no resource body.- This response confirms both build id and version id are valid.
- After metadata and build are ready, the version can be submitted for review.
(21:00) App Review still needs contact info, demo account, notes, and attachments when required. The API maps these to App Review Details, App Review Attachments, and App Store Version Submission.
POST /v1/appReviewDetails
version relationship: {versionId}
POST /v1/appStoreVersionSubmissions
version relationship: {versionId}
DELETE /v1/appStoreVersionSubmissions/{submissionId}
Key points:
- Review details can be PATCHed multiple times before actual submission.
- Creating App Store Version Submission equals clicking Submit for Review.
- Delete the submission to withdraw; missing screenshots or other requirements yield
400with error details on create.
Reading Power and Performance metrics and diagnostics
(23:21) The Power and Performance API reads aggregated data behind the Xcode Power and Performance view. Entry can be by app or by build.
GET /v1/apps/{appId}/perfPowerMetrics
Accept: <Power and Performance custom media type>
GET /v1/builds/{buildId}/perfPowerMetrics
Accept: <Power and Performance custom media type>
Key points:
- Read recent-version metrics from the app’s
perfPowerMetricsrelationship. - Read a specific build’s metrics from the build’s
perfPowerMetricsrelationship. - The transcript mentions HANG metrics in the response; hang rate is in seconds per hour.
(24:09) Disk writes also have diagnostic signatures and log data that push from “writes increased” to specific call stacks.
GET /v1/builds/{buildId}/diagnosticSignatures
response data:
signature
weight
log data relationship
GET {log data relationship URL}
Accept: <Power and Performance custom media type>
Key points:
- Diagnostic signatures sort by contribution to total disk writes; largest contributors first.
signatureidentifies the runtime write location;weightis its share of total writes.- Log data responses include app info, total disk writes, and detailed call stacks for root-cause analysis.
Core Takeaways
-
What to do: Bring release draft creation into CI. Why it’s worth it: The demo chain from app id lookup through version creation, build association, and App Review submission fits turning “prepare release” from web clicks into auditable scripts. How to start: Implement
GET /v1/apps?filter[bundleID]=...andPOST /v1/appStoreVersions, logging the returned{versionId}in your release pipeline. -
What to do: Build a price promotion scheduling script. Why it’s worth it: Price schedules can update atomically in one PATCH, avoiding half-created price nodes. How to start: Read
/v1/apps/{appId}/prices?include=priceTier, then generate the full promotion cycle with temporary IDs${new-price-*}; add environment guards so test payloads never run against live apps. -
What to do: Sync multilingual metadata from your repository to App Store Connect. Why it’s worth it: App Info Localizations and App Store Version Localizations cover name, subtitle, privacy policy, screenshots, keywords, and promotional text—suitable for code review with localization files. How to start: Read version localizations per locale; sync name and keywords for one market first, then add screenshots and preview sets after review flow is verified.
-
What to do: Implement a resumable asset upload worker. Why it’s worth it: App previews, screenshots, App Review attachments, and GeoJSON routing app coverage files all use reservation, part upload, commit, and error check. How to start: Turn upload operations into a task queue by
offsetandlength; retry only failed parts; after commit pollstateand log the errors array onFAILED. -
What to do: Pipe production performance metrics into your team dashboard. Why it’s worth it:
perfPowerMetricsanddiagnosticSignaturesput Xcode Organizer aggregated data in custom tools—hang rate, disk writes, and call stacks can feed regression alerts. How to start: Pull recent-version trends from app-levelperfPowerMetrics, then requestdiagnosticSignaturesand log data for anomalous builds and attachsignature,weight, and call stacks to tickets.
Related Sessions
- Identify trends with the Power and Performance API — Deep dive on
perfPowerMetrics, diagnostic signatures, and log data, continuing this session’s performance API overview. - Diagnose performance issues with the Xcode Organizer — Xcode Organizer view of the same aggregated performance data to understand how API data appears in tools.
- What’s new in App Store Connect — 2020 App Store Connect improvements including this API, in-app purchase, subscriptions, and Game Center.
- Introducing StoreKit Testing in Xcode — Local StoreKit testing environment to pair with automated release flows and purchase testing.
- What’s new with in-app purchase — In-app purchase, refunds, server notifications, and StoreKit updates; this session notes IAP configuration remains web-based.
Comments
GitHub Issues · utterances