Home / Alps2Alps Public API — Developer Documentation

Alps2Alps Public API — Developer Documentation

The Alps2Alps Public API is a free, key-less HTTP API that lets AI agents and developer integrations discover Alpine transfer routes, retrieve real-time prices from the same booking engine that powers the website, look up verified accommodation entries, and generate one-shot checkout links that land the end user directly on the booking form with everything pre-filled.

No authentication is required. All endpoints are rate-limited per IP. All responses are application/json.

Base URL: https://booking.alps2alps.com/api/public/v1/
The full OpenAPI 3.1 spec is available at https://booking.alps2alps.com/openapi/public-v1.json. Import it directly into Postman, Insomnia, or any AI agent framework that accepts an OpenAPI URL (OpenAI function calling, Anthropic tool use, LangChain, AutoGen, and others).
  1. Search locations — call /locations/search to resolve the user’s pickup and drop-off names into airport-… / resort-… / city-… codes.
  2. (Optional) Search accommodations — call /accommodations?resort_id=… once the resort side is known so the user can confirm a specific hotel. Always confirm the chosen entry with the user before sending its id.
  3. Quote the trip — call /transfer-options with the location codes plus passenger, luggage, and date inputs. Present prices, vehicle types, travel time, and any promo discount to the user.
  4. Generate a checkout link — once the user confirms a vehicle, call /checkout-link with the same body plus any optional extras (vehicle type id, flight number, accommodation id, driver notes).
  5. Hand the URL to the user — the returned checkout_url is valid for 24 hours. Opening it lands the user on booking step 3 (Your Details) with all fields pre-filled. They only need to enter contact details and complete payment.

Endpoints

Search for supported pickup and drop-off locations: resorts, airports, train stations, and cities.

Query parameters

ParameterRequiredNotes
qYesSearch term. Strings shorter than 2 characters return an empty array.

Response

A flat array of matching locations. Resort codes follow the pattern resort-{id}; transport hub codes follow {type}-{id} (e.g. 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" }
]

Errors

  • 400 INVALID_PARAMSq parameter missing entirely.

Example

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

2. GET /api/public/v1/accommodations

Read-only access to the verified accommodation catalogue used by the booking funnel’s hotel autocomplete. Results are scoped to a 10 km radius around the supplied resort.

Query parameters

ParameterRequiredDéfautNotes
resort_idYesNumeric resort id from a resort-{id} location code.
qNon""Substring filter on name (accent-insensitive). Max 100 chars.
limitNon20Hard-capped at 50.

Response

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

total is the count before limit is applied, so the caller can tell when results were truncated.

Important: Only id values returned by this endpoint may be passed into /checkout-link as accommodation_id. Free-typed hotel names are not accepted, ensuring every order receives a verified name and address pair.

Errors

  • 400 INVALID_PARAMSresort_id missing or not an integer.
  • 404 RESORT_NOT_FOUND — resort id is unknown, inactive, or has no coordinates.

Example

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

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

Returns real-time prices for every bookable vehicle type on the requested route, in the requested currency, with the requested passenger and luggage configuration. Nothing is persisted — this is a quote-only endpoint.

Request body

Accepts application/json or application/x-www-form-urlencoded.

ChampTypeRequiredNotes
route_from_codestringYese.g. airport-1
route_to_codestringYese.g. resort-11
outbound_datestringYesYYYY-MM-DD
outbound_time_hoursintYes0–23
outbound_time_minutesintYes0–59
outbound_selected_time_is_flightint (0/1)Non1 = the time given is a flight arrival time
is_returnint (0/1)No (default 0)When 1, all return_* fields are required
adult_countintYes≥ 1
children_countintNon
infant_countintNon
children_age_seat_countintNonNumber of child-seat-aged children
children_age_booster_countintNonNumber of booster-seat-aged children
luggage_countintNon
skibag_countintNon
has_ski_equipmentint (0/1)Non
currency_codestringNo (default EUR)ISO 4217 currency code
promo_codestringNonSilently ignored if invalid

For return trips, mirror the outbound fields with a return_ prefix: return_route_to_code, return_date, return_time_hours, return_time_minutes, return_selected_time_is_flight, 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.

Response

