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.
3. Send the holder the link
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
- The pass object: every field, and where it shows.
- Send a notification to every holder's lock screen.
- Your own credentials, to go live.