Skip to main content

1. Read reference data

Use the catalog endpoints with CATALOG_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

With AVAILABILITY_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.
Dates, offsets and IDs here are illustrative. Copy 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

Call POST /reservations with RESERVATIONS_WRITE. The following is a request body; replace the example slot with one returned by availability.
These two notification flags default to 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

Call POST /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.

6. Receive events

Use the webhook reference for signatures, payloads and coverage limits. Partner API writes do not directly emit these webhooks; do not use a webhook as the required acknowledgement of your own API write.