Chapter 7.1 — GDS Integrations (Amadeus, Sabre, Travelport)
1. Purpose
This chapter defines how travoBooks integrates with the three major Global Distribution Systems — Amadeus, Sabre, and Travelport (Galileo / Worldspan / Apollo) — for air offer search, booking creation, pricing, ticket issuance, refund/void, exchange, and post-issuance servicing. It covers the request/response patterns, credential management, error handling, latency budgets, and the abstraction layer that lets module-level code work against any GDS.
2. Why it matters
The GDS is the largest single source of air bookings industry-wide. A robust integration is the difference between a platform that issues tickets reliably and one that fails customers at the worst moment (the issuance call). This integration must handle: - Versioned schemas (XML for traditional GDS, JSON for NDC paths). - Latency variation (200ms to 30s per call). - Transient supplier outages (queue + retry without double-booking). - Strict idempotency (issuance is irreversible — never re-issue).
3. Architecture
The platform implements a supplier-abstraction layer (SupplierClient interface) with per-GDS adapters:
SupplierClient (interface)
├── AmadeusClient
│ └── handles Amadeus Soap / WSAP envelopes
├── SabreClient
│ └── handles Sabre SOAP and REST endpoints
└── TravelportClient
└── handles uAPI XML
Module code calls SupplierClient.searchOffers(...) without knowing the underlying GDS. Per-supplier credentials and configuration are stored encrypted in supplier_credentials.
4. Amadeus integration
4.1 Authentication
- SOAP envelope with WS-Security header containing
OfficeId,Originator,Password,BinarySecurityToken. - Token obtained via
Security_Authenticateand held in memory for the session. - Re-auth on
SOAP-Fault: AUT.SECURITY_TOKEN_EXPIRED.
4.2 Key endpoints used
| Operation | Endpoint |
|---|---|
| Search offers | Fare_MasterPricerTravelBoardSearch |
| Sell from recommendation | Air_SellFromRecommendation |
| Re-price PNR | Fare_PricePNRWithBookingClass |
| Create TST | Ticket_CreateTSTFromPricing |
| Issue ticket | DocIssuance_IssueTicket |
| Display PNR | PNR_Retrieve |
| Cancel segment | Air_CancelSegment |
| Void ticket | Ticket_VoidDocuments |
| Refund | Ticket_ProcessEDoc (with refund indicator) |
| Reissue | Air_RebookAirSegment + reprice + reissue |
4.3 Parsing
The platform uses a dedicated IttAMASearch class (PHP) for parsing Fare_MasterPricerTravelBoardSearch responses. The parser:
- Groups recommendations by flightIndex and resolves fare-family per recommendation.
- Extracts per-segment fare class, baggage allowance, fare basis code, and ATPCO category data.
- Handles ensureArray normalisation (Amadeus returns single-element arrays without wrapper).
- Constructs segmentUID for downstream segment-level operations.
4.4 Office hierarchy
Amadeus uses OfficeId for multi-branch agents. The platform maps partner.amadeus_office_id per branch; selected at request time.
5. Sabre integration
5.1 Authentication
- REST-based OAuth2 token from
/v3/auth/token; SOAP token also supported. - PCC (Pseudo-City Code) sent in every request header.
5.2 Key endpoints
| Operation | Endpoint |
|---|---|
| Bargain Finder Max search | /v1/offers/shop |
| Air price | /v1/offers/pricing |
| Create reservation | /v2/passenger/records (POST) |
| Issue ticket | /v2.0.0/passenger/records/{id}/issuance |
| Cancel | /v1/trip/orders/{id}/cancel |
| Void | /v1/trip/orders/{id}/voidTicket |
| Refund | /v1/trip/orders/{id}/refundTicket |
| Exchange | /v1/trip/orders/{id}/exchange |
5.3 PCC mapping
Sabre's PCC ≈ Amadeus's OfficeId concept. Per-partner per-branch PCC configured.
6. Travelport integration
uAPI-based; XML wire format; similar surface area. Per-PCC equivalent.
7. Cross-GDS canonical model
The platform stores GDS-agnostic data in canonical tables:
| Canonical | Maps to |
|---|---|
bookings.supplier_record_locator |
PNR (Amadeus), PNR (Sabre), Booking File (Travelport) |
booking_tsts.supplier_pricing_record_id |
TST (Amadeus), Price Quote (Sabre), Filed Fare (Travelport) |
booking_tickets.ticket_number |
Standard IATA 13-digit |
booking_segments.fare_basis_code |
ATPCO universal |
booking_segments.booking_class |
RBD universal |
Supplier-specific raw payloads are stored in supplier_request_log for replay and debugging — never used as application data.
8. Issuance pattern (critical)
Ticket issuance is the most sensitive call in the platform. Strict pattern:
The key invariant: the GDS call is outside the DB transaction. If the DB commit fails after a successful GDS issuance, the platform has a real ticket without an internal record — a reconciliation hazard. Mitigation:
- Pre-commit "ready to commit" record in supplier_request_log with the ticket number.
- Background reconciler matches supplier_request_log ticket numbers to booking_tickets.
- Orphan tickets (in log, not in tickets) raise immediate alerts.
This pattern is documented in Chapter 4.2 Ticketing & PNR.
9. Schedule changes & post-issuance servicing
GDS pushes schedule-change notifications via:
- Amadeus: Queue_PlaceMessage to monitored queues; polled.
- Sabre: Notifications API; webhook or queue.
- Travelport: TMU subscription.
Platform:
- Polls / receives the change.
- Updates booking_segments.status, segments[i].new_time.
- Creates a booking_alert for ops.
- If automatic re-protect rule matches, attempts re-accommodation.
10. Latency budget
| Operation | Budget | If exceeded |
|---|---|---|
| Search | 8s typical, 15s max | Show partial results |
| Sell | 5s max | Retry once; surface error |
| Re-price | 5s max | Retry once |
| Issue | 30s max (slow path) | Background queue if timeout |
| Cancel | 10s max | Retry; manual fallback if persistent |
11. Error handling
Common GDS errors and treatments:
| Error | Treatment |
|---|---|
Schedule changed since selection |
Re-search; restart booking flow |
Price changed at issuance |
Surface; require explicit re-confirm |
Seat sold out |
Re-search; offer alternates |
Credit not authorised |
Block; require alternate payment |
Office not authorised for this route |
Configuration error; alert |
Session timeout |
Re-auth; retry once |
Format error in request |
Bug; log + alert engineering; do not retry |
Distinguish retryable (transient network/timeout, session expired) from non-retryable (business reject) errors. Only retryable errors are retried, and at most twice with exponential backoff.
12. Idempotency
All issuance-class operations carry an idempotency key derived from (partner_id, booking_id, operation_type). Replay of an identical issuance request returns the previously-cached ticket number without calling the GDS again.
13. Credentials
Per-supplier credentials stored encrypted at rest (KMS envelope encryption) in supplier_credentials. Accessible only by the integration service account; never exposed to UI; never logged in plaintext.
Rotation: - Production credentials rotated every 90 days (Amadeus / Sabre / Travelport policies). - Rotation orchestrated by a runbook; no API outage.
14. Observability
Every GDS call produces: - Request log row (request, response, latency, status). - Metric: per-operation success rate, p50/p95/p99 latency. - Alert: success rate < 95% on 5-minute window. - Alert: p95 latency > target on 5-minute window.
15. Database tables touched
| Table | Role |
|---|---|
supplier_credentials |
Encrypted auth |
supplier_request_log |
Per-call audit |
bookings |
PNR fields |
booking_tsts |
TST/pricing records |
booking_tickets |
Issued docs |
booking_segments |
Per-segment state from GDS |
idempotency_keys |
Replay safety |
16. Common pitfalls
- ⚠️ GDS call inside DB transaction. Database lock held during a 30s network call → cascading lock contention.
- ⚠️ Retrying non-retryable errors. "Price changed" retried is bad UX; require explicit user re-confirm.
- ⚠️ Trusting GDS-supplied fare without re-pricing. Always re-price before issuance.
- ⚠️ Not capturing fare rules at booking time. Fare rules change; archive the version at booking.
- ⚠️ Sharing credentials across partners. Per-partner credentials only.
- 🔒 Logging request payload with credentials. Strip auth headers from logs.
- ⚠️ Ignoring schedule-change queue. Customers turn up at the airport on the wrong flight.