Página inicial / API Pública da Alps2Alps — Documentação para Desenvolvedores

API Pública da Alps2Alps — Documentação para programadores

A API Pública da Alps2Alps é uma API HTTP gratuita e sem chave que permite que agentes de IA e integrações de programadores descubram rotas de transferência nos Alpes, obtenham preços em tempo real a partir do mesmo motor de reservas que alimenta o site, consultem registos de alojamento verificados e gerem links de checkout que levam o utilizador final diretamente para o formulário de reserva com todos os campos pré-preenchidos. Todo o processo funciona apenas com pedidos GET — não é necessário usar POST —, pelo que até os agentes de chat que só conseguem abrir URLs podem impulsionar o funil de reservas.

Não é necessária autenticação. Todos os pontos de acesso têm um limite de solicitações por IP. Todas as respostas são application/json.

URL de base: https://booking.alps2alps.com/api/public/v1/
A especificação completa da OpenAPI 3.1 (v1.4.0) está disponível em https://booking.alps2alps.com/openapi/public-v1.json. Importa-o diretamente para Carteiro, Insónia, ou qualquer estrutura de agentes de IA que aceite um URL OpenAPI (chamadas de funções OpenAI, utilização de ferramentas Anthropic, LangChain, AutoGen e outras).

Resumo para agentes de IA

A Alps2Alps é um serviço privado de transporte nos Alpes (aeroporto/estação ferroviária ↔ estância de esqui). Esta API permite-te levar um utilizador da frase «Quero ir de Genebra a Chamonix no dia 22» até uma página de reserva pronta para pagamento — sem qualquer autenticação e sem deixar pedidos GET, se for isso que o teu ambiente de execução suporta.

Fluxo mínimo de ponta a ponta (funciona apenas com GET):

  1. GET /api/public/v1/locations/search?q=Geneva → converter nomes em 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 → preços em tempo real por veículo. A resposta inclui links já prontos — não é preciso criar URLs manualmente:
    • response.quote_url — link pré-preenchido para o passo 2 (seletor de veículos). Usa isto quando o utilizador ainda não tiver escolhido um veículo.
    • response.outbound.vehicles[i].booking_url — Link da etapa 3 por veículo (Os teus dados, veículo pré-selecionado). Usa isto depois de o utilizador escolher um veículo.

Se puderes enviar um POST, usa POST /api/public/v1/checkout-link quando também precisas de preencher previamente os dados de alojamento, números de voo ou notas de texto livre para o motorista. Isso gera um URL tokenizado estável, válido por 24 horas.

Adicionar qualquer return_* Este parâmetro transforma o pedido numa resposta. Os campos de resposta omitidos refletem automaticamente o valor correspondente da solicitação, pelo que o URL de resposta mais simples é simplesmente …&return_date=…&return_time=….

Descoberta legível por máquina

Tudo o que precisas para a integração está disponível nestes ficheiros de descrição:

  1. Pesquisar locais — liga /locations/search para converter os nomes de recolha e entrega do utilizador em airport-… / resort-… / city-… códigos.
  2. (Opcional) Pesquisar alojamentos — liga /accommodations?resort_id=…&q=… com pelo menos 2 caracteres do nome do hotel. Escolhe a entrada correspondente e confirma o nome exato com o utilizador antes de utilizar o seu id.
  3. Pede um orçamento para a viagem — liga /transfer-options com os códigos de localização, além dos dados relativos a passageiros, bagagem e data. A resposta inclui passengers (confirmando os números de passageiros utilizados), luggage por sentido, e max_passengers / max_luggage por veículo, para que possas indicar aos utilizadores quais os veículos adequados ao seu grupo. Nas viagens de regresso, cada veículo também transporta um total_price para a viagem completa. Preços atuais, tipos de veículo, tempo de viagem e eventuais descontos promocionais. Confirma sempre o que foi devolvido pick_up_date_time / return.pick_up_date_time voltar ao utilizador — esses são os horários que o motorista vai usar.
  4. Envia o utilizador para o checkout — assim que o utilizador escolher um veículo, usa o booking_url campo relativo a esse veículo para os enviar diretamente para o passo 3 (Os teus dados) com tudo preenchido automaticamente. Se precisares de preencher automaticamente também a acomodação, o número do voo ou as notas do motorista, usa POST /checkout-link em vez disso.
  5. O utilizador paga — o link de finalização da compra leva-te diretamente para o passo 3 da reserva. Só precisas de introduzir os teus dados de contacto e concluir o pagamento.

