Amadeus
Nexa integrates with Amadeus Self-Service APIs for hotel inventory search and booking. Amadeus is the largest GDS and one of the two primary inventory sources for the platform (the other is Hotelbeds).
Amadeus appears in two independent integrations in Nexa: as the hotel vendor described on this page, and — for airlines that run on Amadeus Altéa — as the PSS that supplies disruption events, manifests, and re-accommodation decisions (Airline systems). The two roles use different APIs, different credentials, and different adapters. A tenant may use one, both, or neither.
What we use it for
| Capability | Amadeus API | Nexa adapter |
|---|---|---|
| Hotel availability search | Hotel Search API | AmadeusHotelProviderAdapter (IHotelProvider) |
| Hotel booking | Hotel Orders API | AmadeusBookingProviderAdapter (IBookingProvider) |
| Booking cancellation | Hotel Orders API (DELETE) | AmadeusBookingProviderAdapter.cancel |
How it fits in the platform
Amadeus is one leg of the scatter-gather search — the booking module fans out to every configured inventory source in parallel and time-boxes the aggregation at 2 seconds. Whichever sources have responded by the cutoff are merged, deduplicated, and ranked. Slow Amadeus responses don't slow operators; they just don't appear in the result set for that search.
Authentication
Amadeus uses OAuth2 client credentials with token rotation:
- Token endpoint:
https://api.amadeus.com/v1/security/oauth2/token - Token TTL: 30 minutes (Amadeus-published).
- Nexa caches the token until
exp - 60s. On a 401, force-refresh once before propagating.
Credentials are tenant-managed — the airline holds the contract with Amadeus; Nexa stores the API key + secret in the tenant's Secret Manager namespace under nexa/<tenant>/vendor/amadeus/.
Rate limiting
Amadeus publishes per-customer TPS limits that depend on the airline's plan. The platform enforces the limit cluster-wide via the vendor-egress token bucket:
amadeus.search— typically 10 TPSamadeus.booking— typically 5 TPS
The exact values are tenant-configured at onboarding. Burst beyond the configured TPS blocks at the worker level rather than calling and getting 429'd — the bus accumulates depth, the HPA scales worker count up to the bucket ceiling, and Amadeus never sees the burst.
Search behavior
POST /v1/hotels/search from the operator UI fans out to every adapter. The Amadeus adapter:
- Translates the Nexa search request (
airport,check-in,check-out,rooms,tier) to Amadeus Hotel Search parameters. - Calls Amadeus.
- Translates the response into the
NexaInventoryObjectcanonical format — same field names, same units, same amenity vocabulary as every other adapter. - Returns to the booking aggregator.
The mapper handles vendor-specific quirks: Amadeus's amenity codes map to Nexa's normalized WHEELCHAIR_ACCESSIBLE, FREE_BREAKFAST, etc. via amadeus.amenity.mapper.ts. Star ratings, distance-to-airport, and pricing tiers normalize at the same step.
Booking behavior
When the operator submits compensation, the booking workflow dispatches the work to the Amadeus adapter (selected by reading the partner from the offer URN), and:
- Waits for available budget under per-partner traffic shaping.
- Mints a stable Nexa-side reservation URN before calling Amadeus, so the URN survives retries and ambiguous timeouts.
- Calls Amadeus Hotel Orders with the Nexa reservation URN as the
external_reference. - On success, wraps the Amadeus confirmation as
urn:reservation:<amadeus-id>:vendor:amadeus:status:confirmedand returns the canonical voucher payload. - On failure, classifies the error (transient → retry; permanent → route to manual reconciliation).
Idempotency
Amadeus accepts an external_reference field on booking creation. Nexa supplies the Nexa-side reservation URN. Replays of the same IssueBooking command (e.g., after a worker crash) find the existing booking and return the same confirmation; no duplicate billing.
Cancellation
Cancellation goes through IBookingProvider.cancel(vendorConfirmationUrn). The adapter parses the URN, extracts amadeus, and dispatches to the Amadeus DELETE endpoint. The same idempotency model applies — replays return the same status.
Permanent-failure classification
Some Amadeus errors are not retryable:
| Amadeus error | Nexa classification | Action |
|---|---|---|
NON_REFUNDABLE (cancel attempt) | Permanent | Route to manual reconciliation, transition sub-case to COMPENSATION_FAILED, surface to operator. |
BOOKING_PAST_CANCELLATION_DEADLINE | Permanent | Same as above. |
RATE_NOT_AVAILABLE (book attempt) | Permanent (this offer specifically) | Mark the offer stale, return error to allow the operator to pick a different one. |
INVALID_PAYMENT_INFO | Permanent | Surface to operator; payment method needs correction. |
| 5xx, timeouts, network errors | Transient | Retry with backoff. |
| 429 | Transient | Retry with longer backoff (token bucket should prevent this). |
Permanent failures are surfaced to the operator with the original Amadeus error code in X-Vendor-Error-Code so manual reconciliation has the full context.
Mock mode
Every Amadeus adapter has a sibling mock at amadeus.mock.data.ts. In dev environments, the mock returns deterministic results (a fixed catalog of Santiago hotels with predictable prices), enabling integration testing without Amadeus credentials.
The flag is per-tenant: nexa/<tenant>/vendor/amadeus/mode = mock | live. Customer Success flips this once production credentials are validated.
Onboarding checklist
For a new tenant integrating Amadeus:
- Tenant procures Amadeus Self-Service credentials (production tier).
- Credentials loaded into
nexa/<tenant>/vendor/amadeus/Secret Manager namespace. - Tenant-specific TPS configured in
amadeus.search.bucketandamadeus.booking.bucket. - Adapter health check passes against Amadeus production (
GET /v1/security/oauth2/tokensucceeds,POST /v3/shopping/hotel-offersreturns canonical results). - Mock-mode flag flipped to
live. - First end-to-end booking against a sandbox case validated.
Onboarding takes 1–3 business days assuming credentials are in hand.
Compliance & data handling
Amadeus is a data sub-processor under Nexa's tenant DPAs. Per-passenger data sent to Amadeus is the minimum required for booking: lead-passenger name, contact, group size, room requirements. PII handling is governed by the airline's own data-sharing agreement with Amadeus — Nexa is the data processor, the airline is the controller, Amadeus is the sub-processor.
PNR and passport data do not flow through the Nexa Amadeus adapter for booking purposes — that data lives in the airline's PSS, not in the disruption-handling flow.