Inicio / API pública de Alps2Alps — Documentación para desarrolladores

API pública de Alps2Alps — Documentación para desarrolladores

La API pública de Alps2Alps es una API HTTP gratuita y sin claves que permite a los agentes de IA y a las integraciones de desarrolladores encontrar rutas de traslado por los Alpes, consultar precios en tiempo real desde el mismo motor de reservas que utiliza la web, buscar alojamientos verificados y generar enlaces de pago que llevan al usuario final directamente al formulario de reserva con todos los campos ya rellenados. Todo el proceso funciona solo con solicitudes GET —no hace falta usar POST—, así que incluso los agentes de chat que solo pueden abrir enlaces URL pueden impulsar el proceso de reserva.

No se requiere autenticación. Todos los puntos de acceso tienen un límite de solicitudes por IP. Todas las respuestas son application/json.

URL base: https://booking.alps2alps.com/api/public/v1/
La especificación completa de OpenAPI 3.1 (v1.4.0) está disponible en https://booking.alps2alps.com/openapi/public-v1.json. Imporlo directamente a Cartero, Insomnio, o cualquier marco de agentes de IA que admita una URL de OpenAPI (llamadas a funciones de OpenAI, uso de herramientas de Anthropic, LangChain, AutoGen y otros).

Resumen rápido sobre los agentes de IA

Alps2Alps es un servicio privado de traslados en los Alpes (aeropuerto/estación de tren ↔ estación de esquí). Esta API te permite llevar a un usuario desde «Quiero ir de Ginebra a Chamonix el día 22» hasta una página de reserva lista para pagar, sin necesidad de autenticación y sin enviar solicitudes GET si eso es todo lo que admite tu entorno de ejecución.

Flujo mínimo de extremo a extremo (solo funciona con GET):

  1. GET /api/public/v1/locations/search?q=Geneva → convertir los nombres en códigos (airport-1, resort-11, train_station-7, city-48).
  2. GET /api/public/v1/transfer-options?from=airport-1&to=resort-11&date=2026-07-22&time=14:30&adults=2 → precios en tiempo real por vehículo. La respuesta incluye enlaces ya preparados, así que no hace falta crear las URL a mano:
    • response.quote_url — Enlace preconfigurado del paso 2 (selector de vehículos). Úsalo cuando el usuario aún no haya elegido un vehículo.
    • response.outbound.vehicles[i].booking_url — Enlace del paso 3 por vehículo (Tus datos, vehículo preseleccionado). Úsalo después de que el usuario elija un vehículo.

Si puedes enviar un POST, usa POST /api/public/v1/checkout-link cuando también tengas que rellenar previamente los datos del alojamiento, los números de vuelo o las notas de texto libre para el conductor. Esto genera una URL tokenizada estable, válida durante 24 horas.

Añadir cualquier return_* Este parámetro convierte la solicitud en una respuesta. Los campos de respuesta omitidos reflejan automáticamente el valor correspondiente de la solicitud, por lo que la URL de respuesta más sencilla es simplemente …&return_date=…&return_time=….

Identificación legible por máquina

Todo lo que necesitas para la integración está enlazado en estos archivos de referencia:

  1. Buscar lugares — llama /locations/search para convertir los nombres de recogida y entrega del usuario en airport-… / resort-… / city-… códigos.
  2. (Opcional) Buscar alojamiento — llama /accommodations?resort_id=…&q=… con al menos dos caracteres del nombre del hotel. Elige la entrada que coincida y confirma el nombre exacto con el usuario antes de utilizar su id.
  3. Pide presupuesto para el viaje — llama /transfer-options con los códigos de destino y los datos sobre pasajeros, equipaje y fecha. La respuesta incluye passengers (confirmando el número de pasajeros utilizado), luggage por dirección, y max_passengers / max_luggage por vehículo, para que puedas indicar a los usuarios qué vehículos se adaptan a su grupo. Para los viajes de ida y vuelta, cada vehículo también lleva un total_price para el trayecto completo. Precios actuales, tipos de vehículos, duración del viaje y cualquier descuento promocional. Comprueba siempre el artículo devuelto pick_up_date_time / return.pick_up_date_time volver al usuario — esos son los horarios que el conductor va a seguir.
  4. Lleva al usuario a la caja — una vez que el usuario elija un vehículo, usa el booking_url campo de ese vehículo para que pasen directamente al paso 3 (Tus datos) con todo ya rellenado. Si también necesitas rellenar previamente el alojamiento, el número de vuelo o las notas del conductor, usa POST /checkout-link en su lugar.
  5. El usuario paga: la URL de pago te lleva directamente al paso 3 de la reserva. Solo tienes que introducir tus datos de contacto y completar el pago.

