Skip to content
Last updated

Booking Management

This guide covers the full booking lifecycle: creating, retrieving, updating, and cancelling reservations.

Create a booking

POST /venues/{compositeId}/booking
COMPOSITE_ID="29|CO|275cc44dd2e2496fba44857c9257443a|d99128c546b34b619c4477b712869f2b"

curl -X POST "https://api.bookabletech.com/venues/${COMPOSITE_ID}/booking" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-Partner-Reference: YOUR_INTERNAL_REF" \
  -d '{
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "phone": "+441234567890",
    "partySize": 4,
    "dateTime": "2025-08-15T19:00:00+01:00",
    "type": "book",
    "notes": "Anniversary dinner — please add candles"
  }'

Example response:

{
  "id": "29|CO|550e8400e29b41d4a716446655440000",
  "operatorBookingId": "BKA-7X2P",
  "status": "Confirmed",
  "firstName": "Jane",
  "lastName": "Smith",
  "partySize": 4,
  "date": "2025-08-15",
  "time": "19:00",
  "dateTime": "2025-08-15T19:00:00+01:00",
  "venueGroupName": "The Grand Table Group"
}

Send the slot's times[].dateTime from the availability response unchanged as dateTime. date and time are on the venue's trading day (a 00:30 slot under Saturday's date starts on Sunday); dateTime is the real start moment. date + time are still accepted instead (as in the preorder examples below) — send one form, or both only if they agree (BOOK-N-018). Neither → BOOK-N-019; dateTime without a UTC offset → BOOK-N-020.


Preorders

Some venues offer packages (standalone add-ons — a bottle of wine, a tasting platter, a cocktail kit) and menus (structured multi-course offerings where the guest selects specific dishes). Both are submitted inside the preorders field of the booking request.

If products[].preOrderRequired is true for the chosen product, a preorder must be included — the booking will be rejected without one.

Step 1: Get the preorder catalogue

Packages and menus available at the venue are returned in the GET /venues response under data[].preorders.

Example venue response (truncated):

{
  "data": [
    {
      "name": "The Grand Table",
      "preorders": {
        "packages": [
          {
            "id": "5888a5afc71620e04002d5bb",
            "name": "Prosecco on arrival",
            "price": 8.50,
            "type": "drink"
          },
          {
            "id": "62692e90d2cf1f163744efc4",
            "name": "Sharing charcuterie board",
            "price": 18.00,
            "type": "food",
            "sub_type": "starter"
          }
        ],
        "menus": [
          {
            "id": "68a5f2eee07ae30fcd653b03",
            "name": "Set Menu",
            "description": "2 or 3 courses from our seasonal menu",
            "items": [
              { "packageId": "62c6c9f532c7cc7e4265dfdc", "name": "Pan roasted Padron peppers (V)", "price": 9.00 },
              { "packageId": "619d19eb40e1512ebb03b378", "name": "Beef fillet with truffle jus", "price": 28.00 }
            ]
          }
        ]
      }
    }
  ]
}

Step 2: Check which preorders are valid for your slot

The availability response filters this catalogue per time slot. Each entry in times[] includes a preOrderItems object:

allowedPackages / allowedMenusMeaning
"all"Every item in the venue catalogue is available
"set"Only the IDs listed in packageIds / menuIds are available
"none"No packages / menus for this slot

Example availability response (truncated):

{
  "times": [
    {
      "time": "19:00",
      "type": "book",
      "preOrderItems": {
        "allowedPackages": "set",
        "packageIds": ["5888a5afc71620e04002d5bb"],
        "allowedMenus": "all",
        "menuIds": null
      }
    }
  ]
}

In this example, only the 5888a5afc71620e04002d5bb package is allowed at 19:00, but all menus are available.

Step 3: Add preorders to the booking

Include a preorders object in the booking request body.

Packages — supply the package id and quantity:

curl -X POST "https://api.bookabletech.com/venues/${COMPOSITE_ID}/booking" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "phone": "+441234567890",
    "partySize": 4,
    "date": "2025-08-15",
    "time": "19:00",
    "type": "book",
    "preorders": {
      "packages": [
        { "id": "5888a5afc71620e04002d5bb", "quantity": 4 }
      ]
    }
  }'

Menus — supply the menu id, quantity, and optionally items[] to pre-select specific dishes. Each item uses the packageId from the menu's items[] catalogue:

curl -X POST "https://api.bookabletech.com/venues/${COMPOSITE_ID}/booking" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "phone": "+441234567890",
    "partySize": 4,
    "date": "2025-08-15",
    "time": "19:00",
    "type": "book",
    "preorders": {
      "menus": [
        {
          "id": "68a5f2eee07ae30fcd653b03",
          "quantity": 4,
          "items": [
            { "id": "62c6c9f532c7cc7e4265dfdc", "quantity": 2 },
            { "id": "619d19eb40e1512ebb03b378", "quantity": 2 }
          ]
        }
      ]
    }
  }'

Omitting items is valid — the venue will send the guest a link after booking to complete their menu selections.

Packages and menus can be combined in the same request using both preorders.packages and preorders.menus together.


Retrieve a booking

GET /venues/bookings/{bookingId}

Use this to poll the current status of a Pending booking, or to sync booking details into your system.

BOOKING_ID="29|CO|550e8400e29b41d4a716446655440000"

curl "https://api.bookabletech.com/venues/bookings/${BOOKING_ID}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

The response carries dateTime (the real start moment) alongside date and time, and payments — the payments recorded in Bookable for the booking, oldest first (id, optionType, amount in pence, status, updatedAt). payments is omitted when none is recorded in Bookable, which does not mean the booking is unpaid.

For ongoing status tracking, prefer webhooks over polling.


Update a booking

PATCH /venues/bookings/{bookingId}

Updates use JSON Patch (RFC 6902) with Content-Type: application/json-patch+json. Only confirmed bookings can be updated.

Patchable fields: date, time, partySize, duration, firstName, lastName, email, phone, notes, preorders/packages, preorders/menus

curl -X PATCH "https://api.bookabletech.com/venues/bookings/${BOOKING_ID}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json-patch+json" \
  -d '[
    { "op": "replace", "path": "/partySize", "value": 6 },
    { "op": "replace", "path": "/notes", "value": "Now 6 guests — please arrange accordingly" }
  ]'

If you're changing date, time, or partySize, check availability first — the update will be rejected if the new slot is unavailable.

/payments is read-only. An update can also be refused with:

CodeStatusMeaning
BKRUL-N-007400An operator booking_window rule stops amending a confirmed booking this close to its start
VENUE-N-009404The venue has closed — the booking can no longer be amended, only cancelled

Cancel a booking

DELETE /venues/bookings/{bookingId}

Cancellation is permanent. The booking status changes to Cancelled and a booking.updated webhook fires (if configured) carrying the booking with status: cancelled.

  • Cancelling still works at a closed venue (one returning VENUE-N-009 elsewhere) — use it to unwind bookings you hold.
  • 400 BKRUL-N-008: an operator booking_window rule stops cancelling a confirmed booking this close to its start. Not retryable — contact the venue to cancel.
curl -X DELETE "https://api.bookabletech.com/venues/bookings/${BOOKING_ID}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 204 No Content on success

Error handling

HTTP StatusMeaning
400Invalid request, or an operator booking rule refused it (e.g. BKRUL-N-007 amend / BKRUL-N-008 cancel window closed)
401Token expired — refresh and retry
403You don't have permission to modify this booking
404Booking not found; VENUE-N-009 = venue closed (amend refused, cancel still works)
409Booking cannot be modified in its current state
422Business rule violation

See the Error Catalog for detailed error codes.