1. Read reference data
Use the catalog endpoints withCATALOG_READ to obtain restaurant IDs for
rooms, shifts, tables, prescribers and discounts. IDs belong to the key’s
restaurant. The catalog is not a list of bookable slots: it may contain
staff-only tables or inactive discounts. Availability determines what can be
booked.
2. Search availability
WithAVAILABILITY_READ, call GET /availability using start_at_from,
start_at_to and party_size. Optional shift_id and room_id narrow the
search. Use ISO 8601 timestamps with an explicit offset; use --data-urlencode
when building query strings so a + offset is preserved.
start_at, shift_id and
the room, when present, from an actual returned slot. The response also supplies
its end_at and duration_minutes. POST /availability/check checks one exact
slot; 200 with data.available: false is a normal unavailable result.
Availability does not reserve capacity. Creation rechecks the slot and may
return 422 if it is no longer bookable.
3. Create the reservation
CallPOST /reservations with RESERVATIONS_WRITE. The following is a request
body; replace the example slot with one returned by availability.
true. Setting them to false
suppresses customer notifications and payment-link sending; it does not make the
request a dry run, prevent payment rows or disable restaurant-side
notifications.
customer: null creates an anonymous reservation. Otherwise, creation requires
customer.name. source defaults to WEBSITE. Deposit requirements can be
inferred from the shift; explicit prepaid product or extra selection is not
supported by v1. Inspect the returned status and payments: 201 is not a
promise of confirmation. total_amount_paid records an amount in the smallest
currency unit; it does not charge a customer. Privileged bypass flags and
initial_status are detailed in scopes and the
create endpoint.
Recover from an uncertain result
external_id must be unique within the restaurant. Duplicates return 409, not
the original successful response. After a timeout, search GET /reservations by
external_id with RESERVATIONS_READ before creating again. Keep the same
external reference. There is no Idempotency-Key header contract.
4. Read and update
GET /reservations supports filters and pagination: page starts at 1;
per_page defaults to 25 and cannot exceed 100. GET /reservations/{id}
returns detail. Both require RESERVATIONS_READ; sensitive fields need the
additional scope.
PATCH /reservations/{id} requires RESERVATIONS_WRITE. Omitted fields remain
unchanged. customer: null disconnects the customer; { "id": "..." } connects
an existing customer from this restaurant. Customer fields without an ID update
the linked customer itself, which can affect other reservations referencing that
customer. If none is linked, provide a name to create and connect one.
POS service locks can reject updates with 409 and details.locked_fields.
Business-rule failures return 422. Cancellation is a separate endpoint.
5. Cancel
CallPOST /reservations/{id}/cancel with RESERVATIONS_CANCEL, JSON content
type and a JSON body: {} or { "reason": "Guest requested cancellation" }.
The resulting status is CANCELED_BY_RESTAURANT. An already canceled
reservation is returned without changing its existing cancellation status or
reason. POS service locks can reject cancellation with 409.