Agentes ligeros (sin capacidad POST)

En el caso de los agentes de chat que solo pueden recuperar URL, es posible seguir el mismo flujo de principio a fin sin necesidad de enviar nunca una solicitud POST:

  1. (Opcional) GET /locations/search?q=… para convertir nombres en códigos.
  2. GET /api/public/v1/transfer-options?from=…&to=…&date=…&time=…&adults=… para obtener precios en tiempo real. La respuesta JSON ya contiene los enlaces; solo tienes que usarlos directamente:
    • response.quote_url — te lleva al paso 2 (selector de vehículos).
    • response.outbound.vehicles[i].booking_url — te lleva al paso 3 con ese vehículo ya seleccionado.
    • Si es necesario, puedes seguir creando estas URL manualmente utilizando los alias de enlaces profundos (consulta la sección «Enlaces profundos» ).

Puntos finales

Busca los puntos de recogida y entrega disponibles: complejos turísticos, aeropuertos, estaciones de tren y ciudades.

Parámetros de consulta

ParámetroObligatorioNotas
qTérmino de búsqueda. Las cadenas de menos de 2 caracteres devuelven una matriz vacía.

Respuesta

Una matriz plana de ubicaciones coincidentes. Los códigos de los complejos turísticos siguen el patrón resort-{id}; a continuación, los códigos de los centros de transporte {type}-{id} (p. ej., airport-1, train_station-7, city-48).

[
  { "code": "airport-1",  "name": "Geneva Airport", "type": "airport", "country": "Switzerland" },
  { "code": "resort-11",  "name": "Chamonix",        "type": "resort",  "country": "France" }
]

Errores

  • 400 INVALID_PARAMSq Falta por completo el parámetro.

Ejemplo

curl "https://booking.alps2alps.com/api/public/v1/locations/search?q=cham"

2. GET /api/public/v1/accommodations

Búsqueda de hoteles mediante entrada manual en el catálogo de alojamientos verificados que utiliza la función de autocompletado del paso 3 del proceso de reserva. Los resultados se limitan a un radio de 10 km alrededor del complejo turístico indicado. El flujo previsto es una búsqueda mediante entrada manual: el usuario indica el nombre del hotel y el agente lo transmite como q limitado al complejo turístico, y selecciona el que coincida id para enviar a /checkout-link.

Parámetros de consulta

ParámetroObligatorioPredeterminadoNotas
resort_idID numérico del complejo turístico de un resort-{id} código de ubicación.
qSubcadena del nombre del alojamiento (sin tener en cuenta los acentos). Mín. 2, máx. 100 caracteres.
limitNo20Límite máximo de 50.

Respuesta

{
  "data": [
    {
      "id": 38959,
      "name": "Clos 66",
      "address": "66 Clos des Charmilles, Chamonix",
      "latitude": 45.9123,
      "longitude": 6.8694
    }
  ],
  "total": 4
}

total ¿cuántos son? antes limit se aplica, para que quien lo llama pueda saber cuándo se han truncado los resultados.

Importante: Solo id los valores devueltos por este punto final se pueden pasar a /checkout-link como accommodation_id. No se aceptan nombres de hoteles escritos libremente, lo que garantiza que cada pedido cuente con un nombre y una dirección verificados.

Errores

  • 400 INVALID_PARAMSresort_id falta o no es un número entero, o q falta o tiene menos de 2 caracteres.
  • 404 RESORT_NOT_FOUND — El ID del complejo es desconocido, está inactivo o no tiene coordenadas.

Ejemplo

curl "https://booking.alps2alps.com/api/public/v1/accommodations?resort_id=11&q=clos"

3. GET / POST /api/public/v1/transfer-options

Devuelve precios en tiempo real para cada tipo de vehículo disponible en la ruta solicitada, en la moneda solicitada y con la configuración de pasajeros y equipaje solicitada. No se guarda nada: este es un punto final solo para presupuestos. Hay dos tipos de solicitud que comparten el mismo formato de respuesta:

  • PUBLICAR — cuerpo JSON canónico utilizando book\forms\Transfer Nombres de campos. Recomendado para clientes programáticos con control total sobre los encabezados y el cuerpo.
  • CONSEGUIR — cadena de consulta de alias amigable (from, to, date, time, …). Para los agentes de IA y las herramientas de chat que crean las URL manualmente. Consulta la Enlaces directos sección para ver la tabla completa de alias.

