> ## 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.

# Conventions

> Base URL, resource conventions, IDs, money, and list behavior shared across every Developer API endpoint.

The Developer API is a JSON REST API. Every endpoint in this reference is grouped in the sidebar by resource — general (ping and `/me`), locations, connections, menu, delivery zones, webhooks, orders, bookings, waitlist, and feedback. 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:

```
https://api.staging.maple.inc/v1   # Sandbox — development and testing
https://api.maple.inc/v1           # Production — live traffic
```

Use the credential that matches the host (`mpk_test_…` in the sandbox, `mpk_live_…` in production). See [Environments](https://docs.maple.inc/developer-api/concepts/environments.md).

## Authentication

Send a `Bearer` credential on every request:

```http
Authorization: Bearer mpk_test_…
```

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](https://docs.maple.inc/developer-api/concepts/authentication.md).

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

```json
{ "object": "list", "data": [ /* … */ ] }
```

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:

| Parameter        | Meaning                                                                                                                                                  |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `since`          | Exclusive ISO 8601 (UTC) checkpoint. With `since`, results are **oldest first** so you can drain forward without skipping orders that share a timestamp. |
| `starting_after` | The last order id (`ord_…`) from the previous page. Requires `since`, and the order must belong to your app.                                             |
| `limit`          | Page size, 1–100. Defaults to 100.                                                                                                                       |

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`](https://docs.maple.inc/developer-api/guides/receive-orders.md#catching-up-after-downtime) for a live order, or the [event ledger and replay](https://docs.maple.inc/developer-api/concepts/webhooks.md#the-event-ledger) 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](https://docs.maple.inc/developer-api/concepts/errors.md).

## 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](https://docs.maple.inc/developer-api/guides/take-bookings.md#request-limits).
