Articles · App ExamplesUpdated September 2026

The App Store Connect API is a REST API you authenticate with a token you sign yourself.

The App Store Connect API puts your account behind JSON: apps, builds, TestFlight testers, versions, certificates, profiles and sales reports. There is no password in it anywhere. Every request carries a JSON Web Token that your code signs with a private key Apple hands you exactly once. That single decision is why the first hour of work here goes on authentication rather than on the thing you came to do, which is usually some part of publishing to the App Store.

This page covers how the token is built and how long Apple lets it live, what the key role decides, which parts of App Store Connect the REST API actually reaches, and what breaks the first time the same script runs unattended at three in the morning.

Check whether a token lifetime is legal

The short version

The key is a file you can download once, and the token it signs expires in minutes.

Two objects do all the work. A private key, a .p8 file you download from App Store Connect a single time, and a short lived token you mint from it. The key is the long term secret. The token is not a credential you store anywhere, it is a signature over a handful of claims with an expiry attached.

Almost every problem people hit when they try to automate App Store Connect is one of those two things: a key with the wrong role, or a token that lived too long. Both have exact answers in Apple's own documentation, and both are cheap to get right on day one and expensive to fix later.

How the token is built, and how long it lives

Authentication is ES256 the whole way down. Apple states that all JWTs for the App Store Connect API must be signed with ES256, using the private key that matches the key ID you name in the header. The header itself carries three fields and nothing else: alg set to ES256, kid set to your private key ID, and typ set to JWT.

The payload depends on which kind of key signed it. A team key uses iss, the issuer ID from the API Keys page, together with iat, exp and aud set to appstoreconnect-v1. An individual key does not use iss at all. Apple documents that individual keys instead require the sub key, and that its value is always user. An optional scope claim narrows the token to a list of operations, written out as method and path, for example GET /v1/apps with a platform filter.

Lifetime is where most first attempts fail. App Store Connect works out the lifetime of a token by subtracting the iat claim from the exp claim, and Apple documents that for most requests it rejects a token with a lifetime greater than 20 minutes. There is one documented exception: a token whose scope contains only GET requests, on resources that allow long lived tokens, may have a lifetime of up to six months. Apple also advises picking the shortest lifetime that does the job, and offers two minutes as an appropriate lifetime for a one off request.

Once signed, the token travels in an Authorization header as a bearer token, on every single call. There is no session, no refresh token and no cookie to keep warm. Because iat and exp are absolute Unix times, a machine with a badly wrong clock will happily mint tokens that were never inside the window.

Apple, generating tokens for API requests

Try it

Will App Store Connect accept this token

A token lifetime is exp minus iat. Apple checks it on every request, and the ceiling depends on what the scope claim allows.

Accepted

exp is iat plus 1200 seconds, and the ceiling here is 20 minutes. Apple still advises the shortest lifetime that does the job, and gives two minutes as an appropriate lifetime for a one off request.

The key carries a role, and the role is the blast radius

You create an App Store Connect API key in App Store Connect under Users and Access, in the Integrations tab. Apple documents two kinds. A team key gives access to all apps, with varying levels of access based on the selected roles, and you need an Admin account to generate one. An individual key carries the access and roles of the user it belongs to, and Apple says plainly that individual keys are not able to use Provisioning endpoints, access Sales and Finance, or use notaryTool. If your script touches certificates or profiles, that sentence decides which key you need.

The role is not paperwork. Apple documents that when you create a key you assign it a role that determines the key access to areas of the API and its permissions for performing tasks, and that the roles which apply to keys are the same roles that apply to users on your team. A key with the Admin role has broad permissions and can do things like create new users and delete users. A nightly job that adds a tester to a beta group has no business holding that.

Then the detail that catches teams out: the private key is available for download a single time. The download link only appears while you have not yet downloaded it, and Apple keeps no copy. Secure it the way you would a password, and if you think it has leaked, revoke the key in App Store Connect straight away. Three values together are the whole credential: the issuer ID, the key ID, and the .p8 file itself.

Apple, creating API keys to authorize API requests

What the REST API reaches, and where it stops