Importante: hora de llegada frente a hora de recogida: Por defecto, time y return_time se interpretan como vuelo veces (is_flight y return_is_flight por defecto 1). El sistema calcula el valor real recogida restando la hora del vuelo; en el caso del viaje de vuelta, la recogida en el complejo será antes que la duración del vuelo indicada.

Si el usuario indica un valor deseado recogida una hora en lugar de una hora de vuelo (por ejemplo, «ven a recogernos a las 14:30», «sal del complejo a las 18:00»), establece is_flight=0 y/o return_is_flight=0. De lo contrario, la hora de recogida indicada no será correcta.

Comprueba siempre el artículo devuelto pick_up_date_time / return.pick_up_date_time de vuelta al usuario: esos son los horarios reales que utilizará el conductor.

Ejemplo: Una solicitud con return_time=18:00 y el valor predeterminado return_is_flight=1 (del complejo turístico al aeropuerto) "return.pick_up_date_time": "2026-07-26 14:20:00" — el sistema calculó la hora de salida a partir de un vuelo de las 18:00. Para conseguir un vuelo a las 18:00 recogida, envía &return_is_flight=0.

Cuerpo de la solicitud (POST)

Acepta application/json o application/x-www-form-urlencoded.

CampoTipoObligatorioNotas
route_from_codecadenap. ej. airport-1
route_to_codecadenap. ej. resort-11
outbound_datecadenaYYYY-MM-DD
outbound_time_hoursint0-23
outbound_time_minutesint0–59
outbound_selected_time_is_flightint (0/1)No (valor predeterminado: 1)1 = La hora es la hora de llegada del vuelo; la recogida está calculada. 0 = La hora es la hora de recogida exacta.
is_returnint (0/1)No (valor predeterminado: 0)Cuando 1, todos return_* Estos campos son obligatorios
adult_countint≥ 1
children_countintNo
infant_countintNo
children_age_seat_countintNoNúmero de niños en edad de usar silla infantil
children_age_booster_countintNoNúmero de niños en edad de usar un asiento elevador
luggage_countintNo
skibag_countintNo
has_ski_equipmentint (0/1)No
currency_codecadenaNo (por defecto, EUR)ISO 4217. Resultados de códigos desconocidos o inactivos 400 CURRENCY_NOT_SUPPORTED.
promo_codecadenaNoSi no es válido, se ignora sin avisar

Para los viajes de vuelta, copia los campos del viaje de ida con un return_ prefijo: return_route_to_code, return_date, return_time_hours, return_time_minutes, return_selected_time_is_flight (por defecto 1 — mira la nota sobre la hora más arriba), return_adult_count, return_children_count, return_infant_count, return_children_age_seat_count, return_children_age_booster_count, return_luggage_count, return_skibag_count, return_has_ski_equipment.

Cadena de consulta GET: parámetros adicionales

Todos los alias de salida y de retorno se describen en la sección «Enlaces profundos ». Los siguientes parámetros adicionales solo son relevantes para las solicitudes GET y no forman parte del cuerpo de la solicitud POST:

ParámetroTipoObligatorioDescripción
child_agescadenaNoEdades de los niños del grupo separadas por comas, p. ej. 8,12. Solo a título informativo: no se utiliza para fijar precios ni para seleccionar vehículos. El valor se devuelve en passengers.child_ages y se guardan en el archivo generado quote_url y booking_url.
return_child_agescadenaNoLo mismo que child_ages para el viaje de vuelta. Solo se conserva en las URL generadas.

El sistema de reservas selecciona los vehículos en función de adults, children, y child_seats/boosters lo que cuenta —no la edad de cada niño. El child_ages existe un parámetro para que los asistentes de IA y las integraciones puedan confirmar al usuario que se ha recibido su entrada. Si hay requisitos específicos en cuanto a los asientos (silla infantil frente a elevador), usa el child_seats y boosters parámetros.

Ver ejemplos

Ida, 2 adultos, 2 maletas:

curl "https://booking.alps2alps.com/api/public/v1/transfer-options?from=airport-1&to=resort-11&date=2026-07-22&time=14:30&adults=2&luggage=2"

Viaje de ida y vuelta, 2 adultos + 1 niño + 3 maletas (situación realista de chat con IA):

