> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eat-now.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Booking flow

> Search availability, create a reservation and manage its lifecycle.

## 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.

```bash theme={null}
curl --get 'https://app.eat-now.io/api/partner/v1/availability' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  --data-urlencode 'start_at_from=2030-05-20T18:00:00+02:00' \
  --data-urlencode 'start_at_to=2030-05-20T23:00:00+02:00' \
  --data-urlencode 'party_size=2'
```

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.

```json theme={null}
{
  "customer": { "name": "Example Guest", "email": "guest@example.com" },
  "party_size": 2,
  "start_at": "2030-05-20T19:00:00+02:00",
  "shift_id": "REPLACE_WITH_SHIFT_ID",
  "external_id": "your-system-booking-123",
  "send_client_notifications": false,
  "send_payment_link": false
}
```

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](/api-reference/authentication) 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](/api-reference/webhooks) 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.
