> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bookingshake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bookings

> Read bookings (dossiers) and their events: GET /bookings and GET /bookings/{id}

## Overview

A **booking** (dossier) is the unit your teams manage in BookingShake: one or several **events** (a date, a time slot, a space, a number of guests) created and handled together, with a contact, a company, a status and its financial documents.

The API exposes bookings **read-only**:

* `GET /bookings/{id}` returns one booking with its nested `events[]`
* `GET /bookings` lists bookings with cursor pagination and filters

Bookings are created through [`POST /events/create`](/api-reference/quickstart), which returns the `booking_id`, and change notifications are available through the [booking webhooks](/api-reference/webhooks/bookings).

## The booking payload

The same payload shape is served by both endpoints and by the `data` field of `booking.*` webhooks.

```json theme={null}
{
  "id": "3f6c1b2a-9d4e-4f7a-b0c8-2e5a7d9f1c3b",
  "public_id": "nX4fQ2hB",
  "name": "Acme annual seminar",
  "status_id": "Zx8Kp3Qm7nRt",
  "source_id": "JKd8f3mP2xQw",
  "contact_id": "cli_7hJk2Pq9Rt4M",
  "account_id": "acc_5Fg8Nw1Zx6Vb",
  "owner_ids": ["usr_a1B2c3D4"],
  "created_at": 1756000000000,
  "updated_at": 1756100000000,
  "canceled_at": null,
  "comments": "Recurring client, monthly invoicing",
  "custom_9b2c1de45f": "20000-50000",
  "quote_ids": ["fil_q1A2b3C4"],
  "invoice_ids": ["fil_i9Z8y7X6"],
  "payment_ids": ["pay_1Aa2Bb3C", "pay_4Dd5Ee6F"],
  "events": [
    {
      "id": "rsv_8fj2kQpL0aXc",
      "date": "2026-09-10",
      "start_time": "09:00",
      "end_time": "17:00",
      "space_id": "Lp9Xt2Kj5mQw",
      "secondary_space_ids": [],
      "event_type": "Seminar",
      "pax": 40,
      "comments": "Projector needed",
      "created_at": 1756000000000,
      "custom_c4d5e6f7a8": null
    }
  ]
}
```

### Conventions

* **References are bare IDs.** Resolve `status_id`, `source_id` and `space_id` with `GET /status`, `GET /sources`, `GET /spaces` (these endpoints expose `type`, `is_canceled`, `slug`, `is_default`... so you never hardcode venue-specific IDs). Follow `contact_id`, `account_id`, `invoice_ids`, `payment_ids` to their own endpoints.
* **Timestamps are Unix milliseconds**, business dates are `YYYY-MM-DD`, empty fields are an explicit `null`.
* **Custom fields** configured for your venue appear as additional `custom_*` properties: booking-level fields (collection `requests`) on the booking, event-level fields (collection `reservations`) on each event. Use `GET /fields` for their definitions.
* `owner_ids` are internal user IDs (the salespeople assigned to the booking), exposed for correlation only.
* `payment_ids` exclude security deposits / pre-authorization holds, consistent with the payments endpoints.

<Warning>
  **Booking ID stability.** `id` matches the `booking_id` of payment and invoice webhooks. It is however **not guaranteed stable for the whole life of a booking**: when a single-event booking gains a second event, BookingShake generates a new group ID. When that happens a `booking.updated` webhook delivers the payload under its new `id`; the event IDs (`events[].id`) never change, so the events you already hold let you recognize the booking and store its new `id`.
</Warning>

## GET /bookings/{id}

```bash theme={null}
curl 'https://api.bookingshake.io/api/bookings/3f6c1b2a-9d4e-4f7a-b0c8-2e5a7d9f1c3b' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

Returns `{ "message": "success", "data": { ...booking } }`. A uniform **404** is returned when the booking does not exist, belongs to another venue, or when the id is an event that is member of a group (bookings are addressed by their booking id, not by member event ids).

## GET /bookings

```bash theme={null}
curl 'https://api.bookingshake.io/api/bookings?limit=25&date_from=2026-09-01&date_to=2026-09-30' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

Response:

```json theme={null}
{
  "message": "success",
  "data": {
    "items": [ { "id": "...", "events": [...] } ],
    "next_cursor": "eyJicmFuY2gi..."
  }
}
```

### Pagination

Cursor-based. Pass `next_cursor` back as the `cursor` parameter until it comes back `null`.

<Note>
  A page may contain **fewer than `limit` items even when more data remains** (an internal scan bound protects very large venues). Always iterate on `next_cursor`; never treat a short page as the end of the listing.
</Note>

### Filters

| Parameter                    | Description                                                                                                                                                             |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`                      | 1 to 100, default 25 (in bookings, not events)                                                                                                                          |
| `cursor`                     | Opaque cursor from the previous page                                                                                                                                    |
| `date_from`, `date_to`       | `YYYY-MM-DD`, inclusive, both required together. A booking matches when **at least one** of its events is inside the window. Sorts the listing by event date ascending. |
| `created_from`, `created_to` | Unix **milliseconds**, inclusive, each optional. Bookings created inside the window.                                                                                    |
| `status_id`                  | Exact status filter                                                                                                                                                     |
| `contact_id`                 | Bookings of a contact                                                                                                                                                   |

**Allowed combinations**: `date_from`/`date_to` alone or with `status_id`; `created_from`/`created_to` combinable with `status_id` OR `contact_id`; `status_id` and `contact_id` are mutually exclusive.

<Note>
  The `updated_at` payload field is reliable **from the feature go-live onward**: modifications are stamped going forward, without backfill. `canceled_at` follows the same rule for bookings cancelled before go-live.
</Note>

## Rate limits

Both endpoints follow the standard read limit (60 requests/minute per API key per endpoint). See [Rate Limiting](/api-reference/rate-limiting).