curl "https://booking.alps2alps.com/api/public/v1/transfer-options?from=airport-1&to=resort-11&date=2026-07-22&time=14:30&adults=2&children=1&luggage=3&return_date=2026-07-29&return_time=10:00"

Respuesta

Ejemplo de respuesta GET (todos los campos rellenados, viaje de ida):

{
  "disclaimer": "Prices shown are real-time and calculated using the same engine as the booking website.",
  "quote_url": "https://booking.alps2alps.com/book/quick-search?from=airport-1&to=resort-11&date=2026-07-22&time=14%3A30&adults=2",
  "route": {
    "from": "Geneva Airport",
    "from_code": "airport-1",
    "to": "Chamonix",
    "to_code": "resort-11",
    "distance_km": 99,
    "duration_minutes": 100,
    "travel_time": "01:40:00"
  },
  "currency": "EUR",
  "passengers": {
    "adults": 4,
    "children": 2,
    "child_ages": [8, 12],
    "infants": 0,
    "child_seats": 0,
    "boosters": 0
  },
  "outbound": {
    "pick_up_date_time": "2026-07-22 14:30:00",
    "luggage": {
      "normal_suitcases": 2,
      "ski_equipment": 0
    },
    "vehicles": [
      {
        "vehicle_type_id": 10,
        "name": "Standard minivan",
        "price": 247,
        "max_passengers": 8,
        "max_luggage": 8,
        "offer_code": "requested",
        "total_price": null,
        "booking_url": "https://booking.alps2alps.com/book/quick-checkout?from=airport-1&to=resort-11&date=2026-07-22&time=14%3A30&adults=4&children=2&vehicle=10"
      },
      {
        "vehicle_type_id": 4,
        "name": "VIP",
        "price": 418.50,
        "max_passengers": 7,
        "max_luggage": 7,
        "offer_code": "requested",
        "total_price": null,
        "booking_url": "https://booking.alps2alps.com/book/quick-checkout?from=airport-1&to=resort-11&date=2026-07-22&time=14%3A30&adults=4&children=2&vehicle=4"
      }
    ]
  },
  "return": null,
  "promo_code_applied": false
}

Para un viaje de ida y vuelta, cada vehículo en ambos outbound y return los bloques también llevan un total_price:

{
  "vehicle_type_id": 11,
  "name": "Standard XL minivan",
  "price": 257.21,
  "max_passengers": 8,
  "max_luggage": 8,
  "offer_code": "requested",
  "total_price": 473.81,
  "booking_url": "https://booking.alps2alps.com/book/quick-checkout?from=airport-1&to=resort-11&..."
}

