/api/dashboard
The merchant web dashboard — 41 routes behind a session cookie.
Session-authenticated, OWNER or MANAGER only. The tenant comes from the session and never
from the URL, so a signed-in user can only ever reach their own merchant. A session opened on the
scanner is refused here with a 403 even when its role would otherwise pass.
Some writes narrow further to OWNER — the business profile, the API key, images, and firing a
notice at every pass. Those return 403 for a MANAGER.
Session
| Method | Path | |
|---|---|---|
POST | /api/dashboard/login | Email and password, scoped by tenant slug |
POST | /api/dashboard/logout | 204 |
GET | /api/dashboard/me | The signed-in user, their role and branch |
Programs
A Program is one scheme with one type — STAMPS, POINTS, COUPON or TICKET.
| Method | Path | |
|---|---|---|
GET | /api/dashboard/programs | List |
POST | /api/dashboard/programs | Create. 201 |
GET | /api/dashboard/programs/{id} | One Program with its rules, card fields and images |
PUT | /api/dashboard/programs/{id} | Full replacement, child collections included |
DELETE | /api/dashboard/programs/{id} | 204. DRAFT only — a published Google class is permanent |
POST | /api/dashboard/programs/{id}/publish | DRAFT → LIVE. Irreversible |
POST | /api/dashboard/programs/{id}/archive | Stop issuing without deleting |
POST | /api/dashboard/programs/{id}/unarchive | Back to LIVE, reusing the same Google class |
GET | /api/dashboard/programs/{id}/card-layout-upgrade | Preview what an upgrade would change |
POST | /api/dashboard/programs/{id}/card-layout-upgrade | Apply it. A no-op on anything past layout version 1 |
PUT replaces everything except slug and, on a TICKET, the venue trio's opt-in rules. An
omitted slug keeps the one the Program has — there is no way to un-print a poster.
Card design
| Method | Path | |
|---|---|---|
POST | /api/dashboard/programs/{programId}/images/{kind} | Upload. Replaces the kind if present. 201 |
DELETE | /api/dashboard/programs/{programId}/images/{imageId} | 204 |
GET | /api/dashboard/programs/{programId}/apple-sample.pkpass | A signed sample pass for previewing. 503 without a signing certificate |
Notices
| Method | Path | |
|---|---|---|
POST | /api/dashboard/programs/{programId}/notices | Send to a program or one pass. 202 — it queues |
POST | /api/dashboard/programs/{programId}/notices/preview | Render the tokens without sending |
GET | /api/dashboard/programs/{programId}/notices | The send report. Paginates; filters on status and batchId |
Firing at every pass is OWNER only — it is unbounded and cannot be recalled.
Customers
| Method | Path | |
|---|---|---|
GET | /api/dashboard/customers | Paginated CRM list. Filters: phone, name, enrolledFrom, enrolledTo, hasConsent, sort |
GET | /api/dashboard/customers/{id} | One customer, their passes and their form answers |
GET | /api/dashboard/passes/{passId}/transactions | The append-only ledger for one pass |
Branches
| Method | Path | |
|---|---|---|
GET | /api/dashboard/locations | List |
POST | /api/dashboard/locations | Create. 201 |
GET | /api/dashboard/locations/{id} | One branch with its business hours |
PUT | /api/dashboard/locations/{id} | Update. Re-pushes every live Program that pins it |
DELETE | /api/dashboard/locations/{id} | Close (soft delete). 204 |
Staff
| Method | Path | |
|---|---|---|
GET | /api/dashboard/staff | List |
POST | /api/dashboard/staff | Create. 201 |
GET | /api/dashboard/staff/{id} | One staff member |
PUT | /api/dashboard/staff/{id} | Update |
DELETE | /api/dashboard/staff/{id} | 204 |
POST | /api/dashboard/staff/{id}/pairing-token | Mint the QR a scanner device pairs with |
DELETE | /api/dashboard/staff/{id}/device | Unpair — the "lost phone" button. Idempotent, never a 404 |
Merchant profile
| Method | Path | |
|---|---|---|
GET | /api/dashboard/tenant | The public business page's content |
PUT | /api/dashboard/tenant | Full replacement. OWNER only |
POST | /api/dashboard/tenant/images/{kind} | Logo or cover. 201. OWNER only |
DELETE | /api/dashboard/tenant/images/{imageId} | 204. OWNER only |
GET | /api/dashboard/tenant/api-key | Partner key status |
POST | /api/dashboard/tenant/api-key | Mint or rotate. OWNER only |
DELETE | /api/dashboard/tenant/api-key | Revoke. OWNER only |
Custom fields
| Method | Path | |
|---|---|---|
GET | /api/dashboard/custom-fields | List the merchant's question bank |
POST | /api/dashboard/custom-fields | Create. 201 |
PUT | /api/dashboard/custom-fields/{id} | Update |
DELETE | /api/dashboard/custom-fields/{id} | 204 |
A field is defined once per merchant and selected per Program; the answers belong to the enrollment, not to the person.