Introduction
Welcome to the Reservation platform (RP) API!
This API provides access to resources that can be used to create a timed ticket solution for a specific pass destination. The resources can be used to validate customer orders and pass details, retrieve information on attractions enabled for time based reservations, get time slot availability as well as place bookings in partner systems.
Authentication
Generate a Token
Sample Request:
curl --location --request POST '{{env}}/auth/v1/token/' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderNumber": "{{orderNumber}}",
"email": "{{emailAddress}}"
}'
The Authentication endpoint validates a pass order and provides an accessToken to be included in all subsequent API requests.
To authenticate, simply provide a valid order number and email address, then you will receive an accessToken that is valid for 1 hour.
If the order and/or email are invalid or not applicable for the Reservation Portal, they will not be authenticated.
Make sure to replace
orderNumberandemailAddresswith real data.
HTTP Request
POST /aggregator/v1/token/
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| orderNumber | String | yes | The order number of the order that contains the passes for which reservations are to be made |
| String | yes | The email address used to place the order |
Response
Successful Response
{
"accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJwYX12345678eyJvcmRlck51bWJlciI6IjQ5MDAyOTgiLCJwYXNzZXMiOlt7InBhc3NJZCI6IjI0OTAwMjk4MTAwMSIsInNrdSI6Ik55Y19Qcm9kX0V4cF9jMl9hYSIsImFnZVR5cGUiOiJBRFVMVCIsImV4cGlyZWQiOmZhbHNlfSx7InBhc3NJZCI6IjI0OTAwMjk4MTAwMiIsInNrdSI6Ik55Y19Qcm9kX0V4cF9jMl9hYSIsImFnZVR5cGUiOiJBRFVMVCIsImV4cGlyZWQiOmZhbHNlfV19LCJqdGkiOiJmMDZjZmUzZS0zOGM5LTQ3MDEtOWNkZS03YmQyN2IzNGRjZjMiLCJzdWIiOiJxcnBpbnRlZ3JhdGlvbnRlc3RAbGVpc3VyZXBhc3Nncm91cC5jb20iLCJpYXQiOjE1OTg1MTQzNTcsImV4cCI6MTU5ODUxNzk1N30.CXVJAuoLKmXJrRe-h2aWZgPxNx5TgX26E0YLJ-0EjopZV2xZaQ7jX_KWVIveovePm2B7dcmw9WDg1vBTyCRzh2sQdCidYN0nH5b4-SQwoqIQ0aP3AXHloyVjfj5pejU784j012lkIBd0U03FEdnS-lIvuQwpRnH697QsfYwJrIEfDgZIwJESIsXWoKK7dDHs3tjpXnIEt_tpMzFFOd9HxPK3nS6WMo4pgEpOVhKGespCsMIE7CFr6NSfzIbkmO8GTnGX6SV0BmhbK-R95kno1Rq-ehVw0eNiLSL8UVB5_KQgrwl96kEihiIUn59per0Swc6vc_BrBEGdCxdx4n3cnA"
}
accessToken: To be used in the Authorization header for each subsequent request - valid for 1 hour
Error Codes
Sample Error Response
{
"errorCode" : "AUTH-003",
"errorMessage" : "Order is pending"
}
| Code | Error Type | Error Status |
|---|---|---|
AUTH-000 |
Internal Error | 500 |
AUTH-001 |
Invalid / missing values on request | 400 |
AUTH-002 |
Order has no applicable attractions | 401 |
AUTH-003 |
Order is pending | 401 |
AUTH-004 |
Order is not found | 401 |
AUTH-005 |
Error occurred when finding order | 400 |
AUTH-006 |
Large orders not supported | 400 |
JWT-000 |
Invalid/Expired JWT token | 401 |
Attractions
Get Attractions
curl --location --request GET '{{env}}/attractions/v1/' \
--header 'Authorization: Bearer {{token}}'
Make sure to replace
{{token}}with the accessToken returned from the previous step
The Attractions endpoint provides a list of attractions that have been enabled for timed ticketing for the pass destination. The response will indicate whether each attraction is available for the customer to book. Where the customer has already reserved and/or visited the attraction, the response will indicate the attraction is no longer available.
HTTP Request
POST /aggregator/v1/attractions/
Parameters
None
Response
Successful Response
{
"attractions": [
{
"id": "6293fcb4-cfeb-43c3-b1fc-7fd83a98e496",
"name": "Madame Tussauds",
"title: "Madame Tussauds",
"description": "London Madame Tussauds",
"redemptionInfo": "Present ticket for validation at entrance",
"image": "http://host/img.jpg",
"cancellationWindow": "You will have X amount of time to cancel",
"sku": "Lon_Att_Madame_Tussauds_London",
"state": "AVAILABLE",
"partner": "MERLIN"
},
{
"id": "7293fcb4-cfeb-43c3-b1fc-7fd83a98e496",
"name": "London Eye",
"title: "London Eye",
"description": "Visit the London Eye",
"redemptionInfo": "Present ticket for validation at entrance",
"image": "http://host/img.jpg",
"cancellationWindow": "You will have X amount of time to cancel",
"sku": "Lon_Att_London_Eye_London",
"state": "AVAILABLE",
"partner": "MERLIN"
}
]
}
attractions - a list of attractions with the following information:
id - The attraction id. To be used in the /availability and /booking requests
name - The attraction name
title - The attraction display name
description - Description content for the attraction
redemptionInfo - Redemption Info for attraction
image - Link to a display image
cancellationWindow - Info on cancellation window
sku - The LPG sku of the attraction
state - Is the attraction available for the user? - AVAILABLE|UNAVAILABLE
partner - The partner that manages the attraction
Error Codes
Sample Error Response
{
"errorCode": "AT-002",
"errorMessage": "Attraction not found"
}
| Code | Error Type | Error Status |
|---|---|---|
AT-000 |
Internal Error | 500 |
AT-001 |
Invalid / missing values on request | 400 |
AT-002 |
Attraction not found | 404 |
JWT-000 |
Invalid/Expired JWT token | 401 |
Get Attraction by UUID
curl --location --request GET '{{env}}/attractions/v1/{{attractionId}}' \
--header 'Authorization: Bearer {{token}}'
Make sure to replace
{{token}}with the accessToken returned from the previous step
Get single attraction data for a single UUID
HTTP Request
POST /aggregator/v1/attractions/{{attractionId}}
Parameters
None
Response
Successful Response
{
"id": "6293fcb4-cfeb-43c3-b1fc-7fd83a98e496",
"name": "Madame Tussauds",
"title: "Madame Tussauds",
"description": "London Madame Tussauds",
"redemptionInfo": "Present ticket for validation at entrance",
"image": "http://host/img.jpg",
"cancellationWindow": "You will have X amount of time to cancel",
"sku": "Lon_Att_Madame_Tussauds_London",
"state": "AVAILABLE",
"partner": "MERLIN"
}
id - The attraction id. To be used in the /availability and /booking requests
name - The attraction name
title - The attraction display name
description - Description content for the attraction
redemptionInfo - Redemption Info for attraction
image - Link to a display image
cancellationWindow - Info on cancellation window
sku - The LPG sku of the attraction
state - Is the attraction available for the user? - AVAILABLE|UNAVAILABLE
partner - The partner that manages the attraction
Error Codes
Sample Error Response
{
"errorCode": "AT-002",
"errorMessage": "Attraction not found"
}
| Code | Error Type | Error Status |
|---|---|---|
AT-000 |
Internal Error | 500 |
AT-001 |
Invalid / missing values on request | 400 |
AT-002 |
Attraction not found | 404 |
JWT-000 |
Invalid/Expired JWT token | 401 |
Pass Usages
Get Usages for Passes
curl --location --request GET '{{env}}/pass-usage/v1/?attractionId={{attractionId}}' \
--header 'Authorization: Bearer {{accessToken}}'
The Pass usage endpoint provides usage validity for passes linked to the user's order and attractionId
HTTP Request
GET /aggregator/v1/pass-usage/?attractionId={{attractionId}}
Parameters
| Name | Data Type | Required/Optional | Description |
|---|---|---|---|
| attractionId | String | Required | The id of the attraction |
Response
Successful Response
{
"passUsages": [
{
"passNumber": "048901361001",
"ageType": "ADULT",
"valid": true
},
{
"passNumber": "048901362002",
"ageType": "CHILD",
"valid": false
}
]
}
passUsages - A list of usages with validity for a chosen attraction
Error Codes
Sample Error Response
{
"errorCode" : "JWT-000",
"errorMessage" : "Invalid JWT Token"
}
| Code | Error Type | Error Status |
|---|---|---|
PASS-USAGE-000 |
Internal Error | 500 |
PASS-USAGE-001 |
Invalid / missing values on request | 400 |
PASS-USAGE-002 |
JSON parse error | 400 |
PASS-USAGE-003 |
Invalid Attraction ID | 400 |
PASS-USAGE-004 |
Failed to resolve usage | 400 |
JWT-000 |
Invalid/Expired JWT token | 401 |
Availability
Get Availabilities
curl --location --request GET '{{env}}/availability/v1/?attractionId={{attractionId}}&passes={{passes}}' \
--header 'Authorization: Bearer {{accessToken}}'
Make sure to replace
{{accessToken}},{{attractionId}}and{{passes}}with the accessToken, attractionId and passes from stepsGenerate a Token,Get AttractionsandGet Usages for Passesrespectively
The Availability endpoint provides real-time reservation options from the attraction partner. The times returned will only include ones where capacity available exceeds the number of passes linked to the order.
As each attraction is unique, the time slot options may vary, whereby one attraction may offer time slots every 15 minutes, while another may have an hourly intake.
HTTP Request
GET /aggregator/v1/availability/?attractionId={{attractionId}}&passes={{passes}}
Parameters
| Name | Data Type | Required/Optional | Description |
|---|---|---|---|
| attractionId | String | Required | The id of the attraction to get availability for |
| passes | List |
Required | List of Selected Passes linked to the order |
Response
Successful Response
{
"availableTimes": [
{
"id": "XXXX",
"time": "2020-08-27T10:00:00"
},
{
"id": "XXXX",
"time": "2020-08-27T10:30:00"
},
{
"id": "XXXX",
"time": "2020-08-27T10:45:00"
},
{
"id": "XXXX",
"time": "2020-08-27T11:00:00"
},
{
"id": "XXXX",
"time": "2020-08-27T11:15:00"
},
{
"id": "XXXX",
"time": "2020-09-02T18:00:00"
}
]
}
availableTimes - A list of available time slots and a nullable Id based on partners for the attraction
Error Codes
Sample Error Response
{
"errorCode" : "JWT-000",
"errorMessage" : "Invalid JWT Token"
}
| Code | Error Type | Error Status |
|---|---|---|
AV-000 |
Internal Error | 500 |
AV-001 |
Invalid / missing values on request | 400 |
AV-002 |
Unknown partner | 404 |
AV-003 |
Expired Passes | 400 |
AV-004 |
Error when looking up available timeslots for Partner | 400 |
QRP-002 |
Invalid Quantity of Passes | 400 |
QRP-003 |
Anonymous User with invalid Passes | 400 |
QRP-004 |
Unknown Passes Provided | 404 |
JWT-000 |
Invalid/Expired JWT token | 401 |
Booking
Get Bookings
curl --location --request GET '{{env}}/booking/v1' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Content-Type: application/json' \
Make sure to replace
{{accessToken}}with the accessToken
The Booking endpoint gets all the bookings made.
The response will include a list of all the bookings made with the ticket information, and a URL to download the ticket PDF
HTTP Request
GET /aggregator/v1/booking
Response
Successful Response
[
{
"bookingId": "685055c2-6f39-4d47-a98a-b1e64888078e",
"orderNumber": "4890136",
"externalOrderId": "600012885",
"orderDateTime": "2020-09-18T15:32:45.301151Z",
"attractionId": "6293fcb4-cfeb-43c3-b1fc-7fd83a98e496",
"title: "Madame Tussauds",
"description": "London Madame Tussauds",
"redemptionInfo": "Present ticket for validation at entrance",
"image": "http://host/img.jpg",
"cancellationWindow": "You will have X amount of time to cancel",
"contentId": "685055c2-6f39-4d47-a98a-b1e64888078e",
"entryDate": "2020-09-21",
"entryTime": "10:15:00",
"requestId": "1523c30a-58b2-4157-b914-b3a9caa861f1",
"ticketUrl": "{{env}}/ticket/v1/685055c2-6f39-4d47-a98a-b1e64888078e",
"tickets": [
{
"passId": "048901361001",
"externalTicketId": "600099787022186874",
"ticketType": "ADULT"
},
{
"passId": "048901362002",
"externalTicketId": "600099787022186875",
"ticketType": "ADULT"
}
],
"lastAmendmentDateTime": "2021-05-21T09:00:00Z",
"lastCancellationDateTime": "2021-05-21T09:00:00Z",
"cancellationDateTime": "2021-05-21T09:00:00Z",
"timeSlotId": "BAE.103.E11"
}
]
externalOrderId - The partner order id
bookingId - The LPG booking id
attractionId - The specific attraction that was selected
title - The attraction display name
description - Description content for the attraction
redemptionInfo - Redemption Info for attraction
image - Link to a display image
cancellationWindow - Info on cancellation window
contentId - Drupal Content for the attraction
orderDateTime - The date/time at which the order was placed
entryDate - The date when the event happens
entryTime - The time at which the event happens
requestId - A unique logged in session
ticketUrl - To download a PDF of the tickets purchased
lastAmendmentDateTime - After this time has passed, amending a booking will no longer be possible
lastCancellationDateTime - After this time has passed, cancelling a booking will no longer be possible
cancellationDateTime - The time at which this booking was cancelled (null if not cancelled)
tickets - A list of booked successfully tickets with the partner ticket number and the ticket type (ADULT/CHILD)
timeSlotId - Partner's TimeSlotId
Make a Booking
curl --location --request POST '{{env}}/booking/v1' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"timeSlotId" : {{timeSlotId}},
"attractionId" : {{attractionId}},
"eventDate" : {{eventDate}},
"eventTime" : {{eventTime}},
"passNumbers": {{passNumbers}}
}'
Make sure to replace
{{accessToken}},{{attractionId}},{{eventDate}},{{eventTime}},{{timeSlotId}}with the accessToken, attractionId, desired date and time and timeSlotId from stepsGenerate a Token,Get AttractionsandGet Availabilitiesrespectively
The Booking endpoint creates a reservation at the attraction partner for the specified date and time.
The response will return partner booking details, ticket information and a URL to download the ticket PDF needed by the customer to gain entry at the attraction gate.
HTTP Request
POST /aggregator/v1/booking/
Body Parameters
| Name | Data Type | Required | Description |
|---|---|---|---|
| attractionId | String | yes | The id of the attraction to book |
| eventDate | String | yes | The date of the slot to be booked (YYYY-MM-dd) |
| eventTime | String | yes | The time of the slot to be booked (HH:mm:ss) |
| passNumbers | String Array | yes | The pass numbers to book for |
Response
Successful Response
{
"bookingId": "685055c2-6f39-4d47-a98a-b1e64888078e",
"orderNumber": "4890136",
"externalOrderId": "600012885",
"orderDateTime": "2020-09-18T15:32:45.301151Z",
"attractionId": "6293fcb4-cfeb-43c3-b1fc-7fd83a98e496",
"title: "Madame Tussauds",
"description": "London Madame Tussauds",
"redemptionInfo": "Present ticket for validation at entrance",
"image": "http://host/img.jpg",
"cancellationWindow": "You will have X amount of time to cancel",
"contentId": "685055c2-6f39-4d47-a98a-b1e64888078e",
"entryDate": "2020-09-21",
"entryTime": "10:15:00",
"requestId": "1523c30a-58b2-4157-b914-b3a9caa861f1",
"ticketUrl": "{{env}}/ticket/v1/685055c2-6f39-4d47-a98a-b1e64888078e",
"lastAmendmentDateTime": "2021-05-21T09:00:00Z",
"lastCancellationDateTime": "2020-09-11T09:00:00Z",
"cancellationDateTime": null,
"tickets": [
{
"passId": "048901361001",
"externalTicketId": "600099787022186874",
"ticketType": "ADULT"
},
{
"passId": "048901362002",
"externalTicketId": "600099787022186875",
"ticketType": "ADULT"
}
],
"timeSlotId": "BAE.103.E11"
}
externalOrderId - The partner order id
bookingId - The LPG booking id
attractionId - The specific attraction that was selected
contentId - Drupal Content for the attraction
title - The attraction display name
description - Description content for the attraction
redemptionInfo - Redemption Info for attraction
image - Link to a display image
cancellationWindow - Info on cancellation window
orderDateTime - The date/time at which the order was placed
entryDate - The date when the event happens
entryTime - The time at which the event happens
requestId - A unique session Id
ticketUrl - To download a PDF of the tickets purchased
lastAmendmentDateTime - After this time has passed, amending a booking will no longer be possible
lastCancellationDateTime - After this time has passed, cancelling a booking will no longer be possible
cancellationDateTime - The time at which this booking was cancelled (null if not cancelled)
tickets - A list of booked successfully tickets with the partner ticket number and the ticket type (ADULT/CHILD)
timeSlotId - Partner's TimeSlotId
Cancel a Booking
curl --location --request PUT '{{env}}/booking/v1/{{bookingId}}' \
--header 'Authorization: Bearer {{accessToken}}' \
Make sure to replace
{{accessToken}},{{bookingId}}with the accessToken and bookingId for the booked item
The response will be a 204 status response with no content
HTTP Request
PUT /aggregator/v1/booking/{{bookingId}}
Response
HTTP status 204
Amend a Booking
curl --location --request PUT '{{env}}}}/booking/v1' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"bookingId" : "{{bookingId}}",
"timeSlotId" : "{{timeSlotId}}",
"eventDate" : "{{eventDate}}",
"eventTime" : "{{eventTime}}"
}'
Make sure to replace
{{accessToken}}with the accessToken
HTTP Request
PUT /aggregator/v1/booking
Body Parameters
| Name | Data Type | Required | Description |
|---|---|---|---|
| bookingId | String | yes | The id of the book to amend |
| timeSlotId | String | no | The new timeslot to change to |
| eventDate | String | yes | The date of the slot to be booked (YYYY-MM-dd) |
| eventTime | String | yes | The time of the slot to be booked (HH:mm:ss) |
Response
Successful Response
{
"bookingId": "685055c2-6f39-4d47-a98a-b1e64888078e",
"orderNumber": "4890136",
"externalOrderId": "600012885",
"orderDateTime": "2020-09-18T15:32:45.301151Z",
"attractionId": "6293fcb4-cfeb-43c3-b1fc-7fd83a98e496",
"title: "Madame Tussauds",
"description": "London Madame Tussauds",
"redemptionInfo": "Present ticket for validation at entrance",
"image": "http://host/img.jpg",
"cancellationWindow": "You will have X amount of time to cancel",
"contentId": "685055c2-6f39-4d47-a98a-b1e64888078e",
"entryDate": "2020-09-21",
"entryTime": "10:15:00",
"requestId": "1523c30a-58b2-4157-b914-b3a9caa861f1",
"ticketUrl": "{{env}}/ticket/v1/685055c2-6f39-4d47-a98a-b1e64888078e",
"lastAmendmentDateTime": "2021-05-21T09:00:00Z",
"lastCancellationDateTime": "2020-09-11T09:00:00Z",
"cancellationDateTime": null,
"tickets": [
{
"passId": "048901361001",
"externalTicketId": "600099787022186874",
"ticketType": "ADULT"
},
{
"passId": "048901362002",
"externalTicketId": "600099787022186875",
"ticketType": "ADULT"
}
],
"timeSlotId": "BAE.103.E11"
}
bookingId - The LPG booking id
orderNumber - The LPG order number
externalOrderId - The partner order id
orderDateTime - The date/time at which the order was placed
attractionId - The specific attraction that was selected
title - The attraction display name
description - Description content for the attraction
redemptionInfo - Redemption Info for attraction
image - Link to a display image
cancellationWindow - Info on cancellation window
contentId - Drupal Content for the attraction
entryDate - The date when the event happens
entryTime - The time at which the event happens
requestId - A unique session Id
ticketUrl - To download a PDF of the tickets purchased
lastAmendmentDateTime - After this time has passed, amending a booking will no longer be possible
lastCancellationDateTime - After this time has passed, cancelling a booking will no longer be possible
cancellationDateTime - The time at which this booking was cancelled (null if not cancelled)
tickets - A list of booked successfully tickets with the partner ticket number and the ticket type (ADULT/CHILD)
timeSlotId - Partner's TimeSlotId
Error Codes
Sample Error Response
{
"errorCode": "BOOKING-001",
"errorMessage": "attractionId must not be null"
}
| Code | Error Type | Error Status |
|---|---|---|
BOOKING-000 |
Internal Error | 500 |
BOOKING-001 |
Invalid / missing values on request | 400 |
BOOKING-002 |
Unknown partner | 404 |
BOOKING-003 |
Invalid age type | 400 |
BOOKING-004 |
Client exception | 400 |
BOOKING-005 |
Malformed JSON in request | 500 |
BOOKING-006 |
Cancellation deadline has already passed | 400 |
BOOKING-007 |
This booking is already cancelled | 400 |
BOOKING-008 |
Booking not found | 404 |
BOOKING-009 |
Timeslot no longer available | 400 |
BOOKING-010 |
Failed to place a scan | 400 |
BOOKING-011 |
Invalid Attraction ID | 404 |
BOOKING-012 |
Failed to delete scans | 400 |
BOOKING-013 |
Failed to amend reservation | 400 |
BOOKING-014 |
Ticket(s) booking already exists for this timeslot | 409 |
BOOKING-015 |
Provided booking does not belong to the authenticated user | 403 |
BOOKING-016 |
Amendment deadline has already passed | 400 |
JWT-000 |
Invalid/Expired JWT token | 401 |
Ticket
Download a Ticket
curl --location --request GET '{{env}}/ticket/v1/{{bookingId}}' \
--header 'Authorization: Bearer {{accessToken}}' \
Make sure to replace
{{accessToken}},{{bookingId}}with the accessToken and bookingId
The Ticket endpoint given along with bookingId will download a PDF which gives all the information about the booking and tickets purchased
HTTP Request
GET /ticket/v1/{{bookingId}}
Path Variables
| Name | Data Type | Required/Optional | Description |
|---|---|---|---|
| bookingId | String | Required | The id of the booking to get a downloadable PDF file |
Response
Response Body is in Byte Array Response with content-type as application/pdf
Successful Response
%PDF-1.5
%����
7 0 obj
<</ColorSpace/DeviceGray/Subtype/Image/Height 125/Filter/FlateDecode/Type/XObject/DecodeParms<</Columns 125/Colors 1/Predictor 15/BitsPerComponent 1>>/Width 125/Length 217/BitsPerComponent 1>>stream
x�Օ1�0EŐ�#�&�b�@���M8BF�
�6UK��C��H G��pv�.X$n��
U���d%
4P�m�"��
�q��ǁ�;���&W�G�vT��tN *
Error Codes
Sample Error Response
No Error response body
This request doesn't return any Error Response Body.
| Code | Error Type | Error Status |
|---|---|---|
TICKET-000 |
Internal Error | 500 |
TICKET-001 |
Booking Not Found | 404 |
TICKET-002 |
Booking Cancelled | 400 |
TICKET-003 |
DPD Client Unexpected Error | 500 |
TICKET-004 |
Forbidden Ticket Access | 403 |
JWT-000 |
Invalid/Expired JWT token | 401 |