Campos de solo lectura (null (cuando se usa POST):

  • quote_url — Enlace del paso 2 ya preparado y rellenado con todos los parámetros de búsqueda actuales. Úsalo cuando el usuario aún no haya elegido un vehículo.
  • vehicles[].booking_url — Un enlace listo para usar al paso 3 del proceso de pago para cada vehículo, con ese vehículo ya seleccionado. Cuando el usuario elija un vehículo, envíale directamente esta URL.

Nota sobre la codificación de URL: El quote_url y booking_url los valores de la respuesta JSON utilizan un literal & carácter para separar los parámetros de la consulta (p. ej., …children=2&currency=EUR), lo cual es correcto para las cadenas de URL dentro de JSON. Algunas herramientas —como ciertos paneles de DevTools de los navegadores y las interfaces de chat con IA— pueden mostrar visualmente &currency como ¤cy porque &curren es una entidad HTML (el símbolo ¤). Se trata de un error de visualización sin importancia. La URL real que devuelve la API es correcta. Copia el valor sin procesar de la respuesta JSON, no de una vista HTML ya renderizada.

Campos presentes tanto en GET como en POST:

  • route.from_code / route.to_code — los códigos de ubicación que aparecían en la solicitud.
  • passengers — la configuración completa de pasajeros tras aplicar los valores predeterminados. Incluye child_ages (matriz de números enteros, o null (si no se proporciona o en POST).
  • outbound.luggage / return.luggage — equipaje que se tiene en cuenta a la hora de calcular el precio de cada tramo (normal_suitcases, ski_equipment). Indica qué motor se utilizó.
  • vehicles[].max_passengers — Número máximo de pasajeros que puede transportar este vehículo. Todos los vehículos devueltos ya han superado el filtro de capacidad, por lo que se ha confirmado que son adecuados para el grupo.
  • vehicles[].max_luggage — Número máximo de maletas que puede llevar este vehículo.
  • vehicles[].total_pricesolo viajes de ida y vuelta. El precio total de este tipo de vehículo para ambos tramos, redondeado a dos decimales. null en viajes de ida. No intentes sumar los precios de los tramos a mano; utiliza total_price al mostrar el coste total del viaje.

Campos de respuesta del código promocional:

Cuando se aplicó una promoción válida:

"promo_code": "AMI10",
"promo_code_applied": true,
"promo_code_discount": { "type": "percent", "value": 5 }

Cuando se ha introducido un código promocional pero no es válido para esta ruta, fecha o grupo:

"promo_code": "AMI10",
"promo_code_applied": false,
"promo_code_message": "Promo code is not valid for this route, date, or group."

Errores

  • 400 INVALID_PARAMS — cuerpo vacío, error de validación o fecha incorrecta.
  • 400 CURRENCY_NOT_SUPPORTED — moneda que no figura en la lista de monedas activas (GET y POST).
  • 404 ROUTE_NOT_FOUND — La combinación de códigos de ubicación no se corresponde con ninguna ruta activa.
  • 422 UNSUPPORTED_ROUTE — de estación a estación, de complejo turístico a complejo turístico u otras combinaciones descartadas por el embudo.
  • 422 MANUAL_BOOKING_REQUIRED — La ruta requiere manipulación manual.
  • 429 RATE_LIMITED — Demasiadas solicitudes desde esta IP. Espera un rato y vuelve a intentarlo.
  • 500 INTERNAL_ERROR — El motor de precios ha generado una excepción no reconocida.

Ejemplo de POST

Solo ida:

curl -X POST -H "Content-Type: application/json" \
  -d '{
        "route_from_code": "airport-1",
        "route_to_code": "resort-11",
        "outbound_date": "2026-07-22",
        "outbound_time_hours": 14,
        "outbound_time_minutes": 30,
        "outbound_selected_time_is_flight": 1,
        "is_return": 0,
        "adult_count": 2,
        "luggage_count": 2,
        "currency_code": "EUR"
      }' \
  "https://booking.alps2alps.com/api/public/v1/transfer-options"

Viaje de ida y vuelta, 2 adultos + 1 niño + 3 maletas (situación realista de chat con IA):

curl -X POST -H "Content-Type: application/json" \
  -d '{
        "route_from_code": "airport-1",
        "route_to_code": "resort-11",
        "outbound_date": "2026-07-22",
        "outbound_time_hours": 14,
        "outbound_time_minutes": 30,
        "outbound_selected_time_is_flight": 1,
        "is_return": 1,
        "adult_count": 2,
        "children_count": 1,
        "luggage_count": 3,
        "currency_code": "EUR",
        "return_date": "2026-07-29",
        "return_time_hours": 10,
        "return_time_minutes": 0,
        "return_selected_time_is_flight": 0,
        "return_adult_count": 2,
        "return_children_count": 1,
        "return_luggage_count": 3
      }' \
  "https://booking.alps2alps.com/api/public/v1/transfer-options"

Acepta el mismo cuerpo que /transfer-options además de algunos campos de rellenado automático opcionales. Devuelve una URL de un solo uso válida durante 24 horas. Usa este punto de conexión cuando necesites rellenar previamente un servicio de adaptaciones, un número de vuelo o notas para el conductor junto con la reserva; para todo lo demás, el booking_url campo en el /transfer-options La respuesta GET es más sencilla.

Campos adicionales del cuerpo

CampoTipoNotas
outbound_vehicle_type_idintOpcional. Por defecto, se elige el vehículo de ida más barato disponible.
return_vehicle_type_idintOpcional. Solo se usa cuando is_return = 1.
outbound_flight_numbercadenaOpcional. Caracteres alfanuméricos + guión, máximo 16 caracteres.
return_flight_numbercadenaOpcional. Solo se usa cuando is_return = 1.
accommodation_idintOpcional. Debe ser un identificador devuelto por /accommodations y a menos de 10 km del complejo turístico de la ruta.
additional_infocadenaOpcional. Nota del conductor en formato de texto libre. Máximo 1000 caracteres.
return_additional_infocadenaOpcional. Nota del conductor para el trayecto de vuelta. Solo se usa cuando is_return = 1.

Respuesta

{
  "checkout_url": "https://alps2alps.com/book/public-checkout/8f1c2c…",
  "expires_at":   "2026-05-28 09:14:22",
  "currency":     "EUR",
  "promo_code_applied": true
}

Errores

