Skip to main content
The Developer API is a JSON REST API. Every endpoint in this reference is grouped in the sidebar by resource — auth, locations, connections, menu, orders, and webhooks. This page covers the conventions they all share; the linked concept pages go deeper.

Base URL

Each environment has its own host, both served under the /v1 prefix:
Use the credential that matches the host (mpk_test_… in the sandbox, mpk_live_… in production). See Environments.

Authentication

Send a Bearer credential on every request:
Send your API key (mpk_test_… for the sandbox, mpk_live_… for production) as the bearer token. GET /v1/me returns the app, environment, and scopes for any key. Full detail in Authentication.

Resource conventions

  • Opaque IDs carry a type prefix — str_ (location), ord_ (order), dws_ (webhook subscription), evt_ (event), and so on. Treat them as opaque strings.
  • Money is integer USD cents. 450 means $4.50. Never parse amounts as floats. Currency codes are always uppercase ISO‑4217 (USD).
  • Field casing. Menu payloads use camelCase (externalId, minSelections, modifierGroups); order and webhook payloads use snake_case (fulfillment_type, menu_entity_id, payment_status). A line item’s menu_entity_id carries the externalId you published for that menu object.
  • Timestamps on events and orders are Unix seconds (the created field).
  • Object typing. Most resources carry an object field (order, location, event, …) so you can tell them apart.

Lists

List endpoints return an envelope with an object of list and a data array:
Lists return a bounded window with a has_more flag rather than a total count:
  • GET /v1/orders returns up to 100 orders across your connected locations. Newest first by default; see the catch-up parameters below.
  • GET /v1/webhook_events returns up to 50 events, most recent first.
  • GET /v1/locations and GET /v1/webhook_subscriptions return the full set for your app.

Draining orders after downtime

GET /v1/orders takes three optional query parameters, built for reconciling a backlog: Request GET /v1/orders?since=<checkpoint>&limit=100, then repeat with starting_after set to the last returned order id while has_more is true. There is no location_id filter — filter client-side on location_id. To make Maple redeliver a webhook rather than pull the order yourself, use POST /v1/orders/{orderId}/resend for a live order, or the event ledger and replay when the original event identity matters.

Listing bookings

GET /v1/bookings reads bookings across granted locations, optionally narrowed by location_id. Use start/end as ISO-8601 instants spanning at most 31 days; with neither, the window is the next seven days. Alternatively, updated_since drains updates oldest-first and cannot be combined with a time window. To find the booking a guest is calling or texting about, pass location_id with phone, confirmation_code, or both. The phone is normalized first, so (415) 555-0142 and +14155550142 match the same guest. Without a window, a lookup matches bookings at any time, ordered by slot start; add start/end to narrow it to upcoming days. At a provider-managed location a lookup with phone also checks the provider, so reservations made directly there are found; a code-only lookup covers the ones Maple already knows about. A lookup without location_id returns 400 location_required, and an unusable phone returns 400 invalid_phone. Page with limit (1–100, default 20) and the previous page’s opaque next_cursor as starting_after. Keep filters unchanged across pages. A default window stays fixed across its pages. For checkpoint polling, overlap by a few seconds and dedupe by booking id and version. Bookings use bkg_… IDs and waitlist entries bkw_…; all partner holds use bkh_…, including provider-managed holds. Provider lock tokens are not exposed. Booking resources use snake_case; booking configuration uses camelCase. created is Unix seconds; starts_at, updated_at, expires_at, published_at, and floor as_of are ISO-8601 instants. Availability search bounds are venue-local wall-clock values instead.

Errors

Errors use standard HTTP status codes with a JSON body carrying a stable _tag and a human-readable message. Branch on the tag, not the message. The full catalog is in Errors.

Rate limits

Bookings default to 60 availability searches/minute and 300 other booking requests/minute (waitlist calls included), independently per app/environment across locations. Each app also has an atomic limit of ten live or pending holds per location. A 429 carries Retry-After and JSON retry_after in seconds. These booking budgets do not apply to existing order/menu routes; OAuth token requests have their own limit. Respond to webhooks asynchronously, avoid tight polling loops, and preserve the original idempotency key when retrying writes. See Take bookings.