This guide covers the full booking lifecycle: creating, retrieving, updating, and cancelling reservations.
POST /venues/{compositeId}/bookingCOMPOSITE_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,
"date": "2025-08-15",
"time": "19: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",
"venueGroupName": "The Grand Table Group"
}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.
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 }
]
}
]
}
}
]
}The availability response filters this catalogue per time slot. Each entry in times[] includes a preOrderItems object:
allowedPackages / allowedMenus | Meaning |
|---|---|
"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.
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.
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"For ongoing status tracking, prefer webhooks over polling.
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.
DELETE /venues/bookings/{bookingId}Cancellation is permanent. The booking status changes to Cancelled and a booking.cancelled webhook fires if configured.
curl -X DELETE "https://api.bookabletech.com/venues/bookings/${BOOKING_ID}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 204 No Content on success| HTTP Status | Meaning |
|---|---|
401 | Token expired — refresh and retry |
403 | You don't have permission to modify this booking |
404 | Booking not found |
409 | Booking cannot be modified in its current state |
422 | Business rule violation (e.g. cancellation window has passed) |
See the Error Catalog for detailed error codes.
- Quickstart — first booking in 5 steps
- Webhooks — real-time booking status events
- Bookings API Reference