Pass API
Reference

/api/public

No session — 9 routes reachable by anyone holding the right link.

The prefix is the whole access rule: everything here is either public by nature or addressed by an unguessable id. A customer scanning a poster has no session and no way to get one.

Enrollment

Each call answers at two addresses — the UUID that every printed QR already carries, and the slug pair a poster can print in words.

MethodPath
GET/api/public/programs/{programId}/enrollThe form: fields, colours, consent text, the offer
GET/api/public/tenants/{tenantSlug}/programs/{programSlug}/enrollThe same by slug
POST/api/public/programs/{programId}/enrollTake a card. 200, not 201
POST/api/public/tenants/{tenantSlug}/programs/{programSlug}/enrollThe same by slug

Enrollment is idempotent on (tenant, phone, program): scanning the poster twice hands back the same card with the same stamps on it, and alreadyEnrolled says which happened.

A TICKET program's form only works when the merchant turned on self-issuance. When they have not, it answers the same 404 as a program with no form at all — a distinct error would tell anyone holding the URL that they nearly minted themselves a free ticket.

A ticket sold through a booking system does not use this surface at all. See the partner guide.

MethodPath
GET/api/public/passes/{serial}.pkpass?t=<token>The signed Apple pass file
GET/api/public/passes/{serial}/google?t=<token>302 to Google Wallet's save flow

A wrong or missing t is a 404, not a 401 — a photographed QR must not confirm that a pass exists. Both URLs are returned by enrollment and by partner issuance; they carry the pass's auth token, so they belong to one customer only.

Public assets

MethodPath
GET/api/public/tenants/{slug}/pageThe merchant's public business page
GET/api/public/tenants/{slug}/images/{imageId}/v{version}.pngLogo and cover
GET/api/public/programs/{programId}/images/{imageId}/v{version}.pngCard artwork

The v{version} segment is there to change: images are served immutable with a one-year cache, so an edit becomes a new URL rather than a stale phone.

MethodPath
POST/api/public/google/callbackGoogle tells us a pass was saved or removed

The Google callback is the only signal Google gives that an object exists — a pass can live its whole life issued and never installed, and that gap is a merchant metric rather than an error.

On this page