Todos los errores de /transfer-options, además:

  • 400 INVALID_PARAMSaccommodation_id no es un número entero positivo.
  • 400 VALIDATION_ERROR — ID del alojamiento desconocido, fuera del radio del complejo turístico de la ruta, o la ruta no tiene un lado del complejo.
  • 422 NO_BOOKABLE_VEHICLE — Ningún vehículo tenía un precio válido en esta ruta.
  • 429 RATE_LIMITED — Demasiadas solicitudes desde esta IP. Espera un rato y vuelve a intentarlo.
  • 500 INTERNAL_ERROR — No se ha podido guardar el enlace de pago.

Ejemplo

curl -X POST -H "Content-Type: application/json" \
  -d '{
        "route_from_code": "airport-1",
        "route_to_code": "resort-11",
        "outbound_date": "2026-07-22",
        "outbound_time_hours": 14,
        "outbound_time_minutes": 30,
        "outbound_selected_time_is_flight": 1,
        "is_return": 0,
        "adult_count": 2,
        "luggage_count": 2,
        "currency_code": "EUR",
        "outbound_vehicle_type_id": 4,
        "outbound_flight_number": "BA123",
        "accommodation_id": 38959,
        "additional_info": "Please call on arrival."
      }' \
  "https://booking.alps2alps.com/api/public/v1/checkout-link"

Una familia de puntos finales GET sin estado que permite a los agentes de IA sencillos y a las herramientas de chat gestionar el proceso de reserva mediante URL simples: sin necesidad de POST, sin entradas en la base de datos y sin caducidad. En la mayoría de los casos, el quote_url y booking_url campos devueltos por GET /transfer-options ya están preparadas para ti; la creación manual de la URL que se muestra a continuación sirve para los casos en los que necesites un control total sobre los parámetros o no puedas realizar una llamada previa a la API.

La disyuntiva frente a POST /checkout-link: los enlaces directos no pueden incluir un ID de alojamiento, un número de vuelo ni notas de texto libre del conductor (esas cosas requieren una validación del lado del servidor). Usa POST /checkout-link cuando necesitas esos extras.

Asignación de alias amigables → campos canónicos

Los tres puntos finales de enlaces profundos traducen los mismos alias de cadenas de consulta compactas. La URL mínima viable es simplemente from + to + date + time.

Saliente / compartido:

AliasCampo canónicoPredeterminadoNotas
fromroute_from_codeObligatorio. Por ejemplo: airport-1
toroute_to_codeObligatorio. Por ejemplo: resort-11
dateoutbound_dateEs obligatorio. YYYY-MM-DD
timeoutbound_time_hours + _minutesEs obligatorio. HH:MM. Se interpreta como la hora de llegada del vuelo por defecto (is_flight=1). Establecer is_flight=0 para saber la hora exacta de recogida.
is_flightoutbound_selected_time_is_flight11 = time Se calcula la llegada del vuelo y la recogida. 0 = time es la hora exacta de recogida.
adultsadult_count2
childrenchildren_count0
child_ages— (solo GET)Edades de los hijos separadas por comas, p. ej. 8,12. Se hace eco en passengers.child_ages y se conservan en las URL generadas. Solo a título informativo.
infantsinfant_count0
child_seatschildren_age_seat_count0
boosterschildren_age_booster_count0
luggageluggage_count2
ski_bagsskibag_count0
skihas_ski_equipment0
currencycurrency_codeEURResultados de códigos desconocidos o inactivos 400 CURRENCY_NOT_SUPPORTED en los puntos de acceso JSON. Los enlaces directos del navegador (quick-search, quick-checkout) se ajustan automáticamente al euro, para que un valor desactualizado nunca impida que un usuario llegue al embudo.
promopromo_codeEl mismo comportamiento de no mostrar mensajes de error que el POST

Viaje de vuelta — cualquiera return_* parámetro (o return=1) lo habilita de forma implícita is_return=1. Campos de retorno omitidos sincronización automática el valor de salida correspondiente, así que la URL de retorno más sencilla es simplemente …&return_date=…&return_time=…:

