> ## Documentation Index
> Fetch the complete documentation index at: https://demo-travel.webbinghub.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Supplier adapters: one contract for every supplier

> Every Omnibeds supplier, real or simulated, implements one adapter contract. See its methods, how each supplier keeps state, data modes, and the rules for adding one.

Each supplier in Omnibeds sits behind one adapter in `lib/suppliers/<supplier>/`. The adapter is the only code that knows the supplier's format, its ids and its quirks. Everything above it works with our own domain types: hotels, offers, prices, guests and bookings.

## The contract

The contract is `SupplierAdapter` in `lib/suppliers/types.ts`.

| Method | What it does |
| - | - |
| `capabilities()` | Protocol, how it keeps state, whether it supports price checks, cancellation and holds, and which destinations it covers |
| `health()` | Whether it can be reached, and how fast |
| `search(query)` | Hotels and rates for a query, plus the raw exchange for the log |
| `checkRate(offer)` | The price the supplier will honour now, and whether it changed |
| `hold(offer)` | Optional. Reserves the room and price for a while without booking |
| `book(request)` | Books with every guest, room by room; returns the supplier's reference and `confirmed` or `pending` |
| `cancel(reference)` | Cancels with the supplier |
| `getBooking(reference)` | The supplier's status for a booking, used by reconciliation |
| `lookupBooking(reference)` | Optional. How the supplier holds the booking now, for the live booking page |
| `amendGuests(...)` | Optional. Sends a traveller change to the supplier |

Every call returns its raw request and response, so the Inspector can show exactly what was sent and received.

## The suppliers

| Supplier | Kind | How it keeps state | Presenter only |
| - | - | - | - |
| Aurora Hotels | Simulated (XML) | Session: log in, then send a session id that expires | No |
| Meridian Beds | Simulated (JSON) | Chained: search token, prebook hash, booking | No |
| Hotelbeds | Real, test environment | Offer token: each offer carries a token that expires | Yes |
| LiteAPI | Real | Chained | No |
| RateHawk | Real, test environment | Chained | Yes |

Each real supplier has its own page with its rules, its flow next to ours, and how its data maps to ours:

> [card] [Hotelbeds](https://demo-travel.webbinghub.io/docs/suppliers/hotelbeds.md)
>
> Signature auth, rateKeys, the daily stop.

> [card] [LiteAPI](https://demo-travel.webbinghub.io/docs/suppliers/liteapi.md)
>
> Prebook before booking, pace, outdated offers.

> [card] [RateHawk](https://demo-travel.webbinghub.io/docs/suppliers/ratehawk.md)
>
> Search limits, name rules, the five-step booking.

The simulators let the whole product run with no real supplier at all; Aurora also supports simulated holds. Every simulated supplier carries a "Simulated" badge in the screens.

### Sessions

For a supplier that needs a login, the session manager (`lib/state/session-manager.ts`) logs in on first use and reuses the stored session. Concurrent callers share one login, the session is renewed shortly before it expires, and when the supplier says the session expired it logs in again once and retries the call once. Sessions are stored in Postgres, so every server instance reuses the same one.

### Offer references that expire

An offer keeps its supplier reference and when it expires. When the supplier doesn't publish an expiry, Omnibeds uses its own estimate and labels it "our estimate" in the screen. An expired reference is refreshed by searching again for the same product. See [Booking](https://demo-travel.webbinghub.io/docs/pipelines/booking.md).

## Data modes

| Mode | Meaning |
| - | - |
| `replay` | Answers from synthetic fixtures where a supplier has them; no live call |
| `live` | Calls the supplier for real; counts against its quota |
| `record` | Calls the supplier and records the answer |

Live and record need presenter mode. Omnibeds stops Hotelbeds at 40 live calls a day, below what the test key allows, and every live call to a real supplier is counted on the API usage page.

## Rules for an adapter

**1. Build it from the supplier's public documentation**

Keep the adapter thin: translate requests and answers, nothing more. Orchestration, mapping, pricing and logging stay in our own code.

**2. Respect every documented rule before calling**

Validate each field by the supplier's documentation (for example name characters, required adults per room) and show the rule in the screen, so a request the supplier would refuse is never sent.

**3. Say which errors are worth retrying**

Mark 4xx and malformed answers as not retryable. The orchestrator then skips the retry, which would only spend quota.

**4. Return the raw exchange**

Every call returns what was sent and received, for the log.

**5. Test it live, and clean up**

Add a test to the live suite. Any booking it makes is cancelled at the end, even when the test fails.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.