Skip to content
Maple

Bookings

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, 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:

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.

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.

{ "expected_version": 1, "idempotency_key": "<unique cancellation key>" }

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":

{
"party_size": 2,
"guest": { "first_name": "Alex", "last_name": "Quinn", "phone": "+12125551234" },
"notes": "High chair",
"idempotency_key": "<unique walk-in key>"
}

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.