App Store Connect API key: create one, pick a role, keep the .p8 safe
An App Store Connect API key is a .p8 private key with a Key ID; together with your team's Issuer ID, it signs the short-lived tokens that Apple's App Store Connect API requires. You create it under Users and Access > Integrations > App Store Connect API, and Apple lets you download the .p8 only once.
A team key is made by the Account Holder or an Admin, covers every app in the account and carries one role you pick. An individual key inherits one user's roles and app access. Before anyone can make either, the Account Holder has to request API access, and Apple approves those requests case by case. The key never travels to Apple: your tool signs a token with it, valid for 20 minutes at most on most requests.
By Redjan Hysa, founder of MetaRun · Facts checked October 12, 2026
- per .p8 private key; Apple keeps no copy
- 1 download
- maximum token lifetime for most API requests
- 20 minutes
- the only signing algorithm Apple accepts for these tokens
- ES256
- active individual key per user at a time
- 1
- revoked keys stay listed under Revoked
- 30 days
- the only role that can request API access
- Account Holder
Reference tables
| Value | Example | Where to find it | Where it goes |
|---|---|---|---|
| Issuer ID | 57246542-96fe-1a63-e053-0824d011072a | Users and Access > Integrations > App Store Connect API, near the top, with a Copy button | The token's iss claim. Team keys only. |
| Key ID | 2X9R4HXF34 | The Active list on the same page: hover the ID, then Copy Key ID. Individual keys show it on your profile. | The token header's kid field |
| Private key | AuthKey_2X9R4HXF34.p8 | The Download API Key link next to the new key, shown until the first download | Signs the token. Never sent to Apple. |
The ID values are the placeholders from Apple's token documentation. The downloaded file name carries the Key ID, handy when you've lost track of which file belongs to which key.
| Team key | Individual key | |
|---|---|---|
| Who can create it | Account Holder or Admin | Account Holder, Admin, App Manager, Customer Support, Developer or Marketing, if an Admin hasn't removed their permission |
| App access | Every app in the account; can't be limited | The apps that user can access |
| Role | Picked at creation, can't be edited | The user's own roles |
| How many | Multiple, each with its own role | One active key per user |
| Token payload | iss set to your Issuer ID | sub set to "user", no iss |
| Off limits | Whatever its role can't do | Provisioning endpoints, Sales and Finance, notaryTool |
| Where it lives | Integrations > App Store Connect API > Team Keys | Your profile, under Individual API Key |
| Role | Can do | Can't do |
|---|---|---|
| Admin | Nearly everything: users, API keys, apps, submissions, pricing, review replies, analytics, sales and finance | Sign agreements, transfer apps, create Developer ID certificates, remove subscriptions from sale |
| App Manager | Apps and versions, App Store details, pricing, in-app purchases, subscription pricing, TestFlight, submit for review | Reply to customer reviews, view analytics, sales or finance, generate API keys |
| Developer | Upload builds, internal TestFlight groups, create in-app purchases, view reviews, notarize | Submit apps, create versions, edit App Store details |
| Marketing | Versions, App Store details, in-app events, promo codes, featuring nominations | Submit apps; pricing is read-only |
| Finance | Analytics, Sales and Trends, payments and financial reports | Edit apps, listings or builds |
| Sales | Analytics and Sales and Trends | Financial reports, editing apps |
| Customer Support | Reply to customer reviews, edit App Store details | Submit apps, pricing, TestFlight |
From Apple's role permissions table, which describes users; Apple says keys take the same roles. Some cells depend on extra per-user access (Certificates, Identifiers & Profiles, reports), so test the calls your tool makes before relying on a narrow role.
How to create an App Store Connect API key
A team key needs the Account Holder or Admin role. The last step covers individual keys.
- 01
Request access (first time only)
If the App Store Connect API page shows Request Access, the Account Holder clicks it, accepts the terms and clicks Submit. Nobody can generate keys until Apple approves it.
- 02
Generate the key
In Users and Access, click Integrations, then Team Keys. Click Generate API Key (or the add button if a key exists), name it after where it will live, such as "GitHub Actions upload", pick the role under Access and click Generate. The name and role can't be changed later.
- 03
Download the .p8 straight away
Click Download API Key. The link disappears after one download, so move the file into your password manager or secret store now.
- 04
Copy the Key ID and Issuer ID
Hover the key's ID in the Active list and click Copy Key ID. The Issuer ID sits near the top of the page with its own Copy button.
- 05
Test it
Sign a token and call GET https://api.appstoreconnect.apple.com/v1/apps. A 200 means the key, both IDs and your clock are right.
- 06
Or make an individual key
Click your username at the top right, then Edit Profile. Under Individual API Key, click Generate Key, then Download. There's no Issuer ID to copy.
Which role to give the key
A team key reaches every app in the account and its role is fixed, so give it the narrowest role that covers your tool's calls and use one key per job. For release work (uploads, TestFlight, the listing, pricing, submitting for review), App Manager is the usual pick and what CI services such as Codemagic ask for. Replying to reviews needs Admin or Customer Support. Financial reports need Finance or Admin on a team key. In our testing, Apple's one-time analytics report request needed Admin.
How the key becomes a token
Your tool signs a JWT with the .p8. Header: alg ES256, kid set to the Key ID, typ JWT. Payload: iss set to the Issuer ID (sub set to "user" for an individual key), iat and exp in Unix seconds, aud set to appstoreconnect-v1. It goes in an Authorization: Bearer header.
Apple computes lifetime as exp minus iat and rejects anything over 20 minutes for most requests. Tokens with a scope claim listing only GET requests on certain resources, mostly Xcode Cloud ones, may live up to six months. Reuse a token until it expires. Rate limits apply per key over a rolling hour, reported in the X-Rate-Limit header of every response.
Where to keep the .p8
Apple's guidance: don't share it, don't store it in a code repository, don't put it in client-side code. Add *.p8 to .gitignore before the file lands in a project, along with configs that embed it, such as fastlane's JSON key file or asc's repo-local .asc folder. Locally, use a password manager or the keychain. In CI, use the provider's secret store and write the key to a temporary file at job start; base64-encode it if your secret store mangles line breaks.
Revoking and rotating a key
To revoke, open Integrations > App Store Connect API, choose Team Keys or Individual Keys, click Edit, select the keys, click Revoke Key and confirm. It's permanent. Apple doesn't document an expiry date for keys, so rotation is on you: generate the new key, roll it out, confirm a call works, then revoke the old one. That's also the only way to change a key's role.
How fastlane, EAS submit, asc and hosted tools use the key
fastlane reads a JSON file with key_id, issuer_id and key (the .p8 contents), plus optional duration (maximum 1200 seconds), passed as api_key_path; the app_store_connect_api_key action takes the same values, with issuer_id left empty for an individual key. Expo EAS submit can create and store a key through eas credentials, or use your own via ascApiKeyPath, ascApiKeyIssuerId and ascApiKeyId in eas.json. The open-source asc CLI takes asc auth login --key-id, --issuer-id and --private-key and saves the profile in the keychain.
A hosted tool has to hold the key server-side, so ask how. MetaRun takes it once over TLS, checks it against Apple, and stores it envelope-encrypted: a fresh AES-256-GCM data key encrypts the .p8, that data key is wrapped by a key held in Supabase Vault, and decryption happens only in server memory when a request needs it. Details at metarun.dev/security.
Common problems and how to fix them
401 NOT_AUTHORIZED: "Authentication credentials are missing or invalid."
Why: Apple couldn't verify the token: an Issuer ID from another team, a Key ID that doesn't match the signing .p8, exp more than 20 minutes after iat, an expired token (often a CI clock that's minutes off), the wrong aud, or an individual key sent with iss instead of sub "user".
Fix: Decode the token locally and check each claim. Keep lifetimes well under 20 minutes, sync the machine clock, and re-copy both IDs. If the .p8 comes from an environment variable, check its line breaks survived.
403 FORBIDDEN_ERROR on a call the key should be able to make
Why: The request is valid, but the key's role doesn't allow it or it's outside what individual keys can reach. Apple also lists a revoked key or a malformed token among 403 causes.
Fix: Check the role table. Roles can't be edited, so generate a key with the right role and revoke the old one.
403 FORBIDDEN.REQUIRED_AGREEMENTS_MISSING_OR_EXPIRED: "A required agreement is missing or has expired."
Why: An updated agreement is waiting. Apple requires the Account Holder to accept updated terms to keep full API access.
Fix: The Account Holder signs in and accepts it. The key needs no change.
App Store Connect API keys tab missing, or no Generate API Key button
Why: Older guides, including Apple's revoke page, say "Keys tab", but keys now live under Users and Access > Integrations. If that page shows Request Access, nobody has requested API access yet. Team keys need Account Holder or Admin. The profile button disappears when an Admin removed your Generate Individual API Keys permission or your only role is Finance or Sales.
Fix: Look under Integrations. Ask the Account Holder to request access, or ask an Admin to create a team key or restore your permission (People > your name > Additional Resources).
Lost the .p8, or the Download API Key link is gone
Why: The private key downloads once and Apple keeps no copy, so nobody can send it again.
Fix: Generate a new key with the same role, update every tool, then revoke the old one. If the file may have leaked, revoke first.
Frequently asked questions
What is the App Store Connect API key ID?
The short identifier Apple gives each key, such as 2X9R4HXF34. It goes in the token header's kid field. Copy it from Integrations > App Store Connect API, or read it off the file name, AuthKey_2X9R4HXF34.p8.
Where do I find the App Store Connect Issuer ID?
In Users and Access > Integrations > App Store Connect API, near the top of the page, next to a Copy button. It identifies your team and goes in every team key token's iss claim. Individual keys don't use it.
Can I download the .p8 again?
No. Apple keeps no copy and the download link vanishes after the first download. Generate a new key, switch your tools over, then revoke the old one.
Do App Store Connect API keys expire?
Apple documents no expiry for the key; it works until revoked. The token you sign with it expires, after 20 minutes at most for most requests. If an old setup suddenly fails, check for an expired token, a revoked key or an unsigned agreement.
Individual vs team API key: which should I use for CI?
A team key. It survives people leaving, each pipeline can get its own key and role, and fastlane recommends one because provisioning access (match, cert, sigh) requires it.
What role does an App Store Connect API key need for fastlane or EAS submit?
App Manager covers uploading builds, TestFlight and submitting, and it's what CI services such as Codemagic ask for. Admin also works but gives a leaked key the most reach.
What kind of key does MetaRun need?
A team key. Admin covers everything, including review replies and Apple's search analytics; App Manager covers releases, listings and pricing. You upload it once in Settings, it's stored encrypted server-side and never sent back to the browser.
Sources
- Apple: App Store Connect API (request access, team and individual keys)
- Apple: Creating API keys for App Store Connect API
- Apple: Generating tokens for API requests
- Apple: Revoking API keys
- Apple: Role permissions
- Apple: Roles and access (permission tables)
- Apple: About the HTTP status code
- Apple: Parsing the error response code
- Apple: Identifying rate limits
- Apple Developer Forums: required agreement missing or expired (403)
- fastlane: Using App Store Connect API
- fastlane: app_store_connect_api_key action
- Expo: Submit to the Apple App Store
- Codemagic: App Store Connect publishing
- App Store Connect CLI (asc) on GitHub
Related guides
Guide
The pre-submission checklist, every review status, export compliance, rejections and expedites.
Guide
Internal vs external testers, Beta App Review, public links, and every reason testers see no builds.
Guide
Respond to App Store reviews: who can reply, editing and deleting, Apple's rules and reply templates.
Guide
The 7-day percentage schedule, the 30-day pause budget, and what to do when a bad build is rolling out.
All guides
Releases, TestFlight, pricing, subscriptions, localization, screenshots and more.
With MetaRun: Use the key from an AI agent over MCP
MetaRun
Do this from your AI agent or MetaRun's dashboard, with a preview before every change. 14-day free trial, no card.