API reference.
Base URL: https://api.passmint.com
Authentication
Pass your API key as a Bearer token in the Authorization header. Test keys use the pmk_test_ prefix and live keys use pmk_live_. The mode (test or live) is determined by the key prefix. Test keys are available on every plan; live keys require a paid plan.
Authorization: Bearer pmk_test_xxxIdempotency
Send an Idempotency-Key header on POST and PATCH requests to safely retry without duplicating side effects. Replays within 24 hours return the cached response. Reusing a key with a different request body returns 409.
Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7Response format
Single objects include an object field identifying the type. List endpoints wrap results in a standard envelope.
// Single object
{
"object": "pass",
"id": "pass_xxx",
...
}
// List
{
"object": "list",
"data": [...],
"has_more": false
}Errors
Errors return a consistent JSON envelope with a type, optional code, human-readable message, and the offending param when applicable.
{
"error": {
"type": "invalid_request_error",
"code": null,
"message": "template_id is required",
"param": "template_id"
}
}Passes
Passes are the core resource. Each represents a single wallet pass issued from a template.
Issue a pass
Create a new pass from a template. Supports idempotency.
curl https://api.passmint.com/v1/passes \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"template_id": "tmpl_xxx",
"holder_email": "alice@example.com",
"holder_name": "Alice Johnson",
"field_values": { "seatNumber": "A12" },
"metadata": { "order_id": "ord_123" }
}'{
"object": "pass",
"id": "pass_xxx",
"short_id": "abc123",
"template_id": "tmpl_xxx",
"serial_number": "...",
"mode": "test",
"holder_email": "alice@example.com",
"holder_name": "Alice Johnson",
"field_values": { "seatNumber": "A12" },
"voided": false,
"voided_at": null,
"metadata": { "order_id": "ord_123" },
"created_via_api": true,
"url": "https://passmint.com/p/abc123",
"download_url": "https://passmint.com/p/abc123/download",
"created_at": "2026-04-16T12:00:00Z"
}List passes
Returns a paginated list of passes.
curl "https://api.passmint.com/v1/passes?template_id=tmpl_xxx&limit=10" \
-H "Authorization: Bearer pmk_test_xxx"{
"object": "list",
"data": [{ "object": "pass", "id": "pass_xxx", ... }],
"has_more": false
}Retrieve a pass
Returns a single pass by ID.
curl https://api.passmint.com/v1/passes/pass_xxx \
-H "Authorization: Bearer pmk_test_xxx"Update a pass
Update the field values or metadata on a pass. At least one of field_values or metadata is required. Cannot update voided passes (returns 400). Live updates are pushed to installed passes automatically. Supports idempotency.
curl -X PATCH https://api.passmint.com/v1/passes/pass_xxx \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "field_values": { "seatNumber": "B7" } }'Void a pass
Voids a pass. The pass is not deleted. It is returned with voided: true and a voided_at timestamp.
curl -X DELETE https://api.passmint.com/v1/passes/pass_xxx \
-H "Authorization: Bearer pmk_test_xxx"{
"object": "pass",
"id": "pass_xxx",
"voided": true,
"voided_at": "2026-04-16T14:30:00Z",
...
}Create an expiring download link
Mints a time-limited link to the pass page, the expiring alternative to the permanent url on the pass object. The link works exactly like the permanent one (Apple Wallet download, Google Wallet save, QR handoff) until expires_at, after which it stops resolving and the holder is told to request a fresh one. Mint a new link per delivery; links are independent and minting one never invalidates another.
Be clear-eyed about what expiry protects. The link itself, in an email, a support thread, a log line, a forwarded message. It does not time-limit the pass. A .pkpassdownloaded before expiry is a signed file on the holder's device, barcode included, and no link expiry can reach it. To control redemption, use redemption policies and the scanner, not download links.
To make expiring links the only way in, disabling the permanent URL entirely, set require_download_link on the template.
curl https://api.passmint.com/v1/passes/pass_xxx/download-links \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-d '{ "expires_in": 3600 }'{
"object": "pass.download_link",
"pass_id": "pass_xxx",
"url": "https://passmint.com/p/dl/pdl_mF4jK...",
"expires_in": 3600,
"expires_at": "2026-04-16T13:00:00Z",
"created_at": "2026-04-16T12:00:00Z"
}Download link object
Pass object
Templates
Templates define the design and structure of your passes. Every pass is issued from a template.
Create a template
Create a new pass template. Supports idempotency.
curl https://api.passmint.com/v1/templates \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "VIP Concert Pass",
"type": "event",
"apple_style": "eventTicket",
"design": { ... }
}'{
"object": "template",
"id": "tmpl_xxx",
"name": "VIP Concert Pass",
"type": "event",
"apple_style": "eventTicket",
"design": { ... },
"archived": false,
"created_at": "2026-04-16T12:00:00Z",
"updated_at": "2026-04-16T12:00:00Z"
}List templates
Returns a list of non-archived templates.
curl "https://api.passmint.com/v1/templates?limit=10" \
-H "Authorization: Bearer pmk_test_xxx"Retrieve a template
Returns a single template by ID, including archived templates.
curl https://api.passmint.com/v1/templates/tmpl_xxx \
-H "Authorization: Bearer pmk_test_xxx"Update a template
Update a template's name, design, or archived status. All fields are optional.
curl -X PATCH https://api.passmint.com/v1/templates/tmpl_xxx \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Updated Template Name" }'Archive a template
Archives a template. Existing passes remain valid but no new passes can be issued from an archived template.
curl -X DELETE https://api.passmint.com/v1/templates/tmpl_xxx \
-H "Authorization: Bearer pmk_test_xxx"{
"id": "tmpl_xxx",
"deleted": true
}Template object
Events
Events track the lifecycle of passes, from creation through installation and removal.
List recent events
Returns recent events across all passes.
curl "https://api.passmint.com/v1/events?limit=50" \
-H "Authorization: Bearer pmk_test_xxx"List events for a pass
Returns events for a specific pass.
curl "https://api.passmint.com/v1/passes/pass_xxx/events?limit=20" \
-H "Authorization: Bearer pmk_test_xxx"{
"object": "list",
"data": [
{
"object": "pass_event",
"id": "psEvnt_xxx",
"pass_id": "pass_xxx",
"type": "installed",
"metadata": {},
"created_at": "2026-04-16T13:00:00Z"
}
],
"has_more": false
}PassEvent object
Event types
Webhooks
Webhooks deliver real-time event notifications to your server. Passmint signs every payload so you can verify authenticity.
Create a webhook
Register a new webhook endpoint. The response includes the secret field. This is the only time the secret is returned. Store it securely. Supports idempotency.
Valid event types: pass.issued, pass.add_intent, pass.added_to_wallet, pass.update_pushed, pass.update_delivered, pass.removed, pass.voided, pass.redeemed (fires when a pass is scanned and accepted at a scanner device), or * for all events.
curl https://api.passmint.com/v1/webhooks \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/passmint",
"events": ["pass.issued", "pass.added_to_wallet"],
"description": "Production webhook"
}'{
"object": "webhook",
"id": "whk_xxx",
"url": "https://example.com/webhooks/passmint",
"events": ["pass.issued", "pass.added_to_wallet"],
"description": "Production webhook",
"enabled": true,
"secret": "whsec_xxx",
"created_at": "2026-04-16T12:00:00Z"
}List webhooks
Returns all webhooks for your account.
curl https://api.passmint.com/v1/webhooks \
-H "Authorization: Bearer pmk_test_xxx"Retrieve a webhook
Returns a single webhook by ID. The secret field is not included in retrieval responses.
curl https://api.passmint.com/v1/webhooks/whk_xxx \
-H "Authorization: Bearer pmk_test_xxx"Update a webhook
Update a webhook's URL, subscribed events, description, or enabled status. All fields are optional.
curl -X PATCH https://api.passmint.com/v1/webhooks/whk_xxx \
-H "Authorization: Bearer pmk_test_xxx" \
-H "Content-Type: application/json" \
-d '{ "events": ["*"], "description": "All events" }'Delete a webhook
Permanently deletes a webhook and its delivery history. This is a hard delete and cannot be undone.
curl -X DELETE https://api.passmint.com/v1/webhooks/whk_xxx \
-H "Authorization: Bearer pmk_test_xxx"{
"id": "whk_xxx",
"deleted": true
}List recent deliveries
Returns the last 100 delivery attempts for a webhook.
curl https://api.passmint.com/v1/webhooks/whk_xxx/deliveries \
-H "Authorization: Bearer pmk_test_xxx"{
"object": "list",
"data": [
{
"object": "webhook_delivery",
"id": "whd_xxx",
"webhook_id": "whk_xxx",
"event_type": "pass.issued",
"status": "delivered",
"attempts": 1,
"last_attempt_at": "2026-04-16T12:01:00Z",
"next_attempt_at": null,
"response_status": 200,
"response_body": "ok",
"created_at": "2026-04-16T12:00:00Z"
}
],
"has_more": false
}