Transfers APIs

Hotelbeds Transfers API Integration Guide for Travel Platforms

Jul 08, 2026Hardeep SinghTransfers APIs

Hotelbeds Transfers API Integration Guide for Travel Platforms

Hotelbeds Transfers API Integration Guide for Travel Platforms

Ground transportation is the glue of a trip: airport pickups, hotel-to-port runs, point-to-point city rides. Hotelbeds (HBX Group) exposes all of this through the APITUDE Transfer API 1.0. This guide walks through what it takes to integrate it cleanly — the real endpoints, the authentication model, and the architecture decisions that keep a codebase sane across B2C, B2B, and itinerary-driven flows.

If you've already integrated Hotelbeds Hotels or Activities, the good news is that Hotelbeds Transfers API integration follows the same authentication pattern and a similarly lean request lifecycle — just applied to a different inventory type.

The API in a Nutshell

The Transfer Booking API is smaller in scope than the Hotel API. It breaks down into three phases:

  1. Availability — real-time search for bookable transfer services.
  2. Confirmation — book one or more rateKeys under a single reference.
  3. Post-booking — booking detail, booking list, and cancellation.

Base hosts:

Environment Host
Test https://api.test.hotelbeds.com
Live https://api.hotelbeds.com

Location code types used in requests:

Type Meaning
IATA Airport code (recommended for airports)
ATLAS Hotelbeds custom hotel codes
GPS Latitude/longitude coordinates
PORT Custom port codes
STATION Custom station codes

Authentication

Every call needs two headers, with a SHA-256 signature regenerated per request:

Api-key:     <your api key>
X-Signature: SHA256(apiKey + secret + unixTimestampSeconds)

In a multi-product setup, this signing logic should live as one shared utility used across every Hotelbeds product — Activities, Transfers, and Hotels alike — rather than being reimplemented per integration:

const timestamp = Math.round(Date.now() / 1000);
const signature = sha256(apiKey + secret + timestamp);
// headers: { 'Api-key', 'X-Signature', Accept, 'Content-Type' }

Step 1: Availability

Availability is a GET request with all parameters encoded directly in the path — no request body involved:

GET /transfer-api/1.0/availability/{language}
    /from/{fromType}/{fromCode}
    /to/{toType}/{toCode}
    /{outbound}/{inbound}/{adults}/{children}/{infants}

Key rules:

  • outbound / inbound are ISO datetimes (inbound applies only to round trips).
  • Passenger buckets are strict: adults 13–99, children 3–12, infants 0–2.
  • For GPS-based locations, fromCode is formatted as "lat,lng".

A point-to-point city ride request looks like this:

GET /transfer-api/1.0/availability/en
    /from/GPS/41.387400,2.168600
    /to/GPS/41.403600,2.174400
    /2026-07-15T10:00:00/1/0/0

The response returns a services[] array. The field that matters most is rateKey — the opaque handle used to confirm the booking later. Each service also carries the vehicle type, category, transfer type (private vs. shared), cancellation policy, and sometimes mustCheckPickupTime, a flag worth surfacing directly in the UI.

Practical filtering tip: only retain services that have both a non-empty rateKey and a positive price.totalAmount. Anything else should be dropped during parsing.

Step 2: Confirmation

Booking is a POST carrying the rateKey(s) plus traveler (holder) details:

POST /transfer-api/1.0/bookings
{
  "language": "en",
  "holder": { "name": "John", "surname": "Doe" },
  "transfers": [
    { "rateKey": "20260715|...|SIMPLE|...", "pickupInformation": { } }
  ]
}

Multiple rateKeys can be sent in a single request — useful for round trips or splitting a large group across two vehicles. They all share one booking reference. On success, the response returns the HB reference (e.g. 1-4135098) with status CONFIRMED.

Step 3: Post-booking

  • Detail: GET /transfer-api/1.0/bookings/{reference}
  • Cancel: DELETE /transfer-api/1.0/bookings/{language}/reference/{reference}
  • Simulate cancel (preview penalties): append ?simulation=true
  • Partial cancel (single leg): append /id/{serviceId}
DELETE /transfer-api/1.0/bookings/en/reference/1-4135098
sequenceDiagram participant Client participant Backend participant Hotelbeds Client->>Backend: Search transfer (from, to, dates, pax) Backend->>Hotelbeds: GET /availability/{lang}/from/.../to/... Hotelbeds-->>Backend: services[] with rateKey, price, policies Backend-->>Client: Filtered results (opaque tokens only) Client->>Backend: Confirm booking (token, holder details) Backend->>Hotelbeds: POST /bookings (rateKey + holder) Hotelbeds-->>Backend: HB reference, status CONFIRMED Backend-->>Client: Booking confirmation + voucher Client->>Backend: Cancel booking (reference) Backend->>Hotelbeds: DELETE /bookings/{lang}/reference/{ref} Hotelbeds-->>Backend: Cancellation confirmed Backend-->>Client: Cancellation confirmation

