Wallet Technology

What Is a .pkpass File? Inside Apple Wallet's Pass Format

Rikki Pitt
#pkpass#apple wallet#passkit#digital wallet#file formats
An iPhone beside a leather wallet, the physical wallet that Apple Wallet passes replace

You were emailed a boarding pass, a concert ticket or a coffee shop loyalty card, and you ended up with a file ending in .pkpass. On an iPhone it opens instantly. On a Windows laptop, nothing happens at all.

A .pkpass file is an Apple Wallet pass package: a ZIP archive containing a JSON description of the pass, its images, and a cryptographic signature proving it came from who it claims to. The format was introduced with Passbook in iOS 6 and is still what powers every pass in Apple Wallet today.

Here’s what’s actually inside one, and why that structure explains most of the odd behaviour people run into.

What’s inside a .pkpass file

Rename a .pkpass to .zip, unzip it, and you’ll find something like this:

BoardingPass.pkpass/
├── pass.json          (required)
├── manifest.json      (required)
├── signature          (required)
├── icon.png           (required)
├── icon@2x.png        (required)
├── logo.png
├── strip.png
├── thumbnail.png
└── en.lproj/
    └── pass.strings

Only five of those are mandatory. Everything else depends on the type of pass and how much the designer cared.

pass.json, the pass itself

This is the whole pass expressed as JSON: the text on the front, the fields on the back, the background colour, the barcode, and the metadata Apple needs to route it correctly.

Six keys are required in every pass:

  • formatVersion: always 1
  • passTypeIdentifier: the reverse-DNS ID registered in your Apple Developer account, e.g. pass.com.example.loyalty
  • serialNumber: unique per pass, per pass type
  • teamIdentifier: your Apple Developer Team ID
  • organizationName: the name shown when the pass asks to be added
  • description: a short line used by VoiceOver

Then exactly one style key determines the pass layout. There are five, and you cannot mix them:

Style keyUsed for
boardingPassFlights, trains, ferries, buses
couponOffers and discounts
eventTicketConcerts, matches, cinema
storeCardLoyalty cards, stamp cards, gift cards
genericEverything else, e.g. gym membership, ID badges

If you run a loyalty program, your passes are almost certainly storeCard.

manifest.json, the integrity check

A flat dictionary mapping every file in the package to its SHA-1 hash:

{
  "pass.json": "9c4f5a...",
  "icon.png": "e3b0c4...",
  "logo.png": "5891b5..."
}

The manifest lists every file except itself and the signature. Change a single pixel in logo.png after building the manifest and the hash no longer matches, so the pass is rejected.

signature, the proof of origin

A PKCS#7 detached signature over manifest.json. Because the manifest covers every other file, signing the manifest effectively signs the entire package.

To produce one you need a Pass Type ID certificate from Apple, plus Apple’s WWDR intermediate certificate. This is the part that trips up most first-time developers: an expired WWDR certificate, or a passTypeIdentifier that doesn’t match the certificate, produces a pass that looks perfectly fine in a text editor and is silently refused by Wallet.

The images

icon.png and icon@2x.png are required, and they’re what appears in notifications and search results. Beyond that, logo.png sits in the header, strip.png is the wide banner behind the primary fields, thumbnail.png appears to the right of the fields, and background.png is used by event tickets.

Each accepts @2x and @3x variants for retina displays. Get the dimensions wrong and the pass still loads, but looks stretched or cropped.

Localisation folders

Directories like en.lproj and fr.lproj hold a pass.strings file mapping keys to translated text, plus any localised images. Wallet picks the folder matching the device language.

Why it won’t open on some devices

The format is Apple’s, so support varies:

  • iPhone, iPad, Apple Watch: opens natively in Apple Wallet.
  • Mac: double-clicking opens Pass Viewer, a built-in app that renders the pass and offers to add it to Wallet via iCloud.
  • Android: since April 2024, Google Wallet can import .pkpass files directly through the share sheet. Older devices, or passes Google Wallet rejects, need a third-party app such as PassWallet or Pass2U.
  • Windows and Linux: no native support at all. There is no application that will render the pass for you.

That last one is why so many people search for a way to open a .pkpass file on a PC. You have two realistic options: rename it to .zip and read the raw contents, or drop it into a browser-based pkpass viewer that renders the pass and decodes the package without installing anything.

Is a .pkpass file safe to open?

Generally yes, and the format is deliberately boring in a good way. A pass is a ZIP of JSON and PNG files. There is no executable code, no scripting, nothing that runs on your device when you add it to Wallet.

Two caveats worth knowing:

  1. A pass can carry a webServiceURL, which lets the issuer push updates to it. That’s how a boarding pass changes gate number by itself. It also means the issuer can tell when the pass is still installed.
  2. A valid signature proves the pass came from a registered Apple developer, not that the developer is trustworthy. Treat a pass from an unknown sender the way you’d treat any unexpected attachment.

Looking inside a pass yourself

If you’re debugging a pass that won’t load, the fastest way to find the problem is to open the package and check three things in order: does pass.json parse and contain all six required keys, do the manifest hashes match the actual files, and is the signature valid against a current WWDR certificate.

Our free pkpass inspector does all three in your browser, and the file never leaves your machine. It renders a preview of the pass, pretty-prints pass.json, verifies every manifest hash, decodes the barcode payload and checks the signature chain.

If you’re earlier in the process and just want to check your JSON before packaging anything, the pass.json validator catches missing required fields, malformed colours and barcode misconfigurations.

Building passes rather than debugging them

Everything above is the manual route: generate the JSON, hash the files, sign the manifest, zip it up, and renew your certificates before they expire.

Most businesses running a loyalty program don’t want to own that. Leal issues Apple Wallet and Google Wallet cards for you, so the certificates, signing and push updates are handled, and you design the card in a browser. The free plan covers unlimited customers, so you can test it with real people before paying anything.