Bookings: Booking journey
- Booking
- Booking
- 8 routes
This guide explains how to transform a booking intent into a confirmed option with the Club Med API.
It covers proposal search, optional services and insurance handling, attendee qualification, and booking creation.
Overview
This scenario documents a booking-preparation flow that starts from proposal search and ends with booking creation.
Prerequisites
- A valid
x-api-keyandaccept-language. - The booking criteria required to search a proposal.
- A
proposal_idreturned by the search step before adding services, insurance, or attendee data.
Expected result
The application can create or retrieve a proposal, enrich it with optional services or insurance, qualify attendees, and create the booking option.
Process workflow
Search matching proposals
Use POST/v3/proposals/search to create the proposal that will drive the booking journey. This first step calculates price, stock, and optionability from the submitted booking criteria and returns the proposal_id required by all later steps.
Prerequisites
- Send
accept-languageandx-api-key. - Add
authorizationwhen the seller or partner context requires it. - Prepare a booking payload with product, dates, number of attendees, and package context.
Calling CURL
curl -X 'POST' \
'https://api.clubmed.com/v3/proposals/search' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ ... }'
Example answer
{
"id": "123456",
"product_id": "MPAC",
"price": {
"total": 9815.4,
"currency": "EUR"
},
"remaining_stock": 2,
"option_available": true
}
info: The returned
proposal_idbecomes the working file for services, attendees, insurance, and booking creation.
Response codes
200 OK: returns the proposal matching the submitted criteria.400 Bad Request: the payload is invalid, incomplete, or inconsistent.401 Unauthorized: authentication is missing, invalid, or expired.403 Forbidden: the current context cannot create the proposal.404 Not Found: the product cannot be found.409 Conflict: the proposal criteria are no longer valid.
List available additional services
Use GET/v0/additional_services with proposal_id to list the additional services available for the current proposal. This step is typically used to surface childcare, transfer, rental, or activity upsells before the proposal is qualified.
Prerequisites
- Reuse a valid
proposal_id. - Send
accept-languageandx-api-key. - Optionally add
typeswhen you want to focus on a specific family of services.
Calling CURL
curl -X 'GET' \
'https://api.clubmed.com/v0/additional_services?proposal_id=123456' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'x-api-key: YOUR_API_KEY'
Example answer
[
{
"id": "VMOSK1",
"type": "CHILDCARE",
"currency": "EUR",
"schedules": [
{
"start_date": "20100430",
"end_date": "20100430",
"remaining_stock": 2
}
]
}
]
info: Only attach services that come from this service-search response. It is the reference list for compatible upsells.
Response codes
200 OK: returns the services available for the proposal.206 Partial Content: the result is partial and more pages may exist.400 Bad Request: the proposal or filters are invalid.401 Unauthorized: authentication is missing, invalid, or expired.403 Forbidden: the current market or authentication does not allow this lookup.404 Not Found: the proposal cannot be found.409 Conflict: the proposal criteria are no longer valid.416 Requested Range Not Satisfiable: the requested range is invalid.
Add selected additional services
Use PUT/v0/proposals/{proposal_id}/services to apply the selected additional services to the proposal. This route works in cancel-and-replace mode, so each call must send the full service selection you want to keep on the proposal.
Prerequisites
- Provide
proposal_id. - Send
accept-language,authorizationwhen required, andx-api-key. - Build the payload from the identifiers returned by the additional-services search route.
Calling CURL
curl -X 'PUT' \
'https://api.clubmed.com/v0/proposals/123456/services' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ ... }'
Example answer
HTTP/1.1 204 No Content
info: Because the route is cancel-and-replace, forgetting a previously selected service will remove it from the proposal.
Response codes
204 No Content: the proposal services were updated successfully.400 Bad Request: services are incompatible, missing, or the payload is invalid.401 Unauthorized: authentication is missing, invalid, or expired.404 Not Found: the proposal cannot be found.409 Conflict: the proposal is no longer economically valid.
Qualify proposal attendees
Use PUT/v3/proposals/{proposal_id}/attendees to attach or update attendees on the proposal before turning it into a booking. This is where identity, household composition, and customer linkage are validated.
Prerequisites
- Provide
proposal_id. - Send
accept-language,authorizationwhen required, andx-api-key. - Prepare an attendee payload that respects the rules on birthdates, documents, and household consistency.
Calling CURL
curl -X 'PUT' \
'https://api.clubmed.com/v3/proposals/123456/attendees' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ ... }'
Example answer
[
{
"attendees": [
{
"id": "A",
"customer_id": "123456789",
"customer_status": "NEW_CUSTOMER",
"loyalty_status": "GOLD"
}
]
}
]
info: Most blocking data-quality issues appear here, so the UI should surface the validation feedback clearly.
Response codes
200 OK: returns the updated attendee structure.400 Bad Request: attendee data is invalid, incomplete, duplicated, or inconsistent.401 Unauthorized: authentication is missing, invalid, or expired.403 Forbidden: at least one customer is not allowed to continue.409 Conflict: the proposal is no longer economically valid.
List available insurance options
Use GET/v0/additional_services with types=INSURANCE to list the insurance products available for the proposal. This step isolates the insurance subset so the user can review guarantees before adding or replacing them on the proposal.
Prerequisites
- Reuse a valid
proposal_id. - Send
accept-languageandx-api-key. - Add
types=INSURANCEto focus on insurance services only.
Calling CURL
curl -X 'GET' \
'https://api.clubmed.com/v0/additional_services?proposal_id=123456&types=INSURANCE' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'x-api-key: YOUR_API_KEY'
Example answer
[
{
"id": "TRAVEL_INSURANCE",
"type": "INSURANCE",
"currency": "EUR",
"schedules": [
{
"start_date": "20100430",
"end_date": "20100430",
"remaining_stock": 99
}
]
}
]
info: Filtering the service search on
INSURANCEkeeps the UI focused on insurance choices instead of the full additional-service catalog.
Response codes
200 OK: returns the insurance services available for the proposal.206 Partial Content: the result is partial and more pages may exist.400 Bad Request: the proposal or filters are invalid.401 Unauthorized: authentication is missing, invalid, or expired.403 Forbidden: the current market or authentication does not allow this lookup.404 Not Found: the proposal cannot be found.409 Conflict: the proposal criteria are no longer valid.416 Requested Range Not Satisfiable: the requested range is invalid.
Add the selected insurance
Use PUT/v0/proposals/{proposal_id}/services to apply the selected insurance to the proposal. Because the route behaves as cancel-and-replace, the insurance payload must be merged with the rest of the services you want to keep.
Prerequisites
- Provide
proposal_id. - Send
accept-language,authorizationwhen required, andx-api-key. - Build the insurance payload from identifiers returned by the insurance-service search step.
Calling CURL
curl -X 'PUT' \
'https://api.clubmed.com/v0/proposals/123456/services' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ ... }'
Example answer
HTTP/1.1 204 No Content
info: Never send only the new insurance if other services must remain on the proposal. The route replaces the whole service list.
Response codes
204 No Content: the proposal services were updated successfully.400 Bad Request: services are incompatible, missing, or the payload is invalid.401 Unauthorized: authentication is missing, invalid, or expired.404 Not Found: the proposal cannot be found.409 Conflict: the proposal is no longer economically valid.
Remove an insurance from the proposal
Use PUT/v0/proposals/{proposal_id}/services to remove an insurance from the proposal by sending an updated service list without that insurance. Because the route replaces the full list, removal is done by omission in the new payload.
Prerequisites
- Provide
proposal_id. - Send
accept-language,authorizationwhen required, andx-api-key. - Start from the current proposal service state so you only remove the targeted insurance.
Calling CURL
curl -X 'PUT' \
'https://api.clubmed.com/v0/proposals/123456/services' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ ... }'
Example answer
HTTP/1.1 204 No Content
info: To remove only one insurance safely, rebuild the payload from the latest service state instead of composing it from memory.
Response codes
204 No Content: the service list was updated successfully.400 Bad Request: services are incompatible, missing, or the payload is invalid.401 Unauthorized: authentication is missing, invalid, or expired.404 Not Found: the proposal cannot be found.409 Conflict: the proposal is no longer economically valid.
Create the booking option
Use POST/v3/bookings to create the booking option from the qualified proposal. This is the step that turns the proposal into a booking file and consumes Club Med stock.
Prerequisites
- Send
accept-language,authorizationwhen required, andx-api-key. - Make sure attendee data has already been qualified on the proposal.
- Keep the same locale that was used for proposal creation and qualification.
Calling CURL
curl -X 'POST' \
'https://api.clubmed.com/v3/bookings' \
-H 'accept: application/json' \
-H 'accept-language: en-US' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ ... }'
Example answer
{
"booking_id": "654321",
"households": [
{
"attendees": [
{
"customer_id": 987654,
"type": "MAIN"
}
]
}
],
"option_durability": {
"is_reliable": true,
"expiration_date_time": "20160415T10:23:00.234Z"
}
}
info: Booking creation is the committing step of the journey. If it fails, the error usually points to stale proposal data, missing services, or attendee inconsistencies.
Response codes
200 OK: the booking was created and confirmation data is returned.201 Created: the booking was created successfully.400 Bad Request: the payload is invalid or one required data element is missing.401 Unauthorized: authentication is missing, invalid, or expired.403 Forbidden: the current context is not allowed to create the booking.409 Conflict: price, stock, promotion, or transport conditions are no longer valid.419: the related flight is no longer available.