The door-staff guestlist for one experience
/api/experiences/{id}/ticketsEvery ticket sold for this experience, who it's for, and whether it has been admitted. No manage_services gate, unlike the catalog routes above: checking a guest in is an ordinary front-of-house task every role needs at the door. A cancelled booking's ticket stays in the list (a cancelled guest should not simply vanish from what staff see) but never counts toward admitted/total.
Authorization
sessionCookie The dashboard's Supabase Auth session cookie, set at sign-in. Large sessions are split across
numbered chunks (…auth-token.0, .1), so treat this as a cookie family rather than one name.
Every request re-validates it against the Auth server (getUser()), never by decoding the cookie
locally: a JWT nothing has checked is not a credential. Tenancy is then read from the verified
app_metadata.company_id claim and enforced by row-level security; it is never read from request
input, on any route, ever.
role (admin / staff) is deliberately not in RLS. It gates specific actions in route code,
the operations marked admin below, so hiding a button in the UI is cosmetic only, and a route's
own check is the enforcement.
In: cookie
Path Parameters
Experience id.
Response Body
application/json
application/json
application/json
curl -X GET "https://example.com/api/experiences/string/tickets"{ "tickets": [ { "ticketId": "e3e3e8ea-b02a-4536-85a2-a9c90f4ee74f", "token": "b5507016-7da2-4777-a161-1e8042a6a377", "quantity": 0, "seatLabel": "string", "checkedInAt": "2019-08-24T14:15:22Z", "reservationId": "54c41ef9-5629-4a9c-bb0d-10f615966bd0", "reservationStatus": "string", "partySize": 0, "customerName": "string", "customerPhone": "string" } ], "admitted": 0, "total": 0}Remove an experience image DELETE
Deletes the stored object and nulls `image_url`. Storage removal is best-effort and its failure does not fail the request.
Scan or manually check in a ticket POST
One action, two callers: a live QR scan on /scanner sends `token` (extracted from the decoded ticket URL); the guestlist's own manual "Check in"/"Undo" button sends `ticketId` directly. Exactly one of the two is required. A cancelled or never-confirmed booking's ticket is refused outright. Scanning an already-admitted ticket is not an error: the response reports `alreadyCheckedIn: true` rather than re-admitting or refusing, which is the single most useful thing for the door to know (a duplicate ticket, a guest who stepped back out). `undo: true` clears a check-in instead (a mis-scan correction).