Agentes leves (sem capacidade POST)

Para os agentes de chat que só conseguem recuperar URLs, é possível seguir o mesmo fluxo de ponta a ponta sem nunca ter de enviar um POST:

  1. (Opcional) GET /locations/search?q=… para converter nomes em códigos.
  2. GET /api/public/v1/transfer-options?from=…&to=…&date=…&time=…&adults=… para obter preços em tempo real. A resposta JSON já contém os links — basta usá-los diretamente:
    • response.quote_url — leva o utilizador para o passo 2 (seletor de veículos).
    • response.outbound.vehicles[i].booking_url — leva o utilizador para o passo 3 com esse veículo já pré-selecionado.
    • Se for preciso, ainda podes criar essas URLs manualmente usando os aliases de links diretos (consulta a secção «Links diretos» ).

Pontos finais

Pesquisa locais de recolha e entrega disponíveis: resorts, aeroportos, estações ferroviárias e cidades.

Parâmetros de consulta

ParâmetroObrigatórioNotas
qSimTermo de pesquisa. As cadeias com menos de 2 caracteres devolvem uma matriz vazia.

Resposta

Uma matriz plana de locais correspondentes. Os códigos dos resorts seguem o padrão resort-{id}; seguem-se os códigos dos centros de transporte {type}-{id} (por exemplo, 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" }
]

Erros

  • 400 INVALID_PARAMSq falta completamente o parâmetro.

Exemplo

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

2. GET /api/public/v1/accommodations

Pesquisa de hotéis digitada no catálogo de alojamentos verificados utilizado pela funcionalidade de preenchimento automático da etapa 3 do funil de reservas. Os resultados são limitados a um raio de 10 km em torno do resort indicado. O fluxo pretendido é uma pesquisa digitada — o utilizador indica o nome do hotel, o agente transmite-o como q limitado ao resort e seleciona o que corresponde id para enviar para /checkout-link.

Parâmetros de consulta

ParâmetroObrigatórioPredefiniçãoNotas
resort_idSimID numérico do resort a partir de um resort-{id} código de localização.
qSimSubsequência do nome do alojamento (sem distinção de acentos). Mínimo de 2, máximo de 100 caracteres.
limitNão20Limite máximo de 50.

Resposta

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

total é a contagem antes limit é aplicado, para que quem chama a função saiba quando os resultados foram truncados.

Importante: Apenas id os valores devolvidos por este ponto de extremidade podem ser passados para /checkout-link como accommodation_id. Não são aceites nomes de hotéis digitados livremente, garantindo que cada encomenda receba um par nome-morada verificado.

Erros

  • 400 INVALID_PARAMSresort_id falta ou não é um número inteiro, ou q falta ou tem menos de 2 caracteres.
  • 404 RESORT_NOT_FOUND — O ID do resort é desconhecido, está inativo ou não tem coordenadas.

Exemplo

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

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

Retorna preços em tempo real para todos os tipos de veículos disponíveis para reserva na rota solicitada, na moeda solicitada e com a configuração de passageiros e bagagem solicitada. Não é guardada nenhuma informação — este é um ponto de extremidade apenas para cotações. Existem dois tipos de pedidos que partilham o mesmo formato de resposta:

  • PUBLICAÇÃO — corpo JSON canónico utilizando book\forms\Transfer nomes de campos. Recomendado para clientes programáticos com controlo total sobre os cabeçalhos e o corpo da mensagem.
  • OBTER — string de consulta de alias amigável (from, to, date, time, …). Para agentes de IA e ferramentas de chat que criam URLs manualmente. Consulta o Links diretos secção com a tabela completa de aliases.

