Skip to main content
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

bookings:write authorizes holds, create, change, and guest-side cancellation. It does not authorize venue actions, venue-side cancellation, or walk-ins. 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: 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.

Cancel as the venue

POST /v1/bookings/{id}/venue_cancel (bookings:manage) cancels a requested or confirmed booking on the venue’s behalf and returns it as cancelled_by_venue, for host-stand and POS apps. POST /v1/bookings/{id}/cancel (bookings:write) is the guest’s cancel and always lands as cancelled_by_guest, whatever scopes the app holds.
The guest’s cancellation window does not apply to the venue. A stale version answers 409 stale_version; a booking already seated or finished answers 409 not_cancellable with details.reason. The key is scoped to your app, so a retry after a lost response replays the cancel. Maple-native bookings only for now: other bookings answer 422 capability_unsupported.

Seat a walk-in

POST /v1/locations/{locationId}/walk_ins (bookings:manage) seats a party that just arrived and returns the new booking with status: "seated" and channel: "walk_in":
Maple picks the earliest table that fits the party now, as the venue’s own host stand does; there is no force-book. When no table is free, the request answers 409 slot_unavailable, and its message names the next opening; add the party to the waitlist instead. phone must be a number Maple can text. The key is scoped to your app across its locations: a retry with the same key and request returns the same booking even though its table is now taken, and the same key with a different request or location answers 409 idempotency_key_reused. Maple-native locations only (422 capability_unsupported otherwise).

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 as a change signal and the floor as a reconciliation read. There is no floor webhook in this release. The walk-in queue has its own endpoints; see Run the waitlist.

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.