Booking
The recommended API flow for members making bookings.
This flow replicates a logged in member making a booking through Go Book. However, there is only one change for non-members making a booking which is noted at the appropriate stage.
This endpoint returns all activities available for a site when search text is not entered, but the Site ID filter is added. The activity IDs are then used in the sessions call to find available slots. In Go Book, this is used to display a list of activities for the member to select from.
You will also want to use the Web Bookable Only = True filter in this call to only return activities that can be booked online.
Request
curl --request GET \
--url 'https://example.com/api/search/activities/searchText?siteIds=WIN&webBookableOnly=true&descriptionOnly=true' \
--header 'accept: application/json'Response
[
{
"id": "string",
"name": "string",
"siteId": "string",
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
]
}
]From the previous response, a member should select an activity or a series of activities. These IDs should be passed into this endpoint to retrieve availability and slot information. Slots are the time and location of the activity, e.g. 11am on Court 1.
You will need to provide the member's ID which should be retrieved from when the member logs in. However, if you are making a booking for a non-member, this can be omitted from the same call. The member will then need to provide their details to create an account once they have selected their booking slot.
If not DateFrom value is provided, this will default to the current date and time. The response will bring back sessions between the DateFrom value and the look ahead period which can be set by the operator.
Request
curl --request GET \
--url 'https://example.com/api/availability/v2/sessions/123456?activityIds=WACT000201%2CWACT000301&siteIds=WIN&webBookableOnly=true' \
--header 'accept: application/json'Response
[
{
"activityGroupId": "string",
"activityGroupDescription": "string",
"id": "string",
"name": "string",
"description": "string",
"date": "string",
"imageUrl": "string",
"inCentre": true,
"virtual": true,
"siteId": "string",
"webBookable": true,
"webComments": "string",
"capacity": {
"maxInCentreBookees": 0,
"maxVirtualBookees": 0
},
"typeInd": "string",
"slotCount": 0,
"groupActivityDetails": {
"isGroupActivity": true,
"priceLevels": [
{
"id": "string",
"description": "string"
}
]
},
"locations": [
{
"locationId": "string",
"locationName": "string",
"slots": [
{
"startTime": "2024-11-26T08:14:14.268Z",
"endTime": "2024-11-26T08:14:14.268Z",
"bookableFrom": "2024-11-26T08:14:14.268Z",
"bookableUntil": "2024-11-26T08:14:14.268Z",
"availability": {
"inCentre": 0,
"virtual": 0
},
"alertListEnabled": true,
"alertListCount": 0,
"status": "Available",
"slotReferences": {
"inCentre": "string",
"virtual": "string"
}
}
],
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
]
}
],
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
],
"activityGroupTranslations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
]
}
]From the previous response, a member should select a specific slot for an activity. Pass the slot reference into this request to receive the pricing information for the member and any allowed guests.
Request
curl --request POST \
--url https://example.com/api/pricing/session \
--header 'accept: application/json' \
--header 'content-type: application/*+json' \
--data '
{
"memberId": 0,
"slotReference": "{\\\"BookingId\\\":12345678,\\\"ActivityId\\\":\\\"ACTIVITY1234\\\",\\\"StartDateTime\\\":\\\"2024-10-20T08:00:00Z\\\",\\\"ResourceIds\\\":[\\\"STUDIO1\\\"],\\\"InCentre\\\":true,\\\"Virtual\\\":false}"
}
'Response
{
"memberPriceLevel": {
"id": "string",
"description": "string",
"price": {
"inCentre": 0,
"virtual": 0
},
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
]
},
"paidForbyUsageSub": "string",
"usagesRemaining": 0,
"currency": "string",
"priceLevels": [
{
"id": "string",
"description": "string",
"price": {
"inCentre": 0,
"virtual": 0
},
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
]
}
]
}This endpoint takes the member's, and any guest's, price levels, and the slot reference to return a detailed, timestamped, and signed pricing quote. The same request object should also be used in the lease call to create a lease for the spaces in the activity. The pricing quote response object is used, along with the lease, in the booking call.
Request
curl --request POST \
--url https://example.com/api/pricing/slot \
--header 'accept: application/json' \
--header 'content-type: application/*+json' \
--data '
{
"member": {
"attending": true,
"id": 123456,
"priceLevelId": "ADULT"
},
"slotReference": "{\\\"BookingId\\\":12345678,\\\"ActivityId\\\":\\\"ACTIVITY1234\\\",\\\"StartDateTime\\\":\\\"2024-10-20T08:00:00Z\\\",\\\"ResourceIds\\\":[\\\"STUDIO1\\\"],\\\"InCentre\\\":true,\\\"Virtual\\\":false}",
"additionalBookees": [
{
"priceLevelId": "JUNIOR",
"count": 1
}
]
}
'Response
{
"totalPrice": {
"amount": 0,
"currency": "string"
},
"breakdown": {
"memberPrice": {
"priceLevelId": "string",
"totalPrice": 0,
"productPrices": [
{
"id": "string",
"quantity": 0,
"timeBandId": "string",
"amount": 0,
"taxCodeId": "string",
"taxRate": 0
}
]
},
"currency": "string",
"priceLevels": [
{
"count": 0,
"pricePerAdditionalBookee": 0,
"id": "string",
"totalPrice": 0,
"productPrices": [
{
"id": "string",
"quantity": 0,
"timeBandId": "string",
"amount": 0,
"taxCodeId": "string",
"taxRate": 0
}
]
}
]
},
"paidForbyUsageSub": "string",
"usagesRemaining": 0,
"timeStamp": "string",
"signature": "string"
}To create a booking in Go, you must first create a lease. This reserves the spaces in the activity for the member (and any guests), once they have selected their slot and before they pay.
Use this endpoint to create the lease with the details of the session, the member and/or guests, and a uuid. The uuid must be generated by your system and is a unique identifier used as the lease ID when finalising the booking.
The lease can be updated throughout the process to change activities or attending members. Leases expire after 15 minutes, but can be updated with a refresh.
Request
curl --request PUT \
--url https://example.com/api/bookings/lease/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
--header 'accept: application/json' \
--header 'content-type: application/*+json' \
--data '
{
"member": {
"attending": true,
"id": 123456,
"priceLevelId": "ADULT"
},
"slotReference": "{\\\"BookingId\\\":12345678,\\\"ActivityId\\\":\\\"ACTIVITY1234\\\",\\\"StartDateTime\\\":\\\"2024-10-20T08:00:00Z\\\",\\\"ResourceIds\\\":[\\\"STUDIO1\\\"],\\\"InCentre\\\":true,\\\"Virtual\\\":false}",
"additionalBookees": [
{
"priceLevelId": "JUNIOR",
"count": 1
}
],
"id": "123"
}
'Response
"3fa85f64-5717-4562-b3fc-2c963f66afa6"Creates the booking for the member. This is used for logged in members only. For non-members wanting to book, you must use the Add Member with Bookings endpoint which will create both the member record and booking at the same time.
Request
curl --request POST \
--url https://example.com/api/bookings \
--header 'accept: application/json' \
--header 'content-type: application/*+json' \
--data '
{
"bookings": [
{
"totalPrice": {
"amount": 0,
"currency": "string"
},
"breakdown": {
"memberPrice": {
"priceLevelId": "string",
"totalPrice": 0,
"productPrices": [
{
"id": "string",
"quantity": 0,
"timeBandId": "string",
"amount": 0,
"taxCodeId": "string",
"taxRate": 0
}
]
},
"currency": "string",
"priceLevels": [
{
"count": 0,
"pricePerAdditionalBookee": 0,
"id": "string",
"totalPrice": 0,
"productPrices": [
{
"id": "string",
"quantity": 0,
"timeBandId": "string",
"amount": 0,
"taxCodeId": "string",
"taxRate": 0
}
]
}
]
},
"paidForbyUsageSub": "string",
"usagesRemaining": 0,
"timeStamp": "string",
"signature": "string"
},
"leaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"memberId": 123456,
"payingMemberId": 123456
}
]
}
'Response
{
"bookings": [
{
"leaseID": "string",
"bookingID": 0,
"bookingRef": 0,
"salesInvoiceIds": [
0
],
"bookeePriceLevels": [
{
"id": "string",
"description": "string",
"count": 0,
"price": 0,
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
]
}
]
}
]
}The next stage is to use the hosted forms to create a payment token. The details of how to do this can be found in the Hosted Form Integration Guide from our payment partner.
Once you have the payment token, then move through the payment endpoint.
Use the member ID and sales invoice ID returned from the previous step, then add in details of the payment method to then send the request.
This endpoint will return an initial response stating that 3DS challenge is required. At this point we take the 3DS challenge details, append it to our request and use the payment/pay endpoint again with the refreshed details.
Request
curl --request POST \
--url https://example.com/api/payment/pay \
--header 'accept: application/json' \
--header 'content-type: application/*+json' \
--data '
{
"deviceInformation": {
"timeZone": "-60",
"capabilities": "java, javascript",
"screenResolution": "1200x1920x24"
},
"salesInvoiceIds": [
987654321
],
"memberId": 123456,
"paymentToken": "987654321qwretyuipasdfghjklZXCVBNM",
"saveCardToWallet": false,
}
'Response
{
"responseStatus": "InternalServerError",
"transactionId": "string",
"walletId": "string",
"cardId": "string",
"responseCode": 0,
"paymentProviderReference": "string",
"threeDSecureChallengeUrl": "string",
"threeDSecureChallengeFields": {
"additionalProp": "string"
}
}