Create a new booking
POST /api/bookings
Success: 200 OK
- Products: Operator (
FOH), Consumer (CONSUMER) (any one of these products, not all) - Features: Online Bookings (
ONLINEBOOK), Front of House Generic Access (FOHGENERIC) (any one of these features, not all)
Overview
Converts one or more temporary booking leases into confirmed bookings, generating the associated sales invoices in the process. This is the final call in the booking flow — by the time you reach it you must already hold a valid lease and a matching pricing quote.
Because a lease expires, treat this call as time-sensitive: if it returns 422, the slot
was taken or the lease lapsed between quoting and confirming, and you must restart from
availability.
Use this endpoint to:
- Complete a booking from a lease you created earlier
- Confirm several slots in a single atomic-per-item request
- Generate invoices and payment records alongside the booking
- Finalise group bookings that include additional bookees
Authenticate first — see Authenticating with Gladstone APIs.
Endpoint
POST {base_url}/api/bookings
{base_url} is the environment URL issued to your integration, for example
https://yourorganisation.gladstonego.cloud.
Request headers
| Name | Required | Description |
|---|---|---|
Authorization | Yes | Bearer {accessToken} from API Key Authentication. |
X-Use-SSO | Yes | Always true for partner integrations. |
Content-Type | Yes | application/json |
Request body
The body wraps a list, so a single request can confirm several leases at once.
| Field | Type | Required | Description |
|---|---|---|---|
bookings | array | Yes | One entry per lease being confirmed. An empty array is rejected with 400. |
bookings[].leaseId | string | Yes | The lease returned by the create-lease call. Single-use — a lease cannot be confirmed twice. |
bookings[].bookingId | integer | No | Existing booking id when amending rather than creating. Omit or send 0 for a new booking. |
bookings[].memberId | integer | Yes | The member the booking belongs to. |
bookings[].payingMemberId | integer | No | The member being charged, when this differs from memberId — for example a parent paying for a child. Defaults to memberId. |
bookings[].pricingQuote | object | Yes | The signed quote obtained from pricing. Must match the lease, or the request is rejected. |
bookings[].pricingQuote.memberId | integer | Yes | Member the quote was issued for. |
bookings[].pricingQuote.totalPrice.amount | decimal | Yes | Total amount payable. |
bookings[].pricingQuote.totalPrice.currency | string | Yes | ISO currency code. Maximum 10 characters. |
bookings[].pricingQuote.breakdown | object | No | Per-price-level breakdown of the total. |
bookings[].pricingQuote.paidForbyUsageSub | string | No | Set when the booking is covered by a usage-based subscription rather than being charged. |
bookings[].pricingQuote.usagesRemaining | integer | No | Remaining usages on the covering subscription. |
bookings[].pricingQuote.signature | string | Yes | Signature over the quote. Pass through unchanged. |
The pricingQuote is signed. Do not construct or modify it by hand — pass through
the object exactly as pricing returned it, or the signature check fails.
Sample request
curl -X POST 'https://yourorganisation.gladstonego.cloud/api/bookings' \
-H 'Authorization: Bearer eyJhbGciOi...' \
-H 'X-Use-SSO: true' \
-H 'Content-Type: application/json' \
-d '{
"bookings": [
{
"leaseId": "b7f3c1e2-9a44-4f2b-8c17-0d5e9a1b6c33",
"memberId": 104728,
"payingMemberId": 104728,
"pricingQuote": {
"memberId": 104728,
"totalPrice": { "amount": 8.50, "currency": "GBP" },
"breakdown": {
"currency": "GBP",
"memberPrice": {
"priceLevelId": "PL-STD",
"totalPrice": 8.50,
"productPrices": [
{
"id": "PRD-BADMIN-45",
"quantity": 1,
"timeBandId": "TB-PEAK",
"amount": 8.50,
"taxCodeId": "T-STD",
"taxRate": 20.0
}
]
}
},
"signature": "9f2b...c41a"
}
}
]
}'Response fields
| Field | Type | Description |
|---|---|---|
bookings | array | One entry per confirmed booking. |
bookings[].leaseID | string | The lease that was consumed. Use it to correlate the response back to your request. |
bookings[].slotReference | string | Reference for the booked slot. |
bookings[].bookingID | integer | The new booking's internal id. Use this for amend and cancel calls. |
bookings[].bookingRef | integer | Customer-facing booking reference. Null when the site does not issue one. |
bookings[].salesInvoiceIds | array | Ids of the invoices raised. Pass these to the payment endpoints to collect payment. |
bookings[].bookeePriceLevels | array | Price level applied to each bookee. |
bookings[].keyBookeeBookingInfo | object | Details of the primary bookee. |
discountDetails | array | Discounts applied across the request. |
discountDetails[].slotReference | string | Slot the discount applied to. |
discountDetails[].discountType | string | The kind of discount applied. |
discountDetails[].discountAmount | decimal | Amount deducted. |
Sample response
{
"bookings": [
{
"leaseID": "b7f3c1e2-9a44-4f2b-8c17-0d5e9a1b6c33",
"slotReference": "SLT-2026-08-14-1900-BC2",
"bookingID": 8842190,
"bookingRef": 449281,
"salesInvoiceIds": [ 1290844 ],
"bookeePriceLevels": [
{ "id": "PL-STD", "description": "Standard", "count": 1, "price": 8.50 }
],
"keyBookeeBookingInfo": {
"priceLevelId": "PL-STD",
"price": 8.50
}
}
],
"discountDetails": []
}{
"unprocessableBookings": [
{
"memberId": 104728,
"slotReference": "SLT-2026-08-14-1900-BC2",
"unprocessableReason": "LeaseExpired"
}
]
}Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | The body is missing, bookings is empty, or a required field is absent. |
401 | Unauthorized | Missing, expired or out-of-scope bearer token. |
422 | Unprocessable entity | The request was well-formed but one or more bookings could not be created — expired lease, slot taken, or a pricing quote that no longer matches. Inspect unprocessableBookings[].unprocessableReason per item. |
429 | Too many requests | Rate limit exceeded. Honour the Retry-After header. |
500 | Internal server error | Unexpected failure. Safe to retry once with the same lease; if the lease was consumed you will receive 422. |
A 422 is partial — some bookings in the request may have succeeded. Always reconcile
the returned bookings array against what you sent rather than assuming all-or-nothing.