Create a reservation (staff side)
/api/reservationsA sitting taken at the host stand or over the phone. Always inserted as confirmed, never hold; a hold is a guest's half-finished checkout with an expiry and has no meaning for something staff enter deliberately.
turnMinutes is a free field here, unlike an appointment's duration: a reservation has no service to snapshot a length from, which is exactly why 0011 gave it its own tables. ends_at is derived from it. tableId may be null; a venue that caps covers without assigning tables works as-is.
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
Request Body
application/json
The client is given one of two ways, matching the picker on the dashboard: either customerId for someone already on the roster, or customerName and customerPhone (plus optionally an email) to find-or-create one. When customerId is present the typed fields are ignored entirely.
customerPhone is required on the typed branch and only there. The check lives in resolveOrCreateCustomer, the single writer that creates a client from typed details, so it applies identically here, on POST /api/reservations and on POST /api/clients. Picking an existing client short-circuits to their id and never reaches it, which is what keeps a regular who predates the rule bookable.
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/reservations" \ -H "Content-Type: application/json" \ -d '{ "partySize": 1, "turnMinutes": 5, "startsAt": "2019-08-24T14:15:22Z" }'{ "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"}Replace a named service period (admin, or manage_services) PUT
Writes a whole period at once: "the period called `name` now runs on exactly these days, with these settings". No active period for a weekday means an empty availability grid that day, so this is the endpoint a venue's bookable times live or die by. **PUT, and wholesale, on purpose.** A day of a period is not an entity an operator names; the PERIOD is, and it is identified by its `name`. There is nothing here for a per-row create to be idempotent about, and the old `POST` (one weekday per call) is what made a restaurant serving lunch and dinner all week fourteen separate writes. **One statement, therefore one transaction.** The whole replacement happens inside `book_replace_service_period_group()` (migration 0029) rather than as a PostgREST delete followed by an insert. That is not tidiness: `computeReservationSlots` returns nothing for a day with no periods, so a delete that landed without its insert would take the venue's booking page **offline** until someone re-saved, not merely degrade it. On any error nothing is written and nothing is lost. Gated to admin, or a staff login granted `manage_services` (migration 0082), hospitality's equivalent of the appointments services routes, and gated the same way: an empty `days` array deletes the group, so this one call is as destructive as it is creative.
Add a floor server POST
A server (0097) is a label with a section colour: a name on the floor map, bookable by nothing. The colour is assigned here, round-robin over a fixed palette chosen so the map's white initials stay readable in both themes; callers do not pick colours. Front-of-house work, so no admin gate: the same trust level as moving a party between tables.