Create or update a booking lease
PUT /api/bookings/lease/{uuid}
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
Holds the spaces in a slot while a booking is completed. This is the first call in the
booking flow: create the lease here, price it, then confirm it with
POST /api/bookings, passing this lease's id as leaseId.
You generate the lease id yourself — any GUID — and send it in the path. The same id is
returned in the response body and identifies the lease from then on. Leases expire ten
minutes after they are created by default, so the flow is time-sensitive; confirm
within that window or create a fresh lease. Sites where an operator has enabled
Lease Expiry Override in GO Operator can request a custom lease length with
leaseLengthMinutes.
Calling PUT again with the same uuid replaces the lease rather than adding to it. The
places already held by the existing, unexpired lease are discounted before the capacity
check, so re-leasing the same slot does not count you against yourself; the old lease is
deleted only once the new one has passed every check.
The lease covers one slot, for the member plus any additionalBookees. While a lease for a
slot is being created, the slot is briefly locked, keyed on the
slot reference, so two simultaneous attempts on the same slot do not
both succeed — the second is rejected with 400.
Use this endpoint to:
- Hold spaces in a slot before taking payment
- Extend or amend a hold by re-sending it under the same lease id
- Hold spaces for a guest who is not a member, by sending
member.idof0 - Hold extra spaces for a party activity through
additionalBookees
Endpoint
PUT {base_url}/api/bookings/lease/{uuid}
{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
uuid | string | Yes | The lease id, which you generate: any GUID in 8-4-4-4-12 form. A value that does not parse as a GUID is rejected with The given lease ID of {uuid} must be a GUID. Re-sending the same value replaces the existing lease; use a fresh GUID for a separate hold. This is the value returned in the response and the one you pass as leaseId when confirming the booking. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes | Ignored. The lease is always identified by the uuid in the path, so sending a different GUID here has no effect. |
member | object | Yes | Who the lease is held for. Always required, including for guest holds — in that case send it with an id of 0 and the names filled in. |
member.id | integer (int32) | Yes | The member the lease belongs to, or 0 for a guest who has no membership record. A non-zero value must be an existing member (404 Member ID {id} does not exist) and must be the member the token was issued for, or one of their linked members — otherwise Cannot create lease for Member Id {id} as this member is not logged in. With an anonymous token only 0 is accepted. Member-specific rules — the daily booking limit, the per-activity booking limit and the duplicate-booking check — are applied only when the id is non-zero. |
member.firstName | string | No | Used only for guest holds (member.id of 0), where it is joined with member.lastName to form the name the booking is displayed under. If both names are empty the booking is displayed as Guest. Ignored when member.id identifies a real member — the display name is taken from the member record. |
member.lastName | string | No | The second half of the guest display name; see member.firstName. Ignored when member.id identifies a real member. |
member.attending | boolean | Yes | Whether the member takes one of the spaces themselves. true counts one space for them and triggers the check that rejects the lease if they are already booked into, or already hold a lease for, this slot. false holds spaces only for the people in additionalBookees; if that leaves nobody, the request fails with At least one bookee is required to create a lease. |
member.priceLevelId | string | No | The price level the member's own space is counted under when the slot's per-price-level attendee limits are checked. Ignored when member.id identifies a real member: the price level on that member's record is used instead. When no price level is resolved — a guest, or a member with none — the site's default price level is used. |
slotReference | string | Yes | The slot being held, taken verbatim from the availability response (each slot carries one under slotReferences.inCentre and slotReferences.virtual). Treat it as opaque and pass it through unchanged: it is a JSON document carrying the activity, start time, booking and resource ids. A value that is missing or is not a valid slot-reference document is rejected with Invalid or missing slotReference; one carrying no resource ids with At least one resourceId must be specified if no BookingId is provided; and one whose resource ids do not match what the activity needs with Slot Reference supplied does not contain all the required resource products. It also identifies the slot for the lock that stops two concurrent leases on it both succeeding. |
leaseLengthMinutes | integer (int32) | No | Custom lease length in minutes. Omit it to use the default ten-minute lease. The value is accepted only when the site operator has enabled Lease Expiry Override in GO Operator (Configuration > Bookings and Reservations > Bookings > Lease Expiry Override); otherwise the request is rejected with Custom lease length overrides are not enabled for this site. When enabled, the value must be between 10 and 10080 minutes inclusive. Values outside that range are rejected with Lease length must be between 10 and 10080 minutes. |
additionalBookees | array of object | No | Extra spaces to hold alongside the member, grouped by price level. Accepted only for party activities — sending it for any other activity fails with Additional Bookees can only be specified for party activities, so omit it entirely for an ordinary booking. The counts are added to the member's own space when the slot's remaining capacity is checked. |
additionalBookees[].priceLevelId | string | No | The price level this group of extra bookees is counted under. Entries sharing a price level are added together — and combined with the member's own space when that is at the same level — before the per-price-level maximum-attendee check runs. |
additionalBookees[].count | integer (int32) | No | How many extra spaces to hold at this price level. Contributes to the total number of people on the lease, which must be at least one across the member and every entry here, and which is checked against the spaces remaining on the slot. |
Sample request
curl -X PUT '{base_url}/api/bookings/lease/{uuid}' \
-H 'Authorization: Bearer {accessToken}' \
-H 'X-Use-SSO: true' \
-H 'Content-Type: application/json' \
-d '{
"id": "b7f3c1e2-9a44-4f2b-8c17-0d5e9a1b6c33",
"member": {
"id": 12345,
"firstName": "string",
"lastName": "string",
"attending": true,
"priceLevelId": "string"
},
"slotReference": "string",
"leaseLengthMinutes": 20,
"additionalBookees": [
{
"priceLevelId": "string",
"count": 1
}
]
}'Sample response
"b7f3c1e2-9a44-4f2b-8c17-0d5e9a1b6c33"Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | The path uuid is not a GUID; the slot reference is missing, unreadable, or does not carry the resource products the activity requires; the member is not the logged-in member or one of their linked members; the lease would hold no people at all; additionalBookees was sent for a non-party activity; leaseLengthMinutes was sent when Lease Expiry Override is not enabled for the site (Custom lease length overrides are not enabled for this site); leaseLengthMinutes is outside the accepted range of 10 to 10080 minutes (Lease length must be between 10 and 10080 minutes); the member is already booked into or already leasing this slot; the member has reached the daily or per-activity booking limit; the slot has too few spaces left (There is insufficient space on this activity…); or another request is already leasing this same slot (Could not acquire lock for lease creation…). |
404 | Not found | member.id is non-zero but no such member exists (Member ID {id} does not exist). |
409 | Conflict | Not returned — capacity and duplicate-lease failures return 400. |
500 | Internal server error | An unexpected server-side failure while creating the lease. |