AliasCampo canónicoConfiguración predeterminada de MirrorNotas
return_toreturn_route_to_codede salida from
return_datereturn_date
return_timereturn_time_hours + _minutesSe interpreta como la hora de salida del vuelo por defecto (return_is_flight=1). La hora de recogida en el complejo será más temprano. Configura return_is_flight=0 para la hora exacta de recogida en el complejo.
return_is_flightreturn_selected_time_is_flightde salida is_flight1 = return_time es la hora de salida del vuelo; la hora de recogida se calcula automáticamente. 0 = return_time es la hora exacta de recogida en el complejo turístico.
return_adultsreturn_adult_countde salida adults
return_childrenreturn_children_countde salida children
return_child_ages— (solo GET)de salida child_agesEdades de los niños separadas por comas para el viaje de vuelta. Solo se conservan en las URL generadas.
return_infantsreturn_infant_countde salida infants
return_child_seatsreturn_children_age_seat_countde salida child_seats
return_boostersreturn_children_age_booster_countde salida boosters
return_luggagereturn_luggage_countde salida luggage
return_ski_bagsreturn_skibag_countde salida ski_bags
return_skireturn_has_ski_equipmentde salida ski

Claves de consulta desconocidas (p. ej., utm_source=…) se ignoran sin avisar.

3a. GET /api/public/v1/transfer-options (cita)

Tiene el mismo formato de respuesta que la variante POST. Devuelve JSON, nunca guarda nada. La respuesta incluye quote_url y por vehículo booking_url campos listos para usar.

Solo ida:

curl "https://booking.alps2alps.com/api/public/v1/transfer-options?from=airport-1&to=resort-11&date=2026-07-22&time=14:30&adults=2&luggage=2&currency=EUR"

Ida y vuelta, 2 adultos + 1 niño + 3 maletas — porque los campos de respuesta se copian automáticamente de los de salida, solo return_date y return_time Hay que añadir:

curl "https://booking.alps2alps.com/api/public/v1/transfer-options?from=airport-1&to=resort-11&date=2026-07-22&time=14:30&adults=2&children=1&luggage=3&return_date=2026-07-29&return_time=10:00"

3b. GET /book/quick-search (aterriza en el paso 2)

Enlace directo sin estado que lleva al navegador a paso 2 del proceso de reserva (selección del vehículo) con los precios ya calculados. Equivalente al quote_url devolvido por GET /transfer-options. Es útil cuando quieres crear el enlace manualmente sin una llamada previa a la API.

Solo ida:

Ida y vuelta, 2 adultos + 1 niño + 3 maletas:

Los errores (error de validación, ruta no compatible, ruta no encontrada, fecha incorrecta) redirigen a /book/?step=1 así que el usuario llega directamente al formulario de reserva, sin ver nunca una página de error.

3c. GET /book/quick-checkout (aterriza en la casilla 3)

Equivalente sin estado de POST /checkout-link. Te lleva a paso 3 (Tus datos) con el canal hidrato a partir de la cadena de consulta. Equivalente a la booking_url campo de cada vehículo en el GET /transfer-options respuesta. El vehicle Este parámetro selecciona automáticamente el tipo de vehículo.

Vehículo de ida, ya seleccionado:

Viaje de ida y vuelta, 2 adultos + 1 niño + 3 maletas, vehículo elegido previamente:

Además quick-checkout parámetros:

AliasNotas
vehicleSalida vehicle_type_id de /transfer-options. Si no lo indicas, el filtro selecciona automáticamente el vehículo más barato.
return_vehicleTipo de vehículo para el viaje de vuelta. El valor predeterminado es vehicle para los viajes de vuelta.

accommodation_id, los números de vuelo y las notas del conductor son no compatible con el flujo GET. Usa POST /checkout-link para ellos.

POST o GET: ¿cuál usar?

NecesitoUso
Solo JSON, control total, de máquina a máquinaPOST /api/public/v1/transfer-options
Citar en una URL (chat, correo electrónico, blog)GET /api/public/v1/transfer-options
De la mano del usuario al seleccionador de vehículos (paso 2): usa la plantilla ya preparada quote_url a partir de la respuesta, o crearla manualmenteGET /book/quick-search
Dirige al usuario al paso 3 con un vehículo ya seleccionado: utiliza la opción preconfigurada booking_url a partir de la respuesta, o crearla manualmenteGET /book/quick-checkout
Dirige al usuario al paso 3 con información sobre el alojamiento, notas del conductor, números de vuelo y un enlace válido durante 24 horasPOST /api/public/v1/checkout-link

Mensaje de error y códigos de error

Todos los errores comparten la misma estructura JSON:

