Experience Booking
Before you book: the price handshake
An experience is booked from a priced search result. Run the experience search with startAt and experienceComposition; each result carries a price object with a priceId and an expiresAt (about 15 minutes). That priceId is the id of your booking request — it identifies the offer, party and price server-side, so the booking needs no price or period fields.
Booking with an expired or unknown priceId returns 401 Request expired: re-run the search, show the (possibly changed) price to your user, and book with the fresh priceId.
Create Experience Booking
Book one or several experiences in a single request — the body is an array of booking objects, one per experience.
Endpoint: POST /api/v1/experiences/book
Booking object fields:
| Field | Required | Description |
|---|---|---|
id | yes | The priceId from the priced search result; must be used before its expiresAt. |
startAt / endAt | recommended | The dates the offer was priced for (YYYY-MM-DD; same date for single-day experiences). The priced offer already carries them — send the same values, never different ones. |
customerFirstName, customerLastName, customerEmail | yes | The person or company the booking is for. |
travelers | yes | Every participant. Same shape as hotel travelers: kind (adult / child), gender, firstName, lastName, birthdate; optional nationality, passportNumber, expirationDate, ageIsExact. Must match the party the offer was priced for. |
extras | no | Add-ons to include; see Extras. |
selectedHotels | no | Programs only: for each program day needing accommodation, the chosen hotelId, its programId and dayIndex; set bookedOnMyOwn: true when the customer arranges that night themselves. |
toReference | no | Your own booking reference. |
customerInternalReference, customerFileId | no | Your customer reference / an existing customer file to attach to (one is created when omitted; required when replacing). |
customerPhoneNumber, customerAddress, customerAdditionalAddress, customerCity, customerZipCode, customerCompany | no | Customer contact details. |
tourOperatorName, networkName, note | no | Recorded on the booking. |
replaceBookingId | no | Existing booking this one replaces (requires customerFileId). |
groupUuid | no | Shared UUID grouping related bookings (use the same value across the array to link them). |
tripId | no | Trip to attach the booking to. |
lang | no | Locale for supplier-facing texts (e.g. en, fr). |
Example:
[
{
"id": "experiencePrice:6f1f9e0c-0a52-4c5e-9c1d-3f2b7a9e8d41",
"startAt": "2024-06-15",
"endAt": "2024-06-15",
"customerFirstName": "John",
"customerLastName": "Smith",
"customerEmail": "john.smith@email.com",
"toReference": "TC-2024-001",
"travelers": [
{ "kind": "adult", "gender": "male", "firstName": "John", "lastName": "Smith", "birthdate": "1980-05-15" },
{ "kind": "adult", "gender": "female", "firstName": "Jane", "lastName": "Smith", "birthdate": "1985-08-22" },
{ "kind": "child", "gender": "male", "firstName": "Tommy", "lastName": "Smith", "birthdate": "2010-05-15" }
],
"extras": [
{
"id": "extra-1",
"adultCount": 2,
"childrenBirthdates": ["2010-05-15"],
"scope": "day",
"dayIndex": 1
}
]
}
]Extras
Each entry in extras books one add-on from the priced offer (price.extras in the search result):
| Field | Required | Description |
|---|---|---|
id | yes | The extra's id from the priced offer. |
adultCount | yes | Number of adults taking the extra. |
childrenBirthdates | yes | One birthdate per child taking the extra ([] for none). |
scope | yes | global — applies once to the whole experience; day — applies to one program day. |
dayIndex | with scope: "day" | Which program day the extra applies to (1-based). |
Response:
[
{
"id": "booking-789",
"groupUuid": "group-789",
"startAt": "2024-06-15",
"endAt": "2024-06-15",
"createdAt": "2024-05-01T10:00:00Z",
"updatedAt": "2024-05-01T10:00:00Z",
"currency": "EUR",
"customerLastName": "Smith",
"customerFirstName": "John",
"customerEmail": "john.smith@email.com",
"state": "pending",
"dmcState": "pending",
"totalPrice": 450.00,
"experiencesBooked": [
{
"id": "exp-booking-1",
"priceWithoutPromo": 500.00,
"price": 450.00,
"promotions": ["Early Bird 10%"],
"extras": "Audio guide upgrade",
"travelers": [
{
"id": "traveler-1",
"firstName": "John",
"lastName": "Smith",
"kind": "adult"
}
],
"experience": {
"id": "exp-123",
"name": "Louvre Museum Private Tour",
"organizationName": "Paris Culture Tours"
}
}
]
}
]The response is an array with one created booking per object in your request. Experiences on free_sale periods confirm immediately; on_request periods create the booking in a pending state until the supplier answers — track it through state on GET /api/v1/bookings/{bookingId} or the booking history (states are documented on Search Bookings). Cancellation goes through the common cancel endpoint.
Update Experience Booking
Update an existing experience booking with new options or modifications.
Endpoint: PATCH /api/v1/experiences/updatedBook/{adminBookingId}
Parameters:
adminBookingId(path, required): Admin booking ID
Request Body:
{
"filters": {
"search": "Updated preferences",
"themes": ["cultural", "adventure"]
},
"extras": [
{
"id": "extra-2",
"adultCount": 2,
"dayIndex": 1,
"childrenBirthdates": ["2010-05-15"],
"scope": "global",
"isIncluded": "true"
}
]
}Experience Composition Extras
Update Experience Extra
Update details of an experience composition extra.
Endpoint: PUT /api/v1/experiences/extras/{experienceCompositionExtraId}
Parameters:
experienceCompositionExtraId(path, required): Experience composition extra ID
Request Body:
{
"id": "extra-1",
"extra": {
"id": "exp-extra-123",
"name": "Audio Guide Upgrade"
},
"state": "confirmed",
"price": 25.00,
"priceWithoutPromo": 30.00,
"extraCompositionId": "comp-456",
"adultPax": 2,
"childrenBirthdates": ["2010-05-15"],
"dayIndex": 1
}Cancel Experience Extra
Cancel an experience composition extra.
Endpoint: DELETE /api/v1/experiences/extras/{experienceCompositionExtraId}
Parameters:
experienceCompositionExtraId(path, required): Experience composition extra ID
Booking Management
Get Experience Organizations
Get organizations linked to a specific experience.
Endpoint: GET /api/v1/experiences/{experienceId}/organizations
Parameters:
experienceId(path, required): Experience ID
Response:
[
{
"id": "org-123",
"displayName": "Paris Culture Tours"
},
{
"id": "org-456",
"displayName": "Seine River Cruises"
}
]Export Experience
Export experience details in various formats.
Endpoint: POST /api/v1/experiences/{experienceId}/export/{exportFormat}
Parameters:
experienceId(path, required): Experience IDexportFormat(path, required): Export format (e.g., "pdf", "excel")locale(query, optional): 2-letter language code
Request Body:
{
"startAt": "2024-06-15",
"endAt": "2024-06-15",
"adults": 2,
"children": 1,
"price": 450.00,
"currency": "EUR",
"extras": [
{
"name": "Audio Guide",
"adults": 2,
"children": 1,
"price": 25.00,
"currency": "EUR"
}
],
"clientFolderReference": "TC-2024-001",
"clientFolderId": "folder-456"
}Response:
{
"downloadUrl": "https://example.com/exports/experience-export.pdf",
"expiresAt": "2024-06-10T12:00:00Z"
}Please refer to the bookings documentation for more details on retrieving and managing bookings.