PassFast lets you generate Apple Wallet and Google Wallet passes via API. Design a template, call the API with dynamic data, and get a signed .pkpass file (Apple) or a save URL (Google) back.
PassFast uses two types of API keys. You can manage them on the API Keys page.
| Key Type | Prefix | Use Case | Scopes |
|---|---|---|---|
| Secret | sk_live_ | Server-side only. Full API access. | All |
| Publishable | pk_live_ | Client-side (iOS, web). Can only generate and download passes. | passes:create, passes:download |
All requests use a Bearer token in the Authorization header:
Authorization: Bearer sk_live_your_secret_key_hereBefore you begin, make sure you have:
For custom signing setup (Apple certs, Google service account, APNs), see Setup & Configuration.
curl -X POST https://api.passfa.st/functions/v1/generate-pass \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "X-App-Id: YOUR_APP_ID" \
-H "Content-Type: application/json" \
-d '{
"template_id": "YOUR_TEMPLATE_ID",
"serial_number": "PASS-001",
"wallet_type": "both",
"data": {
"memberName": "Jane Smith",
"memberId": "MEM-12345"
}
}'{
"apple": {
"id": "uuid",
"serial_number": "PASS-001",
"wallet_type": "apple",
"status": "active",
"download_url": "/manage-passes/<id>/download"
},
"google": {
"id": "uuid",
"serial_number": "PASS-001",
"wallet_type": "google",
"status": "active",
"save_url": "https://pay.google.com/gp/v/save/...",
"google_object_id": "issuerId.passId"
},
"warnings": []
}Use wallet_type: "both" to generate Apple and Google passes in one call. For Apple-only, omit wallet_type (defaults to "apple") and pipe to --output pass.pkpass. For Google-only, set wallet_type: "google".
PassFast provides official SDKs for TypeScript and Swift:
import { PassFast } from "@passfast/sdk";
const pf = new PassFast("sk_live_YOUR_SECRET_KEY");
const { passId, pkpassData } = await pf.passes.generate({
template_id: "YOUR_TEMPLATE_ID",
serial_number: "PASS-001",
data: { memberName: "Jane Smith", memberId: "MEM-12345" },
});import PassFast
let client = PassFastClient(apiKey: "pk_live_YOUR_KEY")
let (pass, passId) = try await client.passes.generatePKPass(.init(
templateId: "YOUR_TEMPLATE_ID",
serialNumber: "PASS-001",
data: ["memberName": "Jane Smith", "memberId": "MEM-12345"]
))| Field | Type | Required | Description |
|---|---|---|---|
| template_id | string | Yes | ID of a published template |
| serial_number | string | Yes | Unique serial number for this pass |
| data | object | Yes | Dynamic values matching the template's field schema |
| wallet_type | string | No | "both" (recommended), "apple" (default), or "google" |
| external_id | string | No | Your own identifier for cross-referencing |
| expires_at | string | No | ISO 8601 expiration date |
| get_or_create | boolean | No | Return existing active pass instead of 409 on duplicate serial (default: false) |