Create a range of tables in one request
/api/tables/bulkGenerates prefix + separator + n for every n from from to to inclusive (capped at 50 per batch) and inserts them as one atomic statement. Rejects the whole batch; nothing is created; if any generated name already exists in this org; table names are not unique in the schema, so this is an app-level check on a fresh read, not a database constraint.
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
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/tables/bulk" \ -H "Content-Type: application/json" \ -d '{ "from": 0, "to": 0, "seatsMin": 1, "seatsMax": 1 }'{ "ok": true, "tables": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" } ]}Create a table POST
Unlike services and staff, tables are not part of the cached public booking config; reservation availability is computed live per request, so nothing is revalidated here.
Place a furniture-set piece (a bar, a multi-tabletop banquette) POST
Independent booking (2026-09-10): a piece that renders as ONE object on the floor plan but is backed by N real, separately-bookable rows: one per bar stool, or one per banquette tabletop. Creates a new book_table_link_groups row (`kind='furniture_set'`) and N book_tables rows in one atomic insert; the first row's id is deliberately set equal to the group's own id (the anchor, the only member that ever carries real geometry; see that row's own comment for why no extra column was needed to mark it). Deliberately its own route, not a branch inside POST /api/link-groups: that route gates on the Venue Pro `table_combining` feature, and a furniture-set piece must be placeable on every plan tier. A separate route makes that impossible to leak in by accident. `MAX_COMBINED_TABLES` (the ordinary combine cap) does not apply to this group's kind either, so a whole 12-seat bar can still be booked as one party.