Getting an App Store Connect API key
The API key lives under App Store Connect → Users and Access → Integrations → App Store Connect API, at appstoreconnect.apple.com/access/integrations/api. Only an Account Holder or an Admin user can mint a Team Key. Each key you generate gives you three artifacts:
- An Issuer ID — a UUID that identifies your Apple Developer team. Shown at the top of the Integrations page once you have at least one key.
- A Key ID — a 10-character alphanumeric string unique to each key. Shown in the table once the key is created.
- A .p8 private key file — a PEM-encoded EC P-256 private key downloadable exactly once at creation time. If you lose it, you must revoke the key and create a new one.
The three access roles
- Admin. Full read/write. Can edit users, agreements, pricing, everything. Overkill for build upload and metadata tooling.
- App Manager. Can edit apps, create versions, upload builds, edit metadata, submit for review — but cannot manage users or sign agreements. This is what most CI pipelines and metadata tools should use.
- Developer. Limited to uploading builds via Xcode or altool. No metadata access.
Apple also supports Individual Keys (scoped to a single user's permissions) and Limited Access Keys (scoped to a specific app or set of apps). For third-party tools that manage multiple apps, a Team Key with the App Manager role is the standard choice.
How JWT auth works — conceptually
Apple uses standard ES256 JWT authentication. For every API call you construct a JSON Web Token with:
- Header:
alg: ES256,kid:your Key ID,typ: JWT. - Payload:
iss:your Issuer ID,exp:a Unix timestamp at most 20 minutes in the future,aud:appstoreconnect-v1, andscope:optional endpoint scoping. - Signature: ES256 over the header.payload using the private key from your .p8.
The resulting token goes in the Authorization: Bearer <token>
header on each HTTPS request to
https://api.appstoreconnect.apple.com/v1/. Apple recommends reusing the
same token for all calls within its 20-minute lifetime rather than regenerating per
request.
Common validation errors and what they mean
- 401 NOT_AUTHORIZED. Issuer ID typo (trailing whitespace is a
classic), wrong Key ID in the JWT header, expired
expclaim, or the key was revoked. - 403 FORBIDDEN. Key role does not have permission for the endpoint. App Manager cannot read some billing endpoints, Developer cannot touch metadata endpoints.
- Invalid PEM. The .p8 file was copied with extra whitespace or
line endings. It must start with
-----BEGIN PRIVATE KEY-----, end with-----END PRIVATE KEY-----, and contain base64-encoded content in between. - "Could not find key with ID". The Key ID in your JWT header does not match the Key ID Apple knows for that issuer. Re-check against the Integrations page.
Tip: AppConsul stores App Store Connect API keys in the macOS Keychain with per-team separation, signs ES256 JWTs locally, and calls Apple's API directly — no relay servers, no keys leaving your Mac. See AppConsul →
Frequently asked questions
Is my API key uploaded anywhere when I use this tool?
No. All checks run locally. You can verify by opening browser DevTools Network tab and observing that pasting or validating triggers no requests.
What are the three roles for App Store Connect API keys?
Admin (full), App Manager (app editing + builds, no users), Developer (build upload only). App Manager is the right role for metadata and build tooling.
How does JWT auth with the App Store Connect API work?
ES256-signed JWTs with issuer ID as iss, key ID in the header's
kid, 20-minute max expiry, placed in the
Authorization: Bearer header.
What does "NOT_AUTHORIZED" error from the API mean?
Issuer typo, wrong Key ID in the JWT header, expired token, or revoked key. Regenerate and match the values from the Integrations page exactly.
Don't want to sign JWTs yourself? Use AppConsul.
AppConsul handles App Store Connect API authentication, key rotation, and direct API calls in a native macOS app. Keys stay in Keychain, never touch a server.
See AppConsul →