{
  "disclaimer": "Prices shown are real-time and calculated using the same engine as the booking website.",
  "route": {
    "from": "Geneva Airport",
    "to": "Chamonix",
    "distance_km": 99,
    "duration_minutes": 100,
    "travel_time": "01:40:00"
  },
  "currency": "EUR",
  "outbound": {
    "pick_up_date_time": "2026-07-22 14:30:00",
    "vehicles": [
      { "vehicle_type_id": 2,  "name": "Standard/economy", "price": 175,    "offer_code": "requested" },
      { "vehicle_type_id": 10, "name": "Standard minivan",  "price": 247,    "offer_code": "requested" },
      { "vehicle_type_id": 4,  "name": "VIP",               "price": 418.50, "offer_code": "requested" }
    ]
  },
  "return": null,
  "promo_code_applied": false
}

When a valid promo is applied, the response also includes:

"promo_code_discount": { "type": "percent", "value": 5 }

Errors

  • 400 INVALID_PARAMS — body empty, validation failure, or malformed date.
  • 400 CURRENCY_NOT_SUPPORTED — currency not in the active currency list.
  • 404 ROUTE_NOT_FOUND — location code combination does not map to an active route.
  • 422 UNSUPPORTED_ROUTE — station-to-station, resort-to-resort, or other funnel-rejected combinations.
  • 422 MANUAL_BOOKING_REQUIRED — route requires manual handling.
  • 500 INTERNAL_ERROR — pricing engine threw an unrecognised exception.

Example

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"

Accepts the same body as /transfer-options plus a few optional pre-fill fields. Returns a one-shot URL valid for 24 heures. Opening the URL lands the user on booking step 3 (Your Details) with all fields pre-filled — they only need to enter contact details and pay.

Additional body fields

ChampTypeNotes
outbound_vehicle_type_idintOptional. Defaults to the cheapest available outbound vehicle.
return_vehicle_type_idintOptional. Only used when is_return = 1.
outbound_flight_numberstringOptional. Alphanumeric + hyphen, max 16 chars.
return_flight_numberstringOptional. Only used when is_return = 1.
accommodation_idintOptional. Must be an id returned by /accommodations and within 10 km of the route’s resort.
additional_infostringOptional. Free-text driver note. Max 1000 chars.
return_additional_infostringOptional. Driver note for the return leg. Only used when is_return = 1.

Response

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

Errors

All errors from /transfer-options, plus:

  • 400 INVALID_PARAMSaccommodation_id is not a positive integer.
  • 400 VALIDATION_ERROR — accommodation id unknown, outside the route’s resort radius, or route has no resort side.
  • 422 NO_BOOKABLE_VEHICLE — no vehicle had a usable price on this route.
  • 500 INTERNAL_ERROR — could not persist the checkout link.

Example

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"

Error envelope & error codes

All errors share the same JSON envelope:

{ "error": { "code": "UNSUPPORTED_ROUTE", "message": "The routes from station to station is not supported" } }
HTTPCodeWhen
400INVALID_PARAMSMissing or invalid request fields, malformed dates, or validation failures.
400CURRENCY_NOT_SUPPORTEDCurrency not in the active currency list.
400VALIDATION_ERRORaccommodation_id not found, not in range, or not applicable to this route.
404RESORT_NOT_FOUND/accommodations could not resolve the resort.
404ROUTE_NOT_FOUNDLocation code combination does not map to an active route.
422UNSUPPORTED_ROUTEFunnel rejects this destination-type combination (e.g. station-to-station).
422MANUAL_BOOKING_REQUIREDRoute requires manual handling; not bookable online.
422NO_BOOKABLE_VEHICLENo vehicle had a usable price on this route.
500INTERNAL_ERRORCatch-all for all other unhandled exceptions.

Currencies

Pass any active ISO 4217 currency code in currency_code (e.g. EUR, GBP, CHF, USD). The default is EUR.

For non-EUR responses the disclaimer field in /transfer-options is extended to note that the exact checkout total may shift slightly due to live FX rates (sourced from the ECB, same as the booking website).


Promo codes

Pass promo_code in the request body on either /transfer-options or /checkout-link. The code is validated server-side. If validation fails or the promo service is temporarily unreachable, the code is silently ignored et promo_code_applied returns false — the request itself still succeeds. The caller can retry or surface the unapplied state to the user.

When a promo is applied on /transfer-options, the response includes promo_code_discount with a type (e.g. "percent") and value.


CORS & HTTP methods

The API is browser-callable with no additional configuration:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Headers: Content-Type, Accept
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • OPTIONS preflight returns HTTP 204 with no body.
  • CSRF validation is disabled on all public API endpoints.