Consola API
Pruébalo
Envía una petición real al entorno sandbox e inspecciona la respuesta.
Credenciales
Inicia sesión para elegir entre tus API keys guardadas en vez de pegarlas.
Cuerpo de la petición
Petición cURL
curl -X POST 'https://api.sandbox.travelandz.com/v1/transfers/reservations/changes' \
-H 'Authorization: Bearer YOUR_SECRET_KEY' \
-H 'X-Travelandz-Id: YOUR_PUBLIC_KEY:YOUR_PROFILE_CODE' \
-H 'Content-Type: application/json' \
-d '{"oldReservationId":"5c8563a5d31d4c33a3a1eafbbfe59c4b","useReservationCard":true,"gdsprovider":0,"bookingToken":"opaque_change_offer_token_generated_by_travelandz","pricingToken":"opaque_change_pricing_token_generated_by_travelandz","searchId":"5c8563a5d31d4c33a3a1eafbbfe59c49","resultId":"763475651c06f5ac31ea587084dc0640","currency":"USD","email":"happytraveler@example.com","countryCodeName":"US","phoneNumber":"+18775998200","firstName":"Happy","lastName":"Traveler","airline":"AA","flightNumber":"123","customerSpecialInstructions":"Special instructions changed","partnerTrackingId":"change-1234567ABC"}'Añade tus credenciales para enviar una petición.
Esta petición necesita identificadores o tokens de una llamada anterior. Ejecuta primero el paso previo y pega aquí sus valores.
Respuesta
Pulsa «¡Pruébalo!» para enviar una petición y ver la respuesta aquí.
Reemplaza una reserva existente con una oferta de cambio seleccionada y cotizada.
Autenticación y headers
| Header | Descripción |
|---|---|
Authorization | Bearer <secret_key>. Conserva el secret en el servidor y nunca lo escribas en logs del cliente. |
X-Travelandz-Id | <public_key>:<profile_code>, donde el profile code persistido usa el formato dp_<12 alfanuméricos>. |
LANG | Header recomendado para el idioma. También se acepta Accept-Language. |
Content-Type | application/json para peticiones con body JSON. |
Petición
Acepta todos los campos del booking, más el oldReservationId obligatorio. Usa el bookingToken y el pricingToken generados por el flujo de cambio, no los de la reserva original. Usa useReservationCard para reutilizar el método de pago ya asociado a la reserva.
Schema del body
oldReservationIduseReservationCardgdsprovider0.bookingTokenbookingToken of the selected offer.searchIdsearchId of the selected offer.resultIdresultId of the selected offer.pricingTokenselectedAmenitiesselectedAmenities[]currencyUSD on a new search and is inherited afterwards.emailcountryCodeNameUS or ES.phoneNumberfirstNamelastNamecustomerSpecialInstructionspartnerTrackingIdairlineflightInfoRequired: true. Send it together with flightNumber.flightNumberreturnAirlinereturnFlightNumber.returnFlightNumberextraPaxInfoextraPaxInfo[]firstNameextraPaxInfo[]lastNameextraPaxInfo[]emailextraPaxInfo[]phoneNumberticketTypesticketTypes[]idticketTypes[]countscheduleIndexpaymentTokensuccessUrllanguageLANG or Accept-Language header.Ejemplo de petición
{
"oldReservationId": "5c8563a5d31d4c33a3a1eafbbfe59c4b",
"useReservationCard": true,
"gdsprovider": 0,
"bookingToken": "opaque_change_offer_token_generated_by_travelandz",
"pricingToken": "opaque_change_pricing_token_generated_by_travelandz",
"searchId": "5c8563a5d31d4c33a3a1eafbbfe59c49",
"resultId": "763475651c06f5ac31ea587084dc0640",
"currency": "USD",
"email": "happytraveler@example.com",
"countryCodeName": "US",
"phoneNumber": "+18775998200",
"firstName": "Happy",
"lastName": "Traveler",
"airline": "AA",
"flightNumber": "123",
"customerSpecialInstructions": "Special instructions changed",
"partnerTrackingId": "change-1234567ABC"
}Respuesta exitosa
Responde con el mismo envelope que el booking.
Lee status junto con completed antes de comunicar nada al viajero:
completedconcompleted: truey al menos una reserva: el transfer está reservado.pending: todavía no hay respuesta definitiva. Consulta la reserva para saber cómo terminó; no repitas la petición.failed: la reserva fue rechazada.errorexplica el motivo.
Cuando el cambio se completa, los identificadores de la nueva reserva reemplazan a los de la anterior. Actualiza todo lo que tuvieras guardado de la reserva original.
Schema de respuesta
statuscompletedreservations is not empty.timedOutreservationsreservations[]gdsproviderreservations[]reservationIdreservations[]confirmationNumberreservations[]statusreservations[]cancelledreservations[]totalAmountreservations[]currencyreservations[]pickupInstructionsreservations[]ticketUrlreservations[]selectedScheduleIndexreservations[]departureDatetimereservations[]arrivalDatetimereservations[]selectedAmenitiesreservations[]selectedAmenities[]keyselectedAmenities.reservations[]selectedAmenities[]namereservations[]selectedAmenities[]descriptionreservations[]selectedAmenities[]imageUrlreservations[]selectedAmenities[]pngImageUrlreservations[]selectedAmenities[]inputTypereservations[]selectedAmenities[]includedreservations[]selectedAmenities[]selectablereservations[]selectedAmenities[]selectederrorstatus is failed.metadatametadatauseSearchIdForDetailssearchId instead of reservationId.metadatadetailsIdentifiermetadatadetailsSearchIddetailsIdentifier is searchId.metadatamessageEjemplos de respuesta
200 Cambiado
{
"status": "completed",
"completed": true,
"timedOut": false,
"reservations": [
{
"gdsprovider": 0,
"reservationId": "c204ab71cf4c4f0d9a2f2c5a4de1b8f3",
"confirmationNumber": "TZ-6202244",
"status": "completed",
"cancelled": false,
"totalAmount": 49.84,
"currency": "USD",
"pickupInstructions": "The driver will call you when he arrives.",
"departureDatetime": "2026-08-30T22:40:00-04:00",
"arrivalDatetime": "2026-08-30T23:06:00-04:00",
"selectedAmenities": []
}
],
"metadata": {
"useSearchIdForDetails": false,
"detailsIdentifier": "reservationId"
}
}200 Sin respuesta definitiva
{
"status": "pending",
"completed": false,
"timedOut": false,
"reservations": [],
"metadata": {
"useSearchIdForDetails": false,
"detailsIdentifier": "reservationId"
}
}Errores
| HTTP | Código | Significado | Acción recomendada |
|---|---|---|---|
400 | El body, la query o el path son inválidos, o incluyen una propiedad desconocida. | Corrige la petición usando el array message. | |
400 | transfer_invalid_currency | La moneda está fuera de la lista soportada. | Usa una moneda soportada. |
400 | transfer_invalid_language | El idioma solicitado no está soportado. | Usa uno de los valores de idioma documentados. |
429 | transfer_provider_error | El servicio está temporalmente limitado por rate limit. | Reintenta con backoff exponencial. |
502 | transfer_provider_error | La petición no pudo completarse. | No asumas que tuvo éxito. Conserva tus identificadores y consulta la reserva cuando la operación pudiera haberse creado. |
400 | transfer_pricing_required | La petición no incluye pricing token. | Llama primero a pricing y envía su pricingToken. |
400 | transfer_invalid_booking_token | El booking token expiró, fue modificado o no pertenece a esta oferta. | Vuelve a buscar y usa el token de la nueva oferta seleccionada. |
400 | transfer_invalid_pricing_token | El pricing token es inválido o inconsistente con el resto de la petición. | Vuelve a pedir pricing y envía sin cambios el token devuelto. |
400 | transfer_invalid_amenities | Las keys de amenities están duplicadas, vacías o no están disponibles en esta oferta. | Envía keys únicas tomadas de la oferta o del catálogo de amenities. |
400 | transfer_currency_mismatch | La moneda no coincide con la oferta, la cotización o la reserva. | Reutiliza la moneda devuelta por el paso anterior, u omite el campo para heredarla. |
400 | transfer_flight_info_required | La oferta exige airline y flightNumber. | Envía ambos campos de vuelo cuando la oferta tenga flightInfoRequired: true. |
400 | transfer_return_flight_info_required | Un round trip exige los datos del vuelo de retorno. | Envía returnAirline y returnFlightNumber. |
409 | transfer_price_changed | El precio de la oferta ya no es el que se cotizó. | Vuelve a pedir pricing y cobra el nuevo finalPrice.amount. |
409 | transfer_booking_in_progress | La reserva no pudo aceptarse para este pricing token. | Consulta la reserva antes de crear otra, para no reservar dos veces. |
410 | transfer_pricing_expired | La cotización expiró antes de crear la reserva. | Vuelve a buscar y a cotizar. |
Notas de uso
Si un token de cambio expira o el importe cambia, repite la búsqueda de cambio y el pricing. Un oldReservationId ausente o mal formado se rechaza con 400.
Ejemplo cURL
curl --request POST \
--url "https://api.sandbox.travelandz.com/v1/transfers/reservations/changes" \
-H "Authorization: Bearer $TRAVELANDZ_SECRET_KEY" \
-H "X-Travelandz-Id: $TRAVELANDZ_PUBLIC_KEY:$TRAVELANDZ_PROFILE_CODE" \
-H "Content-Type: application/json" \
--data '{
"oldReservationId": "5c8563a5d31d4c33a3a1eafbbfe59c4b",
"useReservationCard": true,
"gdsprovider": 0,
"bookingToken": "opaque_change_offer_token_generated_by_travelandz",
"pricingToken": "opaque_change_pricing_token_generated_by_travelandz",
"searchId": "5c8563a5d31d4c33a3a1eafbbfe59c49",
"resultId": "763475651c06f5ac31ea587084dc0640",
"currency": "USD",
"email": "happytraveler@example.com",
"countryCodeName": "US",
"phoneNumber": "+18775998200",
"firstName": "Happy",
"lastName": "Traveler",
"airline": "AA",
"flightNumber": "123",
"customerSpecialInstructions": "Special instructions changed",
"partnerTrackingId": "change-1234567ABC"
}'