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/book' \
-H 'Authorization: Bearer YOUR_SECRET_KEY' \
-H 'X-Travelandz-Id: YOUR_PUBLIC_KEY:YOUR_PROFILE_CODE' \
-H 'Content-Type: application/json' \
-d '{"gdsprovider":0,"bookingToken":"opaque_offer_token_generated_by_travelandz","pricingToken":"opaque_public_pricing_token_generated_by_travelandz","searchId":"73a5670b476649a985f0535db1077c05","resultId":"fe94b51ccd0623a9f1adabfbe0614d34","selectedAmenities":["baby_seats","child_booster"],"currency":"USD","email":"happytraveler@example.com","countryCodeName":"US","phoneNumber":"+18775998200","firstName":"Happy","lastName":"Traveler","airline":"AA","flightNumber":"123","customerSpecialInstructions":"My doorbell is broken, please call on arrival","partnerTrackingId":"1234567ABC","extraPaxInfo":[{"firstName":"Jose","lastName":"Smith"}]}'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í.
Crea una reserva a partir de una oferta 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
Envía el bookingToken, pricingToken, searchId y resultId que ya tienes, más los datos de contacto del viajero. selectedAmenities y currency deben coincidir con lo que enviaste a pricing.
Cuando la oferta tiene flightInfoRequired: true, airline y flightNumber son obligatorios. Un round trip que requiere datos de vuelo exige también returnAirline y returnFlightNumber. Si envías ticketTypes, la suma de count debe igualar al pasajero principal más la longitud de extraPaxInfo, así que envía también extraPaxInfo — un array vacío para un único viajero.
Schema del body
gdsprovider0.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
{
"gdsprovider": 0,
"bookingToken": "opaque_offer_token_generated_by_travelandz",
"pricingToken": "opaque_public_pricing_token_generated_by_travelandz",
"searchId": "73a5670b476649a985f0535db1077c05",
"resultId": "fe94b51ccd0623a9f1adabfbe0614d34",
"selectedAmenities": [
"baby_seats",
"child_booster"
],
"currency": "USD",
"email": "happytraveler@example.com",
"countryCodeName": "US",
"phoneNumber": "+18775998200",
"firstName": "Happy",
"lastName": "Traveler",
"airline": "AA",
"flightNumber": "123",
"customerSpecialInstructions": "My doorbell is broken, please call on arrival",
"partnerTrackingId": "1234567ABC",
"extraPaxInfo": [
{
"firstName": "Jose",
"lastName": "Smith"
}
]
}Respuesta exitosa
El booking responde con HTTP 200 y un campo status en lugar de 201, porque la reserva no siempre queda confirmada de inmediato.
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.
metadata.detailsIdentifier te indica qué identificador usar al consultar después la reserva.
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 Reservado
{
"status": "completed",
"completed": true,
"timedOut": false,
"reservations": [
{
"gdsprovider": 0,
"reservationId": "f390daff1fdf4cccb19b7abd825dc011",
"confirmationNumber": "TZ-6202191",
"status": "completed",
"cancelled": false,
"totalAmount": 181.97,
"currency": "USD",
"pickupInstructions": "The driver will call you when he arrives.",
"selectedScheduleIndex": 0,
"departureDatetime": "2026-08-16T14:40:00-04:00",
"arrivalDatetime": "2026-08-16T15:06:00-04:00",
"selectedAmenities": [
{
"key": "baby_seats",
"name": "Baby seats",
"description": "Your vehicle will have a child safety seat to keep children under age 4 safe.",
"imageUrl": "https://api.sandbox.travelandz.com/v1/assets/transfers/images/0/amenities/baby-seats.svg",
"pngImageUrl": "https://api.sandbox.travelandz.com/v1/assets/transfers/images/0/amenities/baby-seats.png",
"inputType": "numeric",
"included": false,
"selected": true,
"selectable": true
},
{
"key": "child_booster",
"name": "Child booster",
"description": "Your vehicle will have a child booster seat to keep children from age 4-8 safe.",
"imageUrl": "https://api.sandbox.travelandz.com/v1/assets/transfers/images/0/amenities/child-booster.svg",
"pngImageUrl": "https://api.sandbox.travelandz.com/v1/assets/transfers/images/0/amenities/child-booster.png",
"inputType": "numeric",
"included": false,
"selected": true,
"selectable": true
}
]
}
],
"metadata": {
"useSearchIdForDetails": true,
"detailsIdentifier": "searchId",
"detailsSearchId": "73a5670b476649a985f0535db1077c05",
"message": "This booking includes amenities. Use searchId to retrieve complete reservation details."
}
}200 Sin respuesta definitiva
{
"status": "pending",
"completed": false,
"timedOut": true,
"reservations": [],
"metadata": {
"useSearchIdForDetails": false,
"detailsIdentifier": "reservationId"
}
}200 Rechazado
{
"status": "failed",
"completed": false,
"timedOut": false,
"reservations": [],
"error": "The booking could not be completed",
"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
Cobra al viajero únicamente el finalPrice.amount devuelto por pricing. Si recibes transfer_price_changed, vuelve a pedir pricing y cobra el nuevo importe.
Si una petición de booking falla con 502, no asumas que falló funcionalmente: consulta la reserva con los identificadores que ya tienes antes de crear otra. Las reservas con amenities deben consultarse por searchId.
Nunca registres tokens, datos de pago ni datos personales del viajero en el cliente.
Ejemplo cURL
curl --request POST \
--url "https://api.sandbox.travelandz.com/v1/transfers/book" \
-H "Authorization: Bearer $TRAVELANDZ_SECRET_KEY" \
-H "X-Travelandz-Id: $TRAVELANDZ_PUBLIC_KEY:$TRAVELANDZ_PROFILE_CODE" \
-H "Content-Type: application/json" \
--data '{
"gdsprovider": 0,
"bookingToken": "opaque_offer_token_generated_by_travelandz",
"pricingToken": "opaque_public_pricing_token_generated_by_travelandz",
"searchId": "73a5670b476649a985f0535db1077c05",
"resultId": "fe94b51ccd0623a9f1adabfbe0614d34",
"selectedAmenities": [
"baby_seats",
"child_booster"
],
"currency": "USD",
"email": "happytraveler@example.com",
"countryCodeName": "US",
"phoneNumber": "+18775998200",
"firstName": "Happy",
"lastName": "Traveler",
"airline": "AA",
"flightNumber": "123",
"customerSpecialInstructions": "My doorbell is broken, please call on arrival",
"partnerTrackingId": "1234567ABC",
"extraPaxInfo": [
{
"firstName": "Jose",
"lastName": "Smith"
}
]
}'