/api-reference/openapi.json), which is itself generated from the live route definitions — it cannot drift from the API’s actual behaviour.
Authentication
Every request needs an access token (plt_…), sent either way:
401 UNAUTHORIZED; requests whose token lacks the operation’s scope get 403 FORBIDDEN.
Scopes
Each operation requires a scope, documented on its endpoint page (and machine-readable asx-required-scopes in the spec): passes:read, passes:write, templates:read, webhooks:read, webhooks:write, scans:read, scans:write.
Resources
| Resource | What it covers |
|---|---|
| Passes | Issue (single/batch), read, void (single/batch), revoke add-to-wallet links |
| Templates | List templates, fetch the published version and its variables schema |
| Template versions | List and read immutable published versions |
| Projects | CRUD plus per-project statistics |
| Scans | Record (single/bulk), list, read, reverse, aggregate stats, real-time SSE stream |
| Webhooks | Endpoint CRUD, test events, delivery history, redelivery |
Conventions
- JSON everywhere — request and response bodies are
application/json(UTF-8). - IDs are opaque strings; don’t parse them.
- Timestamps are ISO 8601 / RFC 3339 in UTC.
- Idempotent issuance —
externalPassIdis unique per workspace; re-sending a create with the same external ID doesn’t create a duplicate pass. - Async lifecycle — issuing, updating, and voiding are queued and processed in the background; the API returns immediately with the pass in its transitional status. Subscribe to webhooks rather than polling.
- Errors — a stable machine-readable shape with
errorCode,message, andcorrelationId; see Errors. - Pagination & filtering — cursor-based, with one consistent filter grammar across list endpoints; see Pagination & filtering.