MAPLE_BASE to your environment’s base URL, including /v1, and MAPLE_KEY to a matching credential. See Environments. You need bookings:read for discovery and reads, and bookings:write for holds and guest-side writes.
1. Read the booking profile
enabled, provider, and capabilities. Native locations have a hold_ttl_seconds of 300 by default. Provider-managed locations report null because the provider owns expiry; always use the hold’s expires_at.
2. Search availability
start and end are venue-local wall-clock times, not UTC instants. Choose a future window no longer than 31 days:
data entry contains an opaque slot_token, starts_at in UTC, starts_at_local, and any quoted cancellation policy. Tokens expire after 15 minutes. Save the selected token unchanged; never reconstruct it from the displayed time.
A 422 is a business outcome, not an empty result: inspect code and details for party-size bounds, booking-window restrictions, or a large-party inquiry contact.
3. Hold the slot
id as the hold ID. The hold claims capacity until expires_at; create the booking before then. If the guest abandons the flow, release a native hold with DELETE /v1/booking_holds/{holdId}. A consumed hold answers 409 hold_consumed instead of reporting that its capacity was released.
Each app may have ten live holds per location, enforced atomically across concurrent requests. Native and provider holds count, including provider acquisitions still awaiting an outcome. A different app cannot release or consume your hold, even if both apps are granted the location; those requests return 404.
If a provider hold response is lost, its quota reservation has a conservative 24-hour quarantine after the last possible provider attempt. Once that deadline passes, it no longer consumes quota. The original operation stays recorded and cannot restart after its replay window; this does not clear an uncertain booking create/change/cancel operation.
All partner hold IDs use bkh_…. Repeating the same slot_token replays your live hold rather than acquiring another lock. OpenTable release remains a no-op: the provider lock and its quota usage remain until expiry or consumption. Check booking_profile.capabilities.hold_release before promising an early release.
4. Create the booking
booking resource. At native locations, its initial status is confirmed or requested, according to the venue’s acceptance policy. Save its id and version. Guest phone is required; the current service accepts dialable North American numbers.
The persisted hold supplies the authoritative quote for both native and provider-managed bookings. You can omit slot_token; it remains accepted as an optional field for existing integrations.
5. Change or cancel
For a native change, search again withchanging_booking_id=<booking id>. This excludes the booking’s current capacity claim. Send the chosen token to POST /v1/bookings/{id}/change, with a new idempotency_key and optionally expected_version.
Provider-managed locations reject changing_booking_id with 422 capability_unsupported. Their direct-change path takes a token from an ordinary availability search instead. OpenTable supports time/party changes, but not guest-note changes or structured intake_answers; those fields return 422 capability_unsupported rather than being silently dropped.
cancelled_by_guest. A stale version answers 409 stale_version with details.expected and details.actual. Provider-backed writes claim the mirrored booking before provider I/O; a competing write can answer 409 operation_in_progress while that claim is active. A successful replay runs before the version check, so its original expected_version does not prevent replay.
Read the booking again before deciding whether to submit a different change. Cancellation and reschedule policy refusals include a reason in details. Version claims serialize writes through Maple; they do not lock out changes made directly in the provider’s own tools.
Request limits
The default per-app, per-environment budgets are 60 availability searches/minute and 300 other booking requests/minute. The budgets are independent and apply across granted locations. Existing order/menu routes are not included. A429 includes both a Retry-After header and retry_after in its JSON body; wait before retrying. Maple can adjust these deployment-level budgets.
Follow changes
Subscribe to booking webhooks. UseGET /v1/bookings/{id} for current state, or the incremental list to catch up after downtime. Venue operations and the live-floor read are described in Booking lifecycle.