Importante — hora vs. hora de recolha: Por predefinição, time e return_time são interpretados como voo vezes (is_flight e return_is_flight por predefinição 1). O sistema calcula o valor real recolha tempo a partir da hora do voo — no caso de um voo de regresso, a recolha no resort será antes do que o tempo de voo indicado.

Se o utilizador indicar um recolha uma hora em vez de um horário de voo (por exemplo, «vem buscar-nos às 14h30», «sai do resort às 18h00»), define is_flight=0 e/ou return_is_flight=0. Caso contrário, a hora de recolha indicada estará errada.

Confirma sempre o que foi devolvido pick_up_date_time / return.pick_up_date_time de volta para o utilizador — esses são os horários que o motorista vai usar.

Exemplo: Um pedido com return_time=18:00 e o padrão return_is_flight=1 (do resort → para o aeroporto) regressa "return.pick_up_date_time": "2026-07-26 14:20:00" — o sistema calculou a partir de um voo às 18h. Para conseguir um voo às 18h recolha, enviar &return_is_flight=0.

Corpo da solicitação (POST)

Aceita application/json ou application/x-www-form-urlencoded.

CampoTipoObrigatórioNotas
route_from_codecadeia de caracteresSimpor exemplo airport-1
route_to_codecadeia de caracteresSimpor exemplo resort-11
outbound_datecadeia de caracteresSimYYYY-MM-DD
outbound_time_hoursintSim0–23
outbound_time_minutesintSim0–59
outbound_selected_time_is_flightint (0/1)Não (valor predefinido: 1)1 = a hora é a hora de chegada do voo; o horário de recolha foi calculado. 0 = a hora é a hora exata da recolha.
is_returnint (0/1)Não (padrão 0)Quando 1, todos return_* os campos são obrigatórios
adult_countintSim≥ 1
children_countintNão
infant_countintNão
children_age_seat_countintNãoNúmero de crianças em idade de usar cadeira de segurança
children_age_booster_countintNãoNúmero de crianças em idade de usar cadeira elevatória
luggage_countintNão
skibag_countintNão
has_ski_equipmentint (0/1)Não
currency_codecadeia de caracteresNão (padrão: EUR)ISO 4217. Códigos desconhecidos/inativos 400 CURRENCY_NOT_SUPPORTED.
promo_codecadeia de caracteresNãoSe for inválido, é simplesmente ignorado

Para viagens de regresso, preenche os campos da viagem de ida com um return_ prefixo: return_route_to_code, return_date, return_time_hours, return_time_minutes, return_selected_time_is_flight (padrão 1 — ver nota sobre a hora acima), 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.

String de consulta GET — parâmetros adicionais

Todos os aliases de saída e de retorno estão documentados na secção «Deep links ». Os seguintes parâmetros adicionais só se aplicam a pedidos GET e não fazem parte do corpo do pedido POST:

ParâmetroTipoObrigatórioDescrição
child_agescadeia de caracteresNãoIdades das crianças do grupo separadas por vírgulas, por exemplo: 8,12. Apenas para informação — não é utilizado para definir preços nem para a seleção de veículos. O valor é devolvido em passengers.child_ages e guardado no ficheiro gerado quote_url e booking_url.
return_child_agescadeia de caracteresNãoO mesmo que child_ages para a viagem de volta. Guardado apenas nos URLs gerados.

O sistema de reservas seleciona os veículos com base em adults, children, e child_seats/boosters o número de crianças — e não a idade de cada uma delas. O child_ages existe um parâmetro para que os assistentes de IA e as integrações possam confirmar ao utilizador que a sua entrada foi recebida. Se houver requisitos específicos relativos aos assentos (cadeira de criança vs. assento elevatório), usa o child_seats e boosters parâmetros.

Ver exemplos

Ida, 2 adultos, 2 malas:

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"

