APNs .p8 Key: What It Is and How to Get It

Entrig
Ib Entrig Team

Setting up iOS push, you will reach a step asking for a .p8 file, a Key ID, and a Team ID. This covers what those are, why Apple needs them, and how to get them, including the one step you genuinely cannot undo.


What APNs Is

Apple Push Notification service is the only path to an iOS device. Every notification your app receives, from every provider, arrives through APNs. Services like Firebase or OneSignal do not bypass it, they talk to it on your behalf.

The flow:

  1. Your app asks the user for notification permission, then registers with APNs and receives a device token.
  2. Your server stores that token and, when there is something to say, calls APNs: “deliver this payload to this token, for this app.”
  3. APNs delivers it, holding onto the message if the device is offline.

Apple controls that path deliberately. It is why a backgrounded iOS app cannot drain your battery polling for updates, and it is why you need credentials to use it.


Why a .p8 Key

APNs will not accept sends from anyone. You have to prove you represent the app you are sending to.

There are two mechanisms, and the older one is still all over the internet:

.p12 certificate.p8 auth key
ExpiresEvery yearNever
ScopeOne appAll apps in your team
EnvironmentsSeparate cert per environmentOne key covers both
On expiryPush silently stopsNothing to expire
Apple recommendsNoYes

The .p12 route means an annual renewal that, when forgotten, breaks push notifications in production with no warning and no obvious cause. Many teams have lost a day to exactly that.

Use the .p8. One key, no expiry, covers everything. The only reason to touch certificates now is an old system that cannot do token auth.


The Four Things You Need

A .p8 on its own is not enough. Apple needs to know which key, whose account, and which app:

ValueLooks likeWhere to find it
.p8 fileAuthKey_ABC123DEFG.p8Downloaded at creation, once
Key IDABC123DEFGNext to the key name in Apple Developer
Team ID1A2B3C4D5EMembership Details
Bundle IDcom.yourcompany.appIdentifiers, and your Xcode target

The Key ID is also embedded in the filename, which is handy when you find an old .p8 and cannot remember which key it was.


Creating the Key

You need a paid Apple Developer Program membership. The free tier cannot create APNs keys.

1. Enable Push Notifications on your App ID

In Apple Developer, go to Certificates, Identifiers & Profiles → Identifiers and select your app’s identifier. Make sure Push Notifications is ticked in the capabilities list, and save.

Also enable the Push Notifications capability on your target in Xcode, which creates the entitlements file.

2. Create the auth key

Go to Certificates, Identifiers & Profiles → Keys and click +.

Give it a name you will recognise in two years, something like Push - MyApp, and tick Apple Push Notifications service (APNs). Continue, then Register.

3. Download it, once

You now get a Download button. This is the step you cannot repeat.

Apple lets you download a .p8 exactly once. There is no second chance and no recovery. If you lose the file, your only option is to revoke the key and create a new one.

Download it and immediately put a copy in your password manager. Not your Downloads folder. Not a Slack message to yourself.

While you are on that screen, copy the Key ID.

4. Get your Team ID

Top right of the Apple Developer portal, or under Membership Details. Ten characters, and it is not the same as your Apple ID.


Sandbox vs Production

This is the single most common source of “push works on my machine but not in production.”

Device tokens are environment specific.

BuildEnvironmentToken valid against
Run from XcodeSandboxSandbox endpoint only
TestFlightProductionProduction endpoint only
App StoreProductionProduction endpoint only

TestFlight is production. People assume a pre-release build is “development” and it is not, which is why push often breaks the moment a build leaves Xcode.

Your .p8 key works for both environments, so the key is not the problem. What has to match is the endpoint your server sends to and the environment the token came from. If they disagree, APNs rejects it with BadDeviceToken.

The practical fix is to record which environment each token came from when you register it, and send accordingly. Most SDKs expose this as an isSandbox flag.


Common Failure Modes

BadDeviceToken. Environment mismatch, almost always. A sandbox token sent to production or the reverse. Check what build produced the token.

InvalidProviderToken. Your Key ID, Team ID, or the .p8 itself do not agree. Usually a copy-paste error, or the wrong key file where you have more than one.

TopicDisallowed or DeviceTokenNotForTopic. The Bundle ID you are sending as does not match the app the token belongs to. Note the topic is your Bundle ID exactly, and app extensions have their own suffixed identifiers.

ExpiredProviderToken. The short-lived JWT your server generates from the .p8 has aged out. Apple expects them refreshed roughly hourly, and this is your sending code’s job, not the key’s.

Nothing arrives at all, no error. Check the user actually granted permission, and test on a real device. Simulator push support depends on your Xcode and macOS versions, so a real device removes one variable when you are trying to work out why nothing is arriving.


Where This Fits

The credential is the easy part. What follows is the real work: storing tokens with their environment, pruning dead ones, deciding who should receive a given notification, building payloads, and refreshing provider tokens on schedule.

If your data lives in Supabase, Entrig handles that half. You upload the .p8, Key ID, Team ID and Bundle ID once, and notifications become configuration against your existing tables rather than a service you maintain. Sandbox and production are stored independently, so a development build and an App Store build can both work at the same time.

You still need this key either way. Apple requires your own credentials to reach your own app, and no service can remove that.


Frequently asked questions

What is an APNs .p8 key?

It is a token-based authentication key that lets a server send push notifications through Apple Push Notification service. You create it once in your Apple Developer account and it does not expire. A single key works for every app in your team and for both the sandbox and production environments.

What is the difference between a .p8 key and a .p12 certificate?

A .p12 is the older certificate-based approach: one per app, per environment, expiring every year, which means an annual renewal that breaks push if you forget. A .p8 auth key never expires, covers every app in your team, and works for both environments. Apple recommends the key, and there is no good reason to start a new project with certificates.

Can I download my APNs key again later?

No. Apple lets you download the .p8 file exactly once, at creation. If you lose it, you cannot recover it, you have to revoke that key and create a new one. Back it up to a password manager the moment you download it.

How many APNs keys can I create?

Apple limits you to two active APNs auth keys per developer account. That limit exists because one key already covers all of your apps, so needing more than one or two is unusual. If you are at the limit, revoke an unused key before creating another.

Why do my iOS notifications work in development but not in the App Store build?

Device tokens are environment specific. A token issued to a build run from Xcode is a sandbox token and is only valid against Apple's sandbox endpoint, while TestFlight and App Store builds get production tokens. If your server sends every token to one environment, half of them fail with BadDeviceToken. Note that TestFlight counts as production, which catches many people out.

Do I need a paid Apple Developer account for push notifications?

Yes. Push notifications require a paid Apple Developer Program membership, currently $99 per year. The free tier cannot create APNs keys or enable the push entitlement.