Add a transfer to a proposal

  • Booking Upsell
  • Transfer option
  • 4 routes
How do I add a transfer service to an existing proposal?

This scenario explains how to locate a proposal, identify transfer offers inside the additional services catalogue, add the selected transfer to the proposal, and verify the result.

Overview

The sequence starts with a proposal search, then uses the additional services catalogue to target the available transfer services before updating the proposal service list and checking the result.

Prerequisites

  • A valid proposal must be created or found first.
  • The proposal_id returned by the first step is required to search, update, and verify proposal services.
  • accept-language and x-api-key are required on the documented calls.
  • The final update follows a cancel & replace logic: if other services must remain attached, they also need to be carried in the PUT payload.

Process workflow

Legend:
Mandatory
Optional
1

Find the proposal to enrich

Mandatory

Use this route to search for the proposals matching the stay criteria provided by your journey. Use it to retrieve the target proposal, keep its proposal_id, and check whether an additional transfer really needs to be added.

Prerequisites

  • accept-language and x-api-key are required.
  • The request body must contain the main search criteria such as product_id, resort_arrival_date, duration, and number_attendees.
  • Keep the id of the selected proposal for the next steps.

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 '{
    "product_id": "BALC",
    "resort_arrival_date": "20260204",
    "duration": 7,
    "number_attendees": 2,
    "known_attendees_information": [
      {"birthdate": "19960905"},
      {"birthdate": "19780619"}
    ]
  }'

Example answer

[
  {
    "id": "123456",
    "product_id": "MPAC",
    "booking_id": 123456,
    "package_id": "AI",
    "label": "Proposal with one club room",
    "duration": 7,
    "price": {
      "total": 9815.4,
      "currency": "EUR",
      "is_transfer_included": true
    },
    "option_available": true,
    "is_bookable": false
  }
]

info: check price.is_transfer_included on the selected proposal: when transport already includes the transfer, no additional transfer service is usually expected.


Response codes

  • OK Response (200): the search returned a list of proposals matching the submitted criteria.
  • Error (400): the criteria or payload are invalid, incomplete, or inconsistent with the search rules documented in Swagger.
  • Error (401): the request is unauthorized because the authentication data or API key is missing, invalid, or expired.
  • Error (403): at least one customer or selling context is not allowed to proceed with the booking flow.
  • Error (404): the requested product cannot be found for the submitted context.
  • Error (409): the proposal criteria are no longer valid at search time.
POST/v3/proposals/search
See more
2

Search available transfer services

Mandatory

This route returns the additional services available for a given proposal. In this scenario, use types=TRANSFER to retrieve only the eligible transfer services before selecting the one to add to the proposal.

Prerequisites

  • accept-language and x-api-key are required.
  • The proposal_id query parameter is required to target the proposal selected in the previous step.
  • Use types=TRANSFER to filter transfer services only.

Calling CURL

curl -X 'GET' \
  'https://api.clubmed.com/v0/additional_services?proposal_id=24797468&types=TRANSFER' \
  -H 'accept: application/json' \
  -H 'accept-language: en-US' \
  -H 'x-api-key: YOUR_API_KEY'

Example answer

[
  {
    "id": "BALVDP",
    "currency": "EUR",
    "product_information_id": "BALVDP",
    "type": "TRANSFER",
    "schedules": [
      {
        "start_date": "20260211",
        "end_date": "20260211",
        "remaining_stock": 969,
        "attendees": [
          {
            "id": "A",
            "price": 16
          },
          {
            "id": "B",
            "price": 16
          }
        ]
      }
    ],
    "age_in_months": {
      "min": null,
      "max": 1199
    },
    "not_compatible_with": [],
    "sold_only_with": []
  }
]

info: on proposals with transport, the transfer can already be included. In that case, the service search may return an empty array or no sellable additional transfer.


Response codes

  • OK Response (200): the list of available transfer services was returned successfully.
  • OK Response (206): the response is partial.
  • Error (400): the proposal or booking context is invalid, not validated, or inconsistent with the submitted customer.
  • Error (401): the request is unauthorized because the authentication data or API key is missing, invalid, or expired.
  • Error (403): access is forbidden for the targeted country or the expected authentication is missing for some usages.
  • Error (404): the proposal or booking was not found for the submitted context.
  • Error (409): the proposal criteria are no longer valid when the list is requested.
  • Error (416): the requested range or filter is not satisfiable.
GET/v0/additional_services
See more
3

Add the transfer to the proposal

Mandatory

This route updates the list of services attached to the proposal so the selected transfer becomes part of it. The resource behaves as cancel & replace: the payload must contain the complete set of services that should remain attached to the proposal after the update.

Prerequisites

  • accept-language and x-api-key are required.
  • The proposal_id path parameter is required.
  • The request body must contain the selected transfer identifier together with the relevant schedules and attendees.
  • If other services must remain attached, read them first and include them in the final payload as well.

Calling CURL

curl -X 'PUT' \
  'https://api.clubmed.com/v0/proposals/24796514/services' \
  -H 'accept: application/json' \
  -H 'accept-language: en-US' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '[
    {
      "id": "BALVDP",
      "schedules": [
        {
          "start_date": "20260211",
          "end_date": "20260211",
          "attendees": [
            {"id": "A"}
          ]
        }
      ]
    }
  ]'

Example answer

No response body is documented on success. Swagger documents a 204 No Content success response.

info: if you submit only the transfer without carrying the other services that must remain, they can be removed from the proposal during the update.


Response codes

  • OK Response (204): the service list was updated successfully with no response body.
  • Error (400): the payload is invalid, contains an incompatible service, or omits a required service.
  • Error (401): the request is unauthorized because the authentication data or API key is missing, invalid, or expired.
  • Error (404): the targeted proposal cannot be found.
  • Error (409): the proposal economic control is no longer valid at update time.
PUT/v0/proposals/{proposal_id}/services
See more
4

Verify the added transfer

Mandatory

This route reads back the services currently attached to the proposal after the update. Use it to confirm that the expected transfer is present with the correct attendees and dates.

Prerequisites

  • x-api-key is required.
  • The proposal_id path parameter is required.
  • Run this verification after the service update PUT.

Calling CURL

curl -X 'GET' \
  'https://api.clubmed.com/v0/proposals/24797468/services' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY'

Example answer

[
  {
    "id": "BALVDP",
    "type": "TRANSFER",
    "currency": "EUR",
    "schedules": [
      {
        "start_date": "20260211",
        "end_date": "20260211",
        "attendees": [
          {
            "id": "A",
            "price": 16,
            "price_without_discount": 16,
            "discounts": []
          }
        ]
      }
    ],
    "product_information_id": "BALVDP",
    "sold_only_with": [],
    "not_compatible_with": []
  }
]

info: if the expected transfer does not appear in this read-back, recheck the PUT payload and the eligibility constraints returned by the service search.


Response codes

  • OK Response (200): the services currently attached to the proposal were returned successfully and allow you to verify the transfer presence.
  • Error (400): the request is invalid or the submitted filter cannot be processed.
  • Error (401): not documented in Swagger.
  • Error (404): not documented in Swagger.
GET/v0/proposals/{proposal_id}/services
See more