The App Store Connect REST API is laid out much like the website. App Store covers apps, App Clips, in-app purchases and customer reviews. TestFlight covers prerelease versions, beta testers and beta groups. Provisioning covers bundle IDs, capabilities, certificates, devices and profiles. Reporting covers sales, finance and analytics. There is also Game Center, Xcode Cloud, webhooks, users and access, and alternative distribution. Responses come back as JSON carrying links to related resources, so you follow relationships instead of guessing at URLs.

TestFlight is the usual reason people start. Creating a beta group, adding testers, attaching a build and editing what those testers see are all ordinary calls, and the ios testflight guide covers what that same flow looks like from the store side rather than from a script.

Where it stops is the binary. Apple does not document an endpoint that accepts an .ipa. The upload operations in the API are for assets: screenshots, app previews, App Review attachments, routing coverage files. The build itself goes up through Xcode or Apple's Transporter app, and only once it has arrived does a build record exist for your code to act on. Plan the automation around that boundary and it stays simple.

Rate limits are per key and reported in an X-Rate-Limit response header, which names the hourly limit and how much of it is left, counted over a rolling hour. Go past it and you get a 429 with the error code RATE_LIMIT_EXCEEDED. Apple notes that actual limits can vary, so read the header rather than hard coding a number you saw in a blog post. If writing the HTTP client yourself is not the point, the app store connect cli route wraps most of this already.

What breaks when nobody is watching

Code that works on a laptop fails in CI for a short list of reasons, and they are nearly all about the key. The .p8 belongs in the secret store, never in the repository, and most CI systems want it base64 encoded to survive life as an environment variable. Write it to a temporary file at the start of the job, read it, delete it at the end, and never log it.

Mint the token inside the job, not before it. A twenty minute ceiling means a token created by an earlier step, or cached between runs, can expire in the middle of a long wait for processing to finish. Generate it at the point of use and generate a fresh one on retry. Then treat the failures as three different problems: a 401 is usually the token, a 403 is usually the role, and a 429 is the rate limit telling you to slow down.

It is also worth deciding early what this automation is for. Moving metadata, testers and release state is what the API does well. Producing the build that gets uploaded is a separate pipeline with its own signing and its own failure modes, and folding both into one script is how a team ends up with a job nobody can debug at release time.

What each way in actually gives you

ApproachRuns unattendedWho signs the JWTReaches provisioningReaches sales and finance
Signing in to App Store Connect by handNonobody, it is a loginYesYes
Team key, JWT your code signsYesyour code, per runYesYes
Individual key, JWT your code signsYesyour code, per runNoNo
A CLI wrapper such as fastlaneYesthe tool, from your p8Yespartly
Hosted CI holding the key for youYesthe service, from a stored secretvariesvaries

Building this into something the team can run

A first version is small. Sign a token, call three endpoints, print what changed. What grows is everything around the call: somebody has to hold the .p8, somebody has to decide which role the key gets, somebody has to notice that a 403 last Tuesday meant a permission changed rather than a bug appeared. Off-the-shelf wrappers cover the common path and stop at the first thing your team does differently, which is usually a release checklist that has to pass before a version state is allowed to move.

Newly is an AI app builder: you describe an app in plain English and it writes a real React Native and Expo project you own, runs it on a cloud iPhone or Android simulator while it builds, and uploads iOS builds to TestFlight through App Store Connect using your own Apple Developer account. The Deploy tab has an Android section too, where one press builds, signs and uploads the app to Google Play internal testing, and it also builds a standalone release APK you can download and install on a phone directly. Plans start at $25 a month and there is no free plan. The published documentation does not describe handing it an App Store Connect API key, so treat any API automation you write as your own, sitting next to the build rather than inside it. The code is yours to take: npm i -g @newly/cli, then newly pull with your project id.

For most teams the honest split is this. Use the API for the parts that are genuinely repetitive, such as inviting testers, rotating what a build tells them, and pulling reports. Leave the parts that need a human decision, such as submitting for review, exactly where they are.

Questions developers ask about the App Store Connect API

It is Apple's REST API for the things you would otherwise do by clicking around App Store Connect: managing apps and app metadata, TestFlight builds and beta testers, App Store versions, provisioning certificates, profiles and devices, users, and sales and finance reports. Responses are JSON and include links to related resources, so you follow relationships rather than assembling URLs by hand.

Ship the app all this automation is about

Describe the app you want, get a real React Native project you own, and have the build and the TestFlight upload handled while you wire up the rest.

Start building