Setting up the App Store Connect API key: a 5-minute guide
A practical walkthrough for creating and configuring App Store Connect API keys — covering roles, secure storage, rotation, and the gotchas that trip up most developers the first time.
The App Store Connect API authenticates every request with a short-lived JSON Web Token. To generate a valid token you need exactly three things: an Issuer ID, a Key ID, and a private key file (ending in .p8). None of those three can be retrieved after the fact — you either have them or you start over. This guide walks through getting all three in under five minutes, choosing the right access role, and storing the key securely enough that you won't lose sleep over it.
If you're building automation on top of the API — automated pricing workflows, metadata pipelines, TestFlight distribution — this setup step is the non-negotiable foundation. Once the key is in hand, our JWT authentication walkthrough covers exactly how to sign tokens with it, and our App Store Connect automation overview shows what you can build once auth is working.
Who can create API keys
Apple restricts API key creation to accounts with the Account Holder role — the person who originally accepted the Apple Developer Program license agreement — or to users granted the Admin role by the Account Holder. If you're a solo developer, that's almost certainly you. If you're at a company, it's whoever set up the developer account.
There are two types of keys in the App Store Connect API:
- Team keys — scoped to your entire organization, can access all apps under the team. This is what most automation use cases require.
- Individual keys — tied to a specific user account and limited to that user's assigned role. Useful for delegating narrow access without granting team-wide permissions.
For pricing automation, metadata management, and sales reporting — the most common automation workloads — team keys are the right choice. The rest of this guide focuses on team keys.
Role check before you start: Log in to App Store Connect and navigate to Users and Access. If you don't see an "Integrations" tab in the left sidebar, your account does not have Account Holder or Admin privileges. You'll need to ask whoever manages the team account to either create the key for you or grant you the Admin role first.
Creating the key: step by step
Step 1: Navigate to the API keys page. In App Store Connect, click your profile avatar in the top-right corner and select "Users and Access." In the left sidebar, under the Integrations heading, click "App Store Connect API." You'll land on a page showing any existing keys alongside two values you'll need later: the Issuer ID (a UUID at the top of the page, shared across all keys on your team) and a list of generated keys each showing its Key ID.
Step 2: Generate a new API key. Click the "+" button. You'll see a dialog asking for two things: a human-readable name for the key (something like pricing-automation or ci-pipeline — this is only for your reference in the UI) and an access level. See the role comparison table in the next section before choosing.
Step 3: Download the .p8 file — immediately. After clicking Generate, App Store Connect shows a "Download API Key" button. Click it before closing the dialog or navigating away. This is the only time Apple presents the download option.
Step 4: Record your Key ID and Issuer ID. The Key ID (a 10-character alphanumeric string like 2X9R4QWVK6) appears in the key list after generation. The Issuer ID is the UUID at the top of the page. Write both down somewhere safe — you'll need them as constants in every JWT you generate.
Choosing the right access role
Picking the minimum role your use case requires is important. If a key is ever compromised, a least-privilege role limits what an attacker can do. Apple's role definitions map to specific API endpoint groups:
| Role | Pricing & IAPs | App metadata & screenshots | Sales & finance reports | Certificates & provisioning |
|---|---|---|---|---|
| Admin | ✓ | ✓ | ✓ | ✓ |
| App Manager | ✓ | ✓ | ✗ | ✗ |
| Developer | ✗ | Limited (read-only on some resources) | ✗ | ✓ |
| Finance | ✗ | ✗ | Full financial reports | ✗ |
| Sales | ✗ | ✗ | Sales reports only | ✗ |
| Marketing | ✗ | Read-only | ✗ | ✗ |
| Customer Support | ✗ | ✗ | ✗ | ✗ |
For pricing and localization automation — updating prices across territories, editing subscription product metadata, reading your list of in-app purchases — App Manager is the recommended minimum role. It gives you write access to pricing and metadata without also granting access to financial data or certificate management, neither of which an automation script typically needs.
For read-only analytics pipelines pulling sales figures, use Sales or Finance depending on whether you need unit counts or revenue data. These roles cannot modify anything in your app listing, making them safe choices for a reporting tool.
Avoid Admin for automated keys. The Admin role is appropriate for a key that a trusted human uses interactively, not for a service account running in CI or on a server. If something goes wrong with an Admin-keyed script — a bug that calls the wrong endpoint, a compromised environment variable — the potential damage is much larger than it needs to be.
Storing the .p8 key securely
The .p8 file is an Elliptic Curve private key in PEM format. Anyone who possesses this file plus your Key ID and Issuer ID can make authenticated API calls on behalf of your team — including changing subscription prices across all 175 storefronts, modifying app metadata, or revoking other API keys. Treat it with the same care as an AWS root key or a production database password.
Three practical storage approaches, ranked by security:
Secret manager (recommended for production). Store the .p8 contents as a secret in AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, or HashiCorp Vault. Your application fetches the secret at runtime and decodes it to a temp file or directly into your JWT library. The private key material never lives on disk in production and is auditable via access logs.
CI/CD environment variable (acceptable for automation pipelines). Base64-encode the file contents — base64 -i AuthKey_XXXXXXXX.p8 | tr -d '\n' — and store the output as an environment secret in GitHub Actions, CircleCI, Bitrise, or whatever CI provider you use. Decode it at runtime: echo "$ASC_PRIVATE_KEY" | base64 --decode > /tmp/AuthKey.p8. Most CI providers encrypt environment secrets at rest and mask them in log output.
Encrypted local file (acceptable for developer machines). If you need the key on a local workstation for development scripts, encrypt it with GPG symmetric encryption (gpg --symmetric AuthKey_XXXXXXXX.p8) and store the .p8.gpg file. Decrypt it in your shell session when needed. Never leave the plaintext .p8 file in a location that might sync to cloud storage.
Never commit the raw .p8 file to a git repository — even a private one. Repository access controls change, forks happen, and git history is effectively permanent. Secret scanning tools like GitHub's push protection and Gitleaks can detect .p8 files in commits, but prevention is better than remediation. A leaked key requires immediate revocation and re-keying every system that uses it.
Revoking, rotating, and managing multiple keys
App Store Connect API keys do not expire automatically. That's convenient for automation but creates a security responsibility: keys need to be managed, not just created and forgotten.
To revoke a key, return to Users and Access → Integrations → App Store Connect API, locate the key by name or Key ID, and click "Revoke." Revocation takes effect immediately — any JWT signed with that key becomes invalid within seconds. If you're rotating a key (replacing an old one with a new one), generate the new key first, update all the places that use it, verify everything works, then revoke the old key. Doing it in the wrong order causes outages.
Situations that should trigger a proactive rotation:
- A team member with access to the .p8 file or to the environment it's stored in leaves the organization
- A server, CI provider, or secret store is decommissioned or experiences a suspected breach
- You shared the key temporarily for debugging and want to retire the shared copy
- Your security policy calls for annual rotation of machine credentials
Apple allows up to 50 active keys per team at any time. That's enough headroom to issue a separate key per integration — one for CI, one for the pricing automation job, one for an analytics pipeline — without needing to share credentials between systems. Separate keys mean you can revoke one service's access without disrupting others, and audit logs are cleaner because each key's activity is attributable to a specific integration.
Common mistakes and how to avoid them
Missing the download window. The most frequent support question around App Store Connect API keys: "I didn't download it and now the button is gone." There is no recovery path. Revoke the key, generate a new one, and don't close the dialog until the file is safely on disk.
Confusing Key ID with the key name. The name you give a key at creation time is a human-readable label that only appears in the App Store Connect UI. It is not the Key ID. The Key ID is the 10-character alphanumeric code that goes into the kid field of your JWT header. These are two different things, and using the name where the ID belongs will produce authentication failures.
Using the wrong Issuer ID. The Issuer ID is a team-level UUID that is the same for all keys on your account. It is not the same as your Apple Team ID (used for code signing), your App ID, or your developer account email. If your JWTs are consistently returning 401 Unauthorized errors despite a valid key, verify the Issuer ID against what's shown on the API keys page — it's the most common source of persistent auth failures.
Omitting the audience claim. The App Store Connect API requires the JWT aud claim to be set to the string appstoreconnect-v1. Generic JWT libraries don't set this by default, and Apple's error messages for a missing or wrong audience claim can be opaque. Our JWT walkthrough covers the exact payload structure Apple expects.
Giving the key Admin access "just in case." Admin keys can do everything, including modifying other team members' roles, revoking other API keys, and accessing all financial data. Reserve Admin for keys that explicitly need full access, and default to App Manager for everything else.
Where to go from here
With a .p8 file, Key ID, and Issuer ID secured, you have everything needed to start building against the App Store Connect API. The logical next steps:
- Authenticate. Generate a signed JWT using the key — our JWT authentication walkthrough covers the exact header, payload, and signing process in Python and Node.
- Audit your territory pricing. The Price Points and Territories endpoints let you pull your current prices and conversion rates across all storefronts. Our territories tool visualizes how your price tiers map to local currencies and purchasing power.
- Automate price updates. Once authentication is working, the Subscription Price Schedule endpoints let you set future price changes programmatically. Our pricing dashboard shows the territory-level impact before you commit to a change.
The key setup itself is five minutes of work. The automation it unlocks — pulling sales data, updating prices across territories, syncing metadata — is where the hours compound.
Sources and further reading
- Apple Developer Documentation: App Store Connect API overview
- Apple Developer Documentation: Generating Tokens for API Requests
- App Store Connect Help: API Keys
- App Store Connect Help: Role Permissions reference
- RevenueCat Engineering Blog — App Store Connect API integration guides
Share this post
Ready to put this into practice?
appsops.store gives you PPP-adjusted pricing across all 175+ App Store territories, App Store Connect API automation, and 39-language localization — all from one dashboard.
Start free →