WalletPassAPI Docs

Getting started

Quickstart

Issue your first Apple Wallet and Google Wallet pass, then update it.

You need an API key, and five minutes. Until you add your own Apple and Google credentials, passes are signed with ours and marked as test passes, so you can try everything first.

1. Get your API key

In the dashboard, open Settings and choose New API key. It starts wpk_ and is shown only once, when it's made. Keep it on your server, and send it in every request:

Authorization: Bearer wpk_…

The examples below read it from an environment variable, WALLET_API_KEY.

2. Create a pass

Send the pass's content to Create a pass. It needs organizationName, and logoText or primaryFields; every other field is up to you.

curl "https://api.walletpassapi.com/v1/passes" \
  -H "Authorization: Bearer $WALLET_API_KEY" \
  -H "Idempotency-Key: order-1042" \
  -H "Content-Type: application/json" \
  -d '{
    "organizationName": "Acme Coffee",
    "logoText": "Acme",
    "style": "loyalty",
    "primaryFields": [
      {
        "key": "points",
        "label": "Points",
        "value": "120",
        "changeMessage": "You now have %@ points"
      }
    ],
    "barcodeValue": "MEMBER-1042",
    "barcodeFormat": "QR"
  }'
const res = await fetch("https://api.walletpassapi.com/v1/passes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WALLET_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "order-1042",
  },
  body: JSON.stringify({
    "organizationName": "Acme Coffee",
    "logoText": "Acme",
    "style": "loyalty",
    "primaryFields": [
      {
        "key": "points",
        "label": "Points",
        "value": "120",
        "changeMessage": "You now have %@ points"
      }
    ],
    "barcodeValue": "MEMBER-1042",
    "barcodeFormat": "QR"
  }),
});
const data = await res.json();
import os

import requests

res = requests.post(
    "https://api.walletpassapi.com/v1/passes",
    headers={"Authorization": f"Bearer {os.environ['WALLET_API_KEY']}", "Idempotency-Key": "order-1042"},
    json={
        "organizationName": "Acme Coffee",
        "logoText": "Acme",
        "style": "loyalty",
        "primaryFields": [
            {
                "key": "points",
                "label": "Points",
                "value": "120",
                "changeMessage": "You now have %@ points",
            },
        ],
        "barcodeValue": "MEMBER-1042",
        "barcodeFormat": "QR",
    },
)
data = res.json()
<?php

$ch = curl_init("https://api.walletpassapi.com/v1/passes");
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("WALLET_API_KEY"),
        "Content-Type: application/json",
        "Idempotency-Key: order-1042",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "organizationName" => "Acme Coffee",
        "logoText" => "Acme",
        "style" => "loyalty",
        "primaryFields" => [
            [
                "key" => "points",
                "label" => "Points",
                "value" => "120",
                "changeMessage" => "You now have %@ points",
            ],
        ],
        "barcodeValue" => "MEMBER-1042",
        "barcodeFormat" => "QR",
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);

The answer:

{
  "serialNumber": "9f904677-e06d-4b0f-8404-878ff1066f88",
  "status": "active",
  "issuer": "platform",
  "shareUrl": "https://app.walletpassapi.com/p/4MOhErCigjeasw-2epMpEkFatq4PNdPYNZqIxXwq5r",
  "createdAt": "2026-10-08T19:31:12.000Z",
  "platforms": { "apple": "built", "google": "built" }
}

Idempotency-Key makes the request safe to retry: if the network drops and you send it again, you get the same pass back, not a second one.

shareUrl opens an install page that offers each phone the right wallet: Add to Apple Wallet on an iPhone, Add to Google Wallet on Android, and a QR code to scan on a computer. Email it, text it, or show it on screen.

Keep the serialNumber: it's how you change the pass later.

4. Update it

When the points change, send the whole pass again to Update a pass, with the new value. Installed passes refresh on holders' phones, and because the field has a changeMessage, the lock screen shows "You now have 135 points".

curl -X PUT "https://api.walletpassapi.com/v1/passes/9f904677-e06d-4b0f-8404-878ff1066f88" \
  -H "Authorization: Bearer $WALLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "organizationName": "Acme Coffee",
    "logoText": "Acme",
    "style": "loyalty",
    "primaryFields": [
      {
        "key": "points",
        "label": "Points",
        "value": "135",
        "changeMessage": "You now have %@ points"
      }
    ],
    "barcodeValue": "MEMBER-1042",
    "barcodeFormat": "QR"
  }'
const res = await fetch("https://api.walletpassapi.com/v1/passes/9f904677-e06d-4b0f-8404-878ff1066f88", {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${process.env.WALLET_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "organizationName": "Acme Coffee",
    "logoText": "Acme",
    "style": "loyalty",
    "primaryFields": [
      {
        "key": "points",
        "label": "Points",
        "value": "135",
        "changeMessage": "You now have %@ points"
      }
    ],
    "barcodeValue": "MEMBER-1042",
    "barcodeFormat": "QR"
  }),
});
const data = await res.json();
import os

import requests

res = requests.put(
    "https://api.walletpassapi.com/v1/passes/9f904677-e06d-4b0f-8404-878ff1066f88",
    headers={"Authorization": f"Bearer {os.environ['WALLET_API_KEY']}"},
    json={
        "organizationName": "Acme Coffee",
        "logoText": "Acme",
        "style": "loyalty",
        "primaryFields": [
            {
                "key": "points",
                "label": "Points",
                "value": "135",
                "changeMessage": "You now have %@ points",
            },
        ],
        "barcodeValue": "MEMBER-1042",
        "barcodeFormat": "QR",
    },
)
data = res.json()
<?php

$ch = curl_init("https://api.walletpassapi.com/v1/passes/9f904677-e06d-4b0f-8404-878ff1066f88");
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => "PUT",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("WALLET_API_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "organizationName" => "Acme Coffee",
        "logoText" => "Acme",
        "style" => "loyalty",
        "primaryFields" => [
            [
                "key" => "points",
                "label" => "Points",
                "value" => "135",
                "changeMessage" => "You now have %@ points",
            ],
        ],
        "barcodeValue" => "MEMBER-1042",
        "barcodeFormat" => "QR",
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);

Sending the same content again changes nothing and uses no operation, so it's safe to call on every change in your system.

Next