{ "error": { "code": "UNSUPPORTED_ROUTE", "message": "The routes from station to station is not supported" } }
HTTPCódigoCuando
400INVALID_PARAMSCampos de solicitud que faltan o no son válidos, fechas con formato incorrecto o errores de validación.
400CURRENCY_NOT_SUPPORTEDCódigo de divisa desconocido o inactivo en un punto final JSON (GET o POST).
400VALIDATION_ERRORaccommodation_id no se ha encontrado, está fuera de rango o no es aplicable a esta ruta.
404RESORT_NOT_FOUND/accommodations No se pudo resolver el problema.
404ROUTE_NOT_FOUNDLa combinación de códigos de ubicación no se corresponde con ninguna ruta activa.
422UNSUPPORTED_ROUTEFunnel rechaza esta combinación de destino y tipo (por ejemplo, de estación a estación).
422MANUAL_BOOKING_REQUIREDEsta ruta requiere gestión manual; no se puede reservar por internet.
422NO_BOOKABLE_VEHICLENingún vehículo tenía un precio válido en esta ruta.
429RATE_LIMITEDSe ha superado el límite de solicitudes por IP. Espera un rato y vuelve a intentarlo con un retraso exponencial.
500INTERNAL_ERRORAtrapa todas las demás excepciones no gestionadas.

Límites de velocidad

La API no requiere autenticación y tiene un límite de solicitudes por IP del cliente. Cuando se supera el límite, la API devuelve un código de estado HTTP 429 con la envolvente del error estándar:

{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Please slow down and retry." } }
  • No te precipites con las peticiones. Un proceso normal de principio a fin suele constar de 3 o 4 llamadas: locations/searchtransfer-options → si quieres checkout-link. Los puntos finales de fijación de precios tienen un límite inferior al de los puntos finales de consulta.
  • En un 429, espera un rato y vuelve a intentarlo con un retraso exponencial, en lugar de volver a intentarlo de inmediato.
  • Direcciones IP compartidas: los usuarios que se conectan a través de una dirección IP compartida (por ejemplo, la de la oficina) comparten el mismo límite de tráfico y pueden alcanzarlo antes.
  • ¿Necesitas un límite mayor? Ponte en contacto con nosotros: podemos acordar un límite por clave para integraciones de producción.

Las cifras exactas por minuto no se publican a propósito para poder ajustarlas sin tener que modificar el contrato. Trata 429 como «una ralentización», no como un fallo permanente.


Monedas

Introduce cualquier código de moneda ISO 4217 válido currency_code (POST) o currency (Obtener alias) — p. ej. EUR, GBP, CHF, USD. El valor predeterminado es EUR.

  • Puntos de conexión JSON (GET y POST /transfer-options, POST /checkout-link) — si se devuelve un código de moneda desconocido o inactivo 400 CURRENCY_NOT_SUPPORTED. Los agentes que llamen a estos puntos finales deberían gestionar ese error en lugar de dar por hecho que se utilizará el valor predeterminado de EUR.
  • Enlaces directos en el navegador (/book/quick-search, /book/quick-checkout) — un inválido currency= El valor vuelve automáticamente al euro, así que un parámetro obsoleto nunca impedirá que un usuario llegue al embudo.

Para las respuestas que no sean en euros, el disclaimer campo en /transfer-options Ten en cuenta que el importe total de la compra puede variar ligeramente debido a los tipos de cambio en tiempo real (proporcionados por el BCE, igual que en la página web de reservas).


Códigos promocionales

Siguiente promo_code (POST) o promo (alias GET) en cualquiera de los dos /transfer-options o /checkout-link. El código se valida en el servidor. Si la validación falla o el servicio de promociones no está disponible temporalmente, el código es ignorado en silencio y promo_code_applied devoluciones false — la solicitud en sí misma sigue completándose con éxito.

Cuando se envía un código pero no se aplica, la respuesta incluye promo_code (copia del código enviado) y promo_code_message explicando por qué no se ha aplicado (por ejemplo, porque el código ha caducado o no es válido para la ruta elegida). promo_code_applied queda false. La respuesta en sí misma sigue funcionando: los precios se muestran con la tarifa completa.

Cuando se aplica una promoción en /transfer-options, la respuesta incluye promo_code_discount con un type (p. ej., "percent") y value. Echa un vistazo a la sección «Respuesta» más arriba para ver los dos casos relacionados con los códigos promocionales.


CORS y métodos HTTP

La API se puede llamar desde el navegador sin necesidad de configuración adicional:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Headers: Content-Type, Accept
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • OPTIONS La comprobación previa devuelve un código HTTP 204 sin cuerpo.
  • La validación CSRF está desactivada en todos los puntos finales de la API pública.