How to Structure the Integration

The API surface itself is simple; the real discipline is architectural. When a platform supports multiple Hotelbeds products (Activities, Transfers, Hotels), all three should share one integration pattern so no team reinvents supplier plumbing from scratch.

flowchart TD A[User / B2B Client] --> B[Controller: B2C or B2B routes] B --> C[Transfer Blender<br/>search suppliers in parallel, dedupe, mint tokens] C --> D[Transfer Supplier Factory<br/>route by channel or rate token] D --> E[HotelbedsTransferService] D --> F[Offline CRS Partner Service] E --> G[Hotelbeds Transfer API 1.0]

Golden rule: controllers should never call the Hotelbeds adapter directly — everything flows through the blender, so live Hotelbeds inventory and offline partner fleets merge into a single unified result set.

Tokens Instead of Raw rateKeys

A raw Hotelbeds rateKey should never reach the browser. Instead, each step in the flow mints a short-lived, opaque token, and the backend resolves it to the real supplier payload internally:

flowchart LR A[Search: tsrch_*] --> B[Rates: trt_*<br/>externalRateKey = Hotelbeds rateKey] B --> C[Hold: thld_*<br/>15-min hold, required before prebook] C --> D[Prebook: trf_* + trpb_*<br/>local draft + prebook token] D --> E[Confirm: order row in transfer_crs_orders]

Routing logic stays trivial this way: if a rate token carries an externalRateKey, the factory routes hold/prebook/confirm/cancel to Hotelbeds; otherwise, it stays with the offline CRS engine.

The Payment-Timing Gotcha

This is the detail that trips up most integrations. In an Activities integration, it's common to preconfirm before payment — but transfers work differently: there is no preconfirm step. The Hotelbeds booking should be created only after payment succeeds:

flowchart LR A[Search] --> B[Details] --> C[Rates] --> D[Hold - 15 min] D --> E[Prebook draft<br/>no HB call yet] E --> F[Checkout: user pays] F --> G[sync-payment:<br/>verify payment, THEN POST /bookings] G --> H[Confirmation + Voucher]

The actual POST /bookings call fires at the sync-payment step, not at prebook. If the hold window expires mid-payment, the standard OTA behavior is to have the user re-select a service.

Vouchers

Prefer whatever Hotelbeds returns natively: a supplier voucher link or PDF from the confirm response. Only fall back to a generated voucher sheet when the supplier response includes nothing usable. For round trips, render one voucher per leg.

Certification Notes

Full Hotelbeds transfer certification exercises terminal routes (ATLAS hotels, IATA airports, PORT, STATION) as well as round-trip bundles — for example, Hotel Sistina (ATLAS) → Rome Ciampino (IATA). Many consumer-facing B2C launches ship GPS point-to-point only via a Places picker first, leaving terminal/airport route types for the B2B API and certification backlog. Hotelbeds certification contact: integrations.btb@hbxgroup.com.

A few things certification reviewers check that are worth building in from day one:

  • Show the cancellation policy on both details and confirmation screens.
  • Surface mustCheckPickupTime as a visible banner when returned.
  • Display total price and currency exactly as returned — don't invent tax lines Hotelbeds didn't send.
  • Log every supplier request/response for audit purposes.

Environment Setup

HOTELBEDS_TRANSFERS_API_KEY=
HOTELBEDS_TRANSFERS_API_SECRET=
HOTELBEDS_TRANSFERS_BASE_URL=https://api.test.hotelbeds.com
HOTELBEDS_TRANSFERS_TIMEOUT_MS=30000

Point-to-point search also requires a GOOGLE_MAPS_API_KEY for the Places pickers.

Key Takeaways

  • The Transfer API is genuinely a three-call flow: availability → bookings → cancel.
  • Availability is a path-based GET; booking is a POST with rateKeys; cancel is a DELETE by reference (with simulate/partial variants).
  • Wrap the integration in a blender + supplier factory so live and offline inventory share one path.
  • Never expose raw rateKeys to the client — use opaque, expiring tokens instead.
  • Remember the timing difference: transfers confirm only after payment, with no preconfirm step.

Get those five points right, and the rest of a Hotelbeds Transfers API integration is just careful parsing.


Need Help With Your Travel API Integration?

Teenva AI & Digital Ventures builds production-grade travel technology — from Hotelbeds Transfers API integration to full OTA booking engines. Reach out at sales@teenvaai.com or call +91 9572020107 to discuss your integration.

Similar Articles