How APNs works
APNs is the intermediary between an app’s server and Apple devices. No direct channel between a
server and an iPhone exists: Apple is the only authorised route.
The delivery chain, simplified:
- The app on the device requests a device token from APNs
- The app passes that token to the retailer’s server
- The server sends a push payload to APNs with the device token and authentication credentials
- APNs delivers the notification to that specific device
APNs supports several delivery priorities: immediate (high priority, wakes the device) and
background (the notification is delivered at the next convenient opportunity and does not wake the
device).
Authentication: certificates versus JWT keys
| Method | Validity | Scope | Recommended |
|---|---|---|---|
| APNs Certificate (.p12) | 1 year, needs rotation | A single app | Legacy |
| APNs Auth Key (.p8) | Key does not expire | All apps in the account | Current |
The p8 JWT key is the preferred method. The key does not expire, the JWT token is refreshed
automatically, and one key covers every app in the account.
The APNs payload: what you can send
{
"aps": {
"alert": {
"title": "Your order has shipped",
"body": "Expect delivery on 3 June"
},
"badge": 1,
"sound": "default",
"content-available": 1
},
"order_id": "12345",
"deep_link": "app://orders/12345"
}
content-available: 1 is the silent push flag: nothing is displayed, but the app receives a signal
to refresh its data in the background.
Practical limits of APNs
- Payload size: a maximum of 4 KB for standard notifications, or 5 KB for VoIP
- Rate limits: APNs does not publish exact figures, but aggressive sending — thousands of
notifications per second to a single device — leads to throttling - Delivery is not guaranteed: if a device is offline for a long period, APNs stores only the
most recent notification for delivery and discards the rest - Sandbox versus production: the two environments use different endpoints, and the wrong
endpoint is a frequent cause of non-delivery during testing
Important: iOS enforces a hard limit on the permission request — if the user declines, the
system dialogue cannot be shown again. The timing of the first request is therefore critical:
show it only after the value of notifications has been demonstrated, such as after a first
successful purchase or when an order is ready.