Apple Push Notification Service

iOS devices connect to Apple's push servers via port 5223. The protocol is proprietary and has nothing to do with XMPP (which uses the same port to establish SSL-encrypted client connections). The Push service protocol also uses SSL encryption.

As of iOS5, Apple uses a new push protocol. The same protocol is used on the Mac too. With iOS4, the protocol used message types  to , while the new protocol uses message types   to   and all fields have a type-length-value encoding.

While every iOS version after that continued adding new message and field types, since iOS 10 there is another new push protocol known as "apnspack", which uses the same message and field types but encodes them in a completely different binary format. The client negotiates use of this new protocol with the protocol name "apns-pack-v1" in ALPN. The apnspack format is not yet documented in this page.

Message Structure
The format of the non-packed APNS protocol is as follows:


 * 1 byte message type
 * 4 byte payload length
 * fields, all with
 * 1 byte type
 * 2 byte length
 * value

Example:
 * message type (Connect)
 * 39 byte payload length
 * 1st field
 * 32 byte length
 * value 1 (32-byte push token)
 * 2nd field
 * 1 byte length
 * value

07 Connect

 * Direction: device to server
 * message type:
 * fields:
 * 32-byte push token
 * 1 byte unknown (value )

08 Connect Response

 * Direction: server to device
 * message type:
 * fields:
 * status ( ok,   some error)
 * unknown (value )
 * unknown (value )
 * 32-byte push token (optional), sent after  field

09 Push Topics

 * Direction: device to server
 * message type:
 * fields:
 * 20-byte ID for enabled topic (like topic for push-enabled app or a specific iCloud service like Find My iPhone)
 * 20-byte ID for disabled topic

0A Push Notification

 * Direction: server to device (for iMessage and possibly others too, also the other way round)
 * message type:
 * fields:
 * recipient push token
 * topic
 * notification payload
 * response token
 * expiry (32-bit UNIX timestamp)
 * timestamp (64-bit UNIX timestamp in nanoseconds)
 * unknown

0B Push Notification Response

 * Direction: server to device (for iMessage and possibly others too, also the other way round)
 * message type:
 * fields:
 * response token
 * status ( ok,   error)

0C Keep-Alive

 * Direction: device to server
 * message type:
 * fields:
 * connection method ("WiFi" or GSM MNC like "31038" for AT&T)
 * iOS version, e.g. "5.0"
 * iOS build number
 * device model, e.g. "iPhone2,1"
 * unknown (values like,   or  )

0D Keep-Alive Confirmation

 * Direction: server to device
 * message type:
 * no fields

0E No Storage

 * Direction: server to device
 * message type:
 * fields:
 * 32-byte push token

0F Flush

 * Direction: both
 * message type:
 * fields:
 * 2-byte integer indicating length of padding
 * padding: NULL-bytes, typical lengths are 64, 128, 256, 512