If you're developing for the App Store, you'll eventually need to generate an app store connect api key.

You might need it for your personal use, or an app that you're using might need it (EAS, RevenueCat, ...)

I for example use the connect api to automate expo app release to TestFlight from GitHub CI pipeline or EAS build.

If you're not yet enrolled into Apple Developer program, but want to be, read my instructions on joining. It will save you some time.

Avoid the Mobile Web View

When accessing the App Store Connect keys table via Chrome from the smartphone or from the responsive view from Chrome, only the first column is visible and interactable. That's going to be a problem, since the key id and private key are in other columns. I reported this issue to Apple, so depending when you read this article and if they fix it, this might not apply.

Steps to generate App Store Connect API key

  • Login to https://appstoreconnect.apple.com
  • Go to Users and Access
  • Go to Integrations and find App Store Connect API
  • Generate a new key - if you need it for TestFlight, assign App Manager Access.
  • Save issuer ID, key ID and private key. You'll need all 3 to generate the JWT token for Authorizing requests.
generate app store connect api key

Make a request with App Store Connect API key from Node

API documentation: https://developer.apple.com/documentation/appstoreconnectapi

For example, I'll create a Nodejs script that will query how many apps are there in the App Store Connect account.

Install the dependencies for signing the jwt token and making the request:

npm i jsonwebtoken axios

To sign the jwt token you need to have the issuer id, private key file and key id. Don't create a long lived token. I noticed that results in 401 unathorized request. My example token expires after 5 minutes. Jwt token part looks like this:

const jwt = require('jsonwebtoken');
const fs = require('fs');

const privateKey = fs.readFileSync(process.env.APPSTORE_API_PRIVATE_KEY_FILE);

const token = jwt.sign({}, privateKey, {
    algorithm: 'ES256',
    expiresIn: '5m',
    issuer: process.env.APPSTORE_ISSUER_ID,
    audience: "appstoreconnect-v1",
    keyid: process.env.APPSTORE_API_KEY_ID,
});

And the request is just a:

axios.get('https://api.appstoreconnect.apple.com/v1/apps', {
    headers: {
        Authorization: `Bearer ${token}`
    }
})