Make your first booking in 6 steps. This guide takes you from zero to a confirmed booking using the Bookable API.
You'll need:
- A
client_idandclient_secret— log in to the Bookable Portal to find your credentials
| Sandbox | Production | |
|---|---|---|
| Base URL | https://api-sandbox.bookabletech.com | https://api.bookabletech.com |
| Auth endpoint | https://auth-sandbox.bookabletech.com/oauth/token | https://auth.bookabletech.com/oauth/token |
Start with sandbox credentials during development.
The Bookable API uses OAuth 2.0 Client Credentials. Exchange your client_id and client_secret for a short-lived bearer token.
curl -X POST https://auth.bookabletech.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "api.bookabletech.com"
}'Example response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"scope": "venue:read venue-booking:create",
"expires_in": 3600,
"token_type": "Bearer"
}Tokens are valid for 1 hour. See Authentication for a full token manager with caching.
Venues are scoped to operators you have onboarded. An operator is the hospitality business whose venues you want to make bookable. You onboard them once, supply their TMS credentials, and their venues immediately become available via GET /venues.
curl -X POST https://api.bookabletech.com/operators \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"businessName": "Acme Restaurant Group",
"partnerSource": "YourTradingName"
}'Example response:
{ "id": 3, "businessName": "Acme Restaurant Group", "createdAt": "2025-03-01T10:00:00Z", "updatedAt": "2025-03-01T10:00:00Z" }Store the id — you need it in the next sub-step.
The operator must tell you which TMS they use and provide their credentials. Bookable supports Collins (CO), SevenRooms (SR), and Zonal (ZO). The example below uses Collins.
OPERATOR_ID=3
curl -X POST "https://api.bookabletech.com/operators/${OPERATOR_ID}/tms-credentials" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tmsSlug": "CO",
"bearer": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"externalOperatorId": "514ada610df690b6770000fd",
"active": true
}'Once active: true, the operator's venues are available in GET /venues. For SevenRooms and Zonal credential fields, and full management endpoints, see the Operator Setup guide.
Use GET /venues to find venues. Filter by city, date, or other criteria to narrow results.
curl "https://api.bookabletech.com/venues?city=London&date=2025-08-15" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Example response (truncated):
{
"data": [
{
"id": "29|X9|275cc44dd2e2496fba44857c9257443a",
"name": "The Grand Table",
"location": { "city": "London" },
"products": [
{
"compositeId": "29|CO|275cc44dd2e2496fba44857c9257443a|d99128c546b34b619c4477b712869f2b",
"productName": "Table Reservation"
}
]
}
]
}The compositeId inside products[] is what you need for the next steps. Each product has its own compositeId.
Before creating a booking, verify that the venue has slots available for your desired date, time, and party size.
GET /venues/{compositeId}/availability?date=YYYY-MM-DD&startTime=HH:MM&partySize=NCOMPOSITE_ID="29|CO|275cc44dd2e2496fba44857c9257443a|d99128c546b34b619c4477b712869f2b"
curl "https://api.bookabletech.com/venues/${COMPOSITE_ID}/availability?date=2025-08-15&startTime=19:00&partySize=4" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Example response:
{
"name": "Table Reservation",
"times": [
{
"time": "19:00",
"duration": 90,
"type": "book",
"productId": "29|CO|275cc44dd2e2496fba44857c9257443a|d99128c546b34b619c4477b712869f2b"
},
{
"time": "19:30",
"duration": 90,
"type": "request",
"productId": "29|CO|275cc44dd2e2496fba44857c9257443a|d99128c546b34b619c4477b712869f2b"
}
]
}If times is null or empty, there are no slots available — try a different date. Use the type from your chosen slot (book or request) in the next step.
Submit the booking with the guest details and the type from Step 4.
POST /venues/{compositeId}/bookingcurl -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_ORDER_ID" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com",
"phone": "+441234567890",
"partySize": 4,
"date": "2025-08-15",
"time": "19:00",
"type": "book",
"notes": "Window table if possible"
}'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"
}The booking status will be Confirmed. Store the id for future retrieval or cancellation, and the operatorBookingId for guest-facing communications.
The booking status will be Pending. The venue operator will review and confirm or decline. Listen for status changes via webhooks — the booking.confirmed and booking.declined events will fire when the operator responds.
| HTTP Status | Meaning |
|---|---|
400 | Invalid request body — check required fields |
401 | Token expired or invalid — refresh your token |
404 | Venue not found or compositeId incorrect |
409 | No longer available at the requested time |
422 | Business rule violation (e.g. party size out of range) |
See the Error Catalog for the full list of error codes and resolution steps.