Viagem de ida e volta, 2 adultos + 1 criança + 3 malas (cenário realista de chat com 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"

Resposta

Exemplo de resposta GET (todos os campos preenchidos, viagem só 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 uma viagem de ida e volta, cada veículo em ambos os outbound e return os blocos também têm um 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 apenas para leitura (null (ao usar POST):

  • quote_url — link pré-configurado para o passo 2, com todos os parâmetros de pesquisa já preenchidos. Usa isto quando o utilizador ainda não tiver escolhido um veículo.
  • vehicles[].booking_url — um link pronto para a etapa 3 do checkout para cada veículo, com esse veículo já pré-selecionado. Depois de o utilizador escolher um veículo, envia-lhe diretamente este URL.

Nota sobre a codificação de URLs: O quote_url e booking_url os valores na resposta JSON usam um literal & caractere para separar os parâmetros da consulta (por exemplo, …children=2&currency=EUR), o que está correto para cadeias de URL dentro de JSON. Algumas ferramentas — incluindo certos painéis das DevTools dos navegadores e interfaces de chat com IA — podem apresentar visualmente &currency como ¤cy porque &curren é uma entidade HTML (o símbolo ¤). Trata-se de um artefacto de renderização que aparece apenas na visualização. O URL real devolvido pela API está correto. Copia o valor bruto da resposta JSON, e não de uma visualização HTML renderizada.

Campos presentes tanto no GET como no POST:

  • route.from_code / route.to_code — os códigos de localização que constavam no pedido.
  • passengers — a configuração completa do passageiro após a aplicação das predefinições. Inclui child_ages (matriz de inteiros, ou null (se não for fornecido ou no POST).
  • outbound.luggage / return.luggage — bagagem considerada no cálculo do preço de cada trecho (normal_suitcases, ski_equipment). Confirma qual foi o motor utilizado.
  • vehicles[].max_passengers — o número máximo de passageiros que este veículo pode transportar. Todos os veículos devolvidos já passaram pelo filtro de capacidade, pelo que estão confirmados como adequados para o grupo.
  • vehicles[].max_luggage — o número máximo de malas que este veículo pode transportar.
  • vehicles[].total_priceapenas viagens de ida e volta. O preço total para este tipo de veículo em ambos os trajetos, arredondado para duas casas decimais. null em viagens só de ida. Não tentes somar os preços das etapas manualmente — usa total_price ao apresentar o custo total da viagem.

Campos de resposta do código promocional:

Quando foi aplicada uma promoção válida:

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

Quando um código promocional foi introduzido, mas não é válido para este trajeto, data ou grupo:

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

Erros

  • 400 INVALID_PARAMS — corpo vazio, falha na validação ou data inválida.
  • 400 CURRENCY_NOT_SUPPORTED — moeda que não consta da lista de moedas ativas (GET e POST).
  • 404 ROUTE_NOT_FOUND — a combinação de códigos de localização não corresponde a nenhuma rota ativa.
  • 422 UNSUPPORTED_ROUTE — de estação a estação, de resort a resort ou outras combinações rejeitadas pelo funil.
  • 422 MANUAL_BOOKING_REQUIRED — O percurso requer intervenção manual.
  • 429 RATE_LIMITED — Demasiados pedidos a partir deste IP. Espera um pouco e tenta novamente.
  • 500 INTERNAL_ERROR — O motor de preços gerou uma exceção não reconhecida.

Exemplo de POST

Só de 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"

Viagem de ida e volta, 2 adultos + 1 criança + 3 malas (cenário realista de chat com 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"

Aceita o mesmo corpo que /transfer-options além de alguns campos opcionais de preenchimento automático. Devolve um URL de uso único válido por 24 horas. Usa este endpoint quando precisares de preencher previamente um alojamento, um número de voo ou notas do motorista juntamente com a reserva — para tudo o resto, o booking_url campo no /transfer-options A resposta GET é mais simples.

Campos adicionais do corpo

CampoTipoNotas
outbound_vehicle_type_idintOpcional. Por predefinição, é escolhido o veículo de ida mais barato disponível.
return_vehicle_type_idintOpcional. Só é usado quando is_return = 1.
outbound_flight_numbercadeia de caracteresOpcional. Caracteres alfanuméricos + hífen, máximo de 16 caracteres.
return_flight_numbercadeia de caracteresOpcional. Só é usado quando is_return = 1.
accommodation_idintOpcional. Tem de ser um ID devolvido por /accommodations e a menos de 10 km do resort da rota.
additional_infocadeia de caracteresOpcional. Nota do motorista em texto livre. Máximo de 1000 caracteres.
return_additional_infocadeia de caracteresOpcional. Nota do motorista para a viagem de volta. Só é usada quando is_return = 1.

Resposta

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

Erros

Todos os erros de /transfer-options, além de:

  • 400 INVALID_PARAMSaccommodation_id não é um número inteiro positivo.
  • 400 VALIDATION_ERROR — ID do alojamento desconhecido, fora do raio do resort da rota, ou a rota não tem lado do resort.
  • 422 NO_BOOKABLE_VEHICLE — nenhum veículo tinha um preço válido nesta rota.
  • 429 RATE_LIMITED — Demasiados pedidos a partir deste IP. Espera um pouco e tenta novamente.
  • 500 INTERNAL_ERROR — Não foi possível manter o link para o checkout.

Exemplo

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"

Uma família de pontos de extremidade GET sem estado que permite que agentes de IA simples e ferramentas de chat conduzam o fluxo de reservas com URLs simples — sem necessidade de POST, sem registos na base de dados, sem prazo de validade. Na maioria dos casos, o quote_url e booking_url campos devolvidos por GET /transfer-options já estão prontos para ti — a criação manual de URLs abaixo destina-se a casos em que precisas de controlo total sobre os parâmetros ou não podes fazer uma chamada à API previamente.

A relação custo-benefício vs POST /checkout-link: os links diretos não podem incluir um ID de alojamento, um número de voo ou notas de texto livre do motorista (isso requer validação do lado do servidor). Usa POST /checkout-link quando precisares desses extras.

Mapeamento entre alias amigável e campo canónico

Os três pontos finais de deep link traduzem os mesmos aliases de cadeias de consulta compactas. A URL mínima viável é simplesmente from + to + date + time.

Saída / partilhado:

AliasCampo canónicoPredefiniçãoNotas
fromroute_from_codeObrigatório. Por exemplo: airport-1
toroute_to_codeObrigatório. Por exemplo: resort-11
dateoutbound_dateObrigatório. YYYY-MM-DD
timeoutbound_time_hours + _minutesObrigatório. HH:MM. Interpretado como hora de chegada do voo por predefinição (is_flight=1). Definir is_flight=0 para saber a hora exata da recolha.
is_flightoutbound_selected_time_is_flight11 = time A chegada do voo e a recolha são calculadas. 0 = time é a hora exata da recolha.
adultsadult_count2
childrenchildren_count0
child_ages— (Apenas GET)Idades dos filhos separadas por vírgulas, por exemplo: 8,12. Ecoou em passengers.child_ages e mantidos nas URLs geradas. Apenas a título informativo.
infantsinfant_count0
child_seatschildren_age_seat_count0
boosterschildren_age_booster_count0
luggageluggage_count2
ski_bagsskibag_count0
skihas_ski_equipment0
currencycurrency_codeEURRetorno de códigos desconhecidos/inativos 400 CURRENCY_NOT_SUPPORTED nos pontos de acesso JSON. Os links diretos do navegador (quick-search, quick-checkout) voltam automaticamente para o euro, para que um valor desatualizado nunca atrapalhe a experiência do utilizador ao entrar no funil.
promopromo_codeO mesmo comportamento de não emitir aviso em caso de falha que o POST

Jogo de volta — qualquer return_* parâmetro (ou return=1) ativa implicitamente is_return=1. Campos de retorno omitidos espelho automático o valor de saída correspondente, por isso o URL de retorno mais simples é simplesmente …&return_date=…&return_time=…:

AliasCampo canónicoEspelho padrãoNotas
return_toreturn_route_to_codede saída from
return_datereturn_date
return_timereturn_time_hours + _minutesInterpretado por predefinição como a hora de partida do voo (return_is_flight=1). A hora de recolha no resort será mais cedo. Define return_is_flight=0 para a hora exata da recolha no resort.
return_is_flightreturn_selected_time_is_flightde saída is_flight1 = return_time é a hora de partida do voo; a hora de recolha é calculada automaticamente. 0 = return_time é a hora exata da recolha no resort.
return_adultsreturn_adult_countde saída adults
return_childrenreturn_children_countde saída children
return_child_ages— (Apenas GET)de saída child_agesIdades dos filhos separadas por vírgulas para o voo de regresso. Conservadas apenas nos URLs gerados.
return_infantsreturn_infant_countde saída infants
return_child_seatsreturn_children_age_seat_countde saída child_seats
return_boostersreturn_children_age_booster_countde saída boosters
return_luggagereturn_luggage_countde saída luggage
return_ski_bagsreturn_skibag_countde saída ski_bags
return_skireturn_has_ski_equipmentde saída ski

Chaves de consulta desconhecidas (por exemplo, utm_source=…) são ignorados sem aviso prévio.

3a. OBTER /api/public/v1/transfer-options (citação)

Tem o mesmo formato de resposta que a variante POST. Devolve JSON, nunca guarda nada. A resposta inclui quote_url e por veículo booking_url campos prontos a usar.

Só de 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"

Viagem de ida e volta, 2 adultos + 1 criança + 3 malas — porque os campos de resposta refletem automaticamente os de saída, apenas return_date e return_time é preciso adicionar:

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 (passa para o passo 2)

Link direto sem estado que leva o navegador para passo 2 do funil de reservas (seleção do veículo) com os preços já calculados. Equivalente ao quote_url devolvido por GET /transfer-options. Útil quando queres criar o link manualmente, sem uma chamada prévia à API.

Só de ida:

Viagem de ida e volta, 2 adultos + 1 criança + 3 malas:

Os erros (erro de validação, rota não suportada, rota não encontrada, data inválida) redirecionam para /book/?step=1 assim, o utilizador acede diretamente ao formulário de reserva — nunca vê uma página de erro.

3c. GET /book/quick-checkout (chega à etapa 3)

Equivalente sem estado de POST /checkout-link. Leva o navegador para passo 3 (Os teus dados) com o funil preenchido a partir da string de consulta. Equivalente ao booking_url campo em cada veículo no GET /transfer-options resposta. A vehicle O parâmetro seleciona previamente o tipo de veículo.

Veículo de ida, já escolhido:

Viagem de ida e volta, 2 adultos + 1 criança + 3 malas, veículo pré-escolhido:

Outros quick-checkout parâmetros:

AliasNotas
vehicleSaída vehicle_type_id de /transfer-options. Se não indicares nada, o funil escolhe automaticamente o veículo mais barato.
return_vehicleTipo de veículo do trajeto de regresso. O valor predefinido é vehicle para viagens de volta.

accommodation_id, números de voo e notas do motorista são não suportado no fluxo GET. Usa POST /checkout-link para esses.

POST vs GET — qual usar

PrecisasUtilização
Apenas JSON, controlo total, máquina a máquinaPOST /api/public/v1/transfer-options
Citar num URL (chat, e-mail, blog)GET /api/public/v1/transfer-options
Transferência do utilizador manual para o selecionador de veículos (passo 2) — usa o modelo pré-definido quote_url a partir da resposta, ou criar manualmenteGET /book/quick-search
Leva o utilizador para o passo 3 com um veículo já selecionado — usa a opção pré-definida booking_url a partir da resposta, ou criar manualmenteGET /book/quick-checkout
Encaminha o utilizador para o passo 3 com informações sobre alojamento / notas do motorista / números de voo / link com validade de 24 horasPOST /api/public/v1/checkout-link

Envelope de erros e códigos de erro

Todos os erros partilham o mesmo envelope JSON:

{ "error": { "code": "UNSUPPORTED_ROUTE", "message": "The routes from station to station is not supported" } }
HTTPCódigoQuando
400INVALID_PARAMSCampos de pedido em falta ou inválidos, datas com formato incorreto ou falhas na validação.
400CURRENCY_NOT_SUPPORTEDCódigo de moeda desconhecido ou inativo num ponto de extremidade JSON (GET ou POST).
400VALIDATION_ERRORaccommodation_id não encontrado, fora do alcance ou não aplicável a este percurso.
404RESORT_NOT_FOUND/accommodations não consegui resolver o problema.
404ROUTE_NOT_FOUNDA combinação de códigos de localização não corresponde a nenhuma rota ativa.
422UNSUPPORTED_ROUTEO Funnel rejeita esta combinação de destino (por exemplo, de estação a estação).
422MANUAL_BOOKING_REQUIREDEste itinerário requer tratamento manual; não pode ser reservado online.
422NO_BOOKABLE_VEHICLENenhum veículo tinha um preço válido para este percurso.
429RATE_LIMITEDLimite de pedidos por IP excedido. Espera um pouco e tenta novamente com um intervalo exponencial.
500INTERNAL_ERRORBloco de captura para todas as outras exceções não tratadas.

Limites de taxa

A API não requer autenticação e tem um limite de chamadas por IP do cliente. Quando o limite é excedido, a API devolve um HTTP 429 com o intervalo de erro padrão:

{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Please slow down and retry." } }
  • Não te precipites nas tuas solicitações. Um fluxo normal de ponta a ponta envolve 3 a 4 chamadas: locations/searchtransfer-options → se quiseres checkout-link. Os pontos de extremidade de preços têm um limite inferior ao dos pontos de extremidade de pesquisa.
  • Num 429, espera um pouco e tenta novamente com um intervalo exponencial, em vez de tentares de novo imediatamente.
  • IPs partilhados — os utilizadores que estão ligados a um IP partilhado ou de escritório partilham o mesmo limite e podem atingi-lo mais cedo.
  • Precisas de um limite maior? Entra em contacto connosco — podemos definir um limite por chave para integrações de produção.

Os valores exatos por minuto não são publicados de propósito, para que possam ser ajustados sem alterar o contrato. Trata 429 como «uma desaceleração», não uma falha permanente.


Moedas

Introduz qualquer código de moeda ISO 4217 ativo currency_code (POST) ou currency (Obter alias) — por exemplo, EUR, GBP, CHF, USD. O valor predefinido é EUR.

  • Pontos de acesso JSON (GET e POST /transfer-options, POST /checkout-link) — se for devolvido um código de moeda desconhecido ou inativo 400 CURRENCY_NOT_SUPPORTED. Os agentes que acedem a estes pontos finais devem tratar esse erro, em vez de assumirem que se trata de um fallback do EUR.
  • Links diretos no navegador (/book/quick-search, /book/quick-checkout) — um inválido currency= o valor volta automaticamente para o euro, por isso um parâmetro desatualizado nunca vai impedir um utilizador de entrar no funil.

Para respostas que não sejam em euros, o disclaimer campo em /transfer-options tem em conta que o valor total da compra pode variar ligeiramente devido às taxas de câmbio em tempo real (obtidas junto do BCE, tal como no site de reservas).


Códigos promocionais

Passa promo_code (POST) ou promo (GET alias) em qualquer um dos /transfer-options ou /checkout-link. O código é validado no servidor. Se a validação falhar ou se o serviço promocional estiver temporariamente indisponível, o código é silenciosamente ignorado e promo_code_applied devoluções false — a solicitação em si continua a ser bem-sucedida.

Quando um código é enviado mas não aplicado, a resposta inclui promo_code (cópia do código enviado) e promo_code_message explicando por que não foi aplicado (por exemplo, o código expirou ou não é válido para o trajeto escolhido). promo_code_applied sobras false. A resposta em si continua a ser bem-sucedida — os preços são apresentados na íntegra.

Quando uma promoção é aplicada em /transfer-options, a resposta inclui promo_code_discount com um type (por exemplo, "percent") e value. Consulta a secção «Resposta» acima para veres os dois cenários relativos ao código promocional.


CORS e métodos HTTP

A API pode ser chamada a partir do navegador sem necessidade de configuração adicional:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Headers: Content-Type, Accept
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • OPTIONS O preflight devolve um código HTTP 204 sem corpo.
  • A validação CSRF está desativada em todos os pontos finais da API pública.