Generate an API key in App Store Connect under Users and Access > Integrations > App Store Connect API; download the .p8 private key file (it can only be downloaded once).
Construct a JWT: header {alg: ES256, kid: YOUR_KEY_ID}, payload {iss: YOUR_ISSUER_ID, iat: now, exp: now+1200, aud: appstoreconnect-v1}; sign with the .p8 private key using ES256.
Include the JWT in API requests as Authorization: Bearer {token}; tokens are valid for up to 20 minutes and must be regenerated after expiry.
List builds for an app via GET https://api.appstoreconnect.apple.com/v1/builds with filter[app] and filter[processingState]=VALID to find processed builds.
Add a build to TestFlight internal testing by POSTing to https://api.appstoreconnect.apple.com/v1/betaAppReviewSubmissions or by assigning the build to a beta group via the betaGroups relationship endpoint.
Submit for external TestFlight review if needed via POST https://api.appstoreconnect.apple.com/v1/betaAppReviewSubmissions with a relationship to the target build.
Known gotchas
The .p8 private key file cannot be re-downloaded after the initial download — if lost, the API key must be revoked and a new one generated, invalidating any existing integrations using the old key.
JWT expiry is hard-capped at 20 minutes; requests made with a token older than 20 minutes receive a 401, so token generation must be automated in long-running processes.
Builds must finish Apple's processing (which can take 10-30+ minutes after upload) before they can be added to TestFlight groups; polling the processingState field is required before attempting group assignment.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp