TRAVEL & BOOKINGAug 20, 202611 min read

How to Integrate Multiple GDS Providers Into One Booking Engine

Amadeus, Sabre, Travelport and direct supplier feeds all model the same trip differently. Here's the architecture that lets a single booking engine search, price, book and refund across all of them without the whole thing falling over when one provider has a bad day.

If you're building a travel product — flights, hotels, or both — you quickly hit a wall: no single supplier has everything, and none of them agree on how to describe it. One returns fares as XML with segment codes; another gives you JSON with a completely different fare model; a direct hotel feed hands you room rates with its own tax rules. Wiring your app directly to each one is how you end up with a codebase nobody wants to touch.

I've built and run a travel reservation platform that talks to four GDS and supplier integrations end to end. This is the architecture I keep coming back to, and the specific problems that will bite you if you skip a layer.

Start with one rule: your app never speaks GDS

The single most important decision is that nothing above the integration layer knows which provider a result came from. Your search page, your booking flow, your admin panel — they all work with one internal model. Amadeus, Sabre and Travelport live behind an adapter, and the rest of the system never imports their SDKs.

Concretely, you define your own normalised types — a FlightOffer, a HotelOffer, a PriceBreakdown — and every provider adapter is responsible for translating into those types. This is a classic provider abstraction (the adapter pattern), and it's the difference between adding a fifth supplier in a week versus a month.

public interface IFlightProvider
{
    string Name { get; }
    Task<IReadOnlyList<FlightOffer>> SearchAsync(FlightQuery q, CancellationToken ct);
    Task<PricedOffer> PriceAsync(string offerId, CancellationToken ct);
    Task<BookingResult> BookAsync(BookRequest r, CancellationToken ct);
}

Every provider implements the same interface. The engine holds a list of them. When you onboard a new supplier, you write one adapter and register it — you don't touch the search or booking code at all.

Search: fan out, but expect stragglers

A search request goes to every relevant provider in parallel, and you merge the results. The mistake people make is waiting for all of them. GDS response times are wildly uneven — one provider answers in 400ms, another takes 6 seconds, and occasionally one just doesn't respond.

So the rule is: fan out, apply a hard per-provider timeout (say 5–8 seconds), and return whatever came back in time. A slow supplier should degrade one row of results, never freeze the page.

Practical detail: return partial results with a flag. The UI can show "still searching Provider X…" and stream late results in, rather than making the user stare at a spinner because one GDS is having a slow morning.

Then you normalise and de-duplicate. The same flight often comes back from two GDSes at slightly different prices — you decide the rule (cheapest wins, or preferred supplier wins) and collapse duplicates so the customer sees a clean list.

Caching and rate limits are not optional

GDS calls cost money and are rate-limited. If you hit their live APIs on every keystroke, you'll blow through quotas and your bill. Two things save you:

The trap here is caching too aggressively. Fares move. Which brings us to the hardest problem in the whole system.

The price-drift problem (and why booking is two steps)

Between the moment a customer sees a fare and the moment they click "book", the price or availability can change. GDS search results are indicative, not a promise. If you book straight off a cached search price, you'll routinely sell fares that no longer exist — and eat the difference.

The fix is a mandatory re-price / confirm step before payment:

  1. Customer selects an offer.
  2. You call the provider's price or confirm availability endpoint for that exact offer, live.
  3. If the price still matches — proceed to payment.
  4. If it changed — show the new price and make the customer re-confirm before charging them.

Only after that live confirmation do you take payment and issue the booking. This one step prevents the most expensive class of bug in travel software: selling something you can't fulfil at the price you quoted.

Failover: one provider down ≠ platform down

With multiple suppliers you get resilience almost for free — if you design for it. Wrap each provider call in a circuit breaker. If a GDS starts timing out or throwing errors, trip the breaker and stop sending it traffic for a cooldown period. Search simply continues with the remaining providers; the customer never sees an error page, just slightly fewer options.

Log every trip and recovery. When a supplier degrades at 2am, you want the audit trail to show exactly what happened without waking anyone up.

Booking, payment and the refund pipeline

Booking is where money and state meet, so it has to be transactional in spirit even though the GDS itself isn't. The pattern:

Refunds and cancellations are their own workflow. Each supplier has different rules, penalties and time windows, so cancellation policy lives in the adapter, and the refund itself runs as a background job with retries — GDS refund calls fail transiently and need to be re-tried without a human babysitting them. Automating this end to end is what turns a booking tool into a platform that can actually run 24/7.

The admin panel is half the product

Everything above is invisible to your operations team unless you build for them. An internal admin panel that shows every booking, its provider, its payment and refund state, and a full audit log is not a nice-to-have — it's how support resolves a stuck booking at midnight without reading raw GDS logs. Build it alongside the engine, not after.

Pitfalls I'd flag before you start

Get the abstraction layer and the confirm-before-charge step right, and adding suppliers becomes routine. Get them wrong, and every new integration is a rewrite. The architecture isn't complicated — it's just unforgiving about the details.


Building or fixing a booking engine?

I've built a multi-GDS travel reservation platform end to end — search, booking, refunds and admin. If you're integrating suppliers or your current engine is fragile, let's talk.

Start a project →
← Back to all posts