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

# Booking lifecycle

> Booking statuses, guest and venue permissions, provider limitations, and the live floor.

A booking is a party's reservation at a location. Its `status` records the lifecycle; `service_state` is a separate front-of-house detail and may be `null`. Use the lifecycle verbs rather than writing either field directly.

## Statuses and permissions

| Status                   | Meaning                                                        |
| ------------------------ | -------------------------------------------------------------- |
| `requested`              | The venue must accept or decline the request                   |
| `confirmed`              | The reservation is accepted                                    |
| `seated`                 | The party is seated                                            |
| `completed`              | Service has finished                                           |
| `declined_by_venue`      | The venue declined the request                                 |
| `cancelled_by_guest`     | The guest, or a partner acting for the guest, cancelled        |
| `cancelled_by_venue`     | The venue cancelled                                            |
| `cancelled_unattributed` | A provider reported cancellation without identifying the actor |
| `no_show`                | The party did not arrive                                       |

`bookings:write` authorizes holds, create, change, and guest-side cancellation. It does not authorize venue actions. An app with `bookings:read` can read all bookings at its granted locations, not only bookings it created. Venue-internal notes are never included.

## Act for the venue

These endpoints require **`bookings:manage`** and a location grant:

| Endpoint suffix on `/v1/bookings/{id}` | Legal transition                  |
| -------------------------------------- | --------------------------------- |
| `/confirm`                             | `requested` → `confirmed`         |
| `/decline`                             | `requested` → `declined_by_venue` |
| `/seat`                                | `confirmed` → `seated`            |
| `/complete`                            | `seated` → `completed`            |
| `/no_show`                             | `confirmed` → `no_show`           |

Send `POST` with `{}` or `{ "expected_version": 3 }`. Each response is the updated full booking. A stale version answers `409 stale_version`; an illegal transition answers `409 illegal_transition` with `details.from_status`. The audit records the app acting for the venue on the `api_partner` channel. The client cannot select its own actor or elevate a `bookings:write` request.

OpenTable does not support these venue write-backs. It answers `422 capability_unsupported`; check the location's profile capabilities before offering a venue action. Resy and SevenRooms are not served booking gateways.

## Read the live floor

`GET /v1/locations/{locationId}/booking_floor` requires `bookings:read` and is available only at enabled Maple-native locations with authored geometry.

The response contains `as_of`, `time_zone`, `tables`, `areas`, and `summary`. Tables report their current state (`free`, `reserved`, `held`, `seated`, or `maintenance`), the covering party in `current`, and their next claim within 24 hours in `next`.

* A future reservation does not make a table occupied now: it can be `free` with a non-null `next`.
* `current.guest` contains separate first/last names and `phone_last_four`, never full phone or venue notes. Follow `booking_id` to read the booking when needed.
* Holds have no booking ID. Their `booking_id` is `null`; internal hold IDs are not exposed on the floor.
* `ends_at` is `null` when a seated party has overstayed its planned turn; the API does not promise when it will leave.
* `listed: false` keeps an occupied table visible after it was removed from the current plan. Such parties contribute to `off_plan_parties`.
* Seat bounds or area capacity are `null` when not known. A combination's party counts once in area occupancy, not once per table.

Read on demand or poll at intervals of **at least 15 seconds**. Use [booking webhooks](/developer-api/webhook-events#booking-events) as a change signal and the floor as a reconciliation read. There is no floor webhook or waitlist API in this release.

## Events describe changes, payloads describe dispatch-time state

Each booking transition has its own stable event identity per recipient app/environment. The embedded booking is its latest state when the event is first recorded for that recipient, not a historical transition snapshot. For example, a delayed `booking.created` event can embed a booking already cancelled. `previous_status` is `null` in this version.

Dedupe deliveries by event ID. Reconcile booking state by `id` and `version`; do not infer historical state solely from the event name or assume delivery order.
