NDC 21.3 Integration Guide for Flight APIs
A practical, developer-oriented overview of NDC 21.3: concepts, messages, XML structure and real-life integration tips.
1. Why NDC 21.3 matters
NDC is IATA’s standard for modern airline distribution. Instead of the traditional “availability & pricing in old GDS formats”, NDC is offer & order based. Version 21.3 is one of the most widely used and stable NDC releases in production.
If you are building a flight engine, OTA, agency platform or B2B travel tool, you will eventually need to:
- Search and price NDC offers
- Create orders (bookings) using NDC messages
- Retrieve, modify and cancel NDC orders
- Combine NDC content with non-NDC (GDS, LCC, direct) sources
This article focuses on the technical side: which messages you really need, basic XML structure and how to design your backend around NDC 21.3.
2. Core concepts: offers and orders
In NDC, you don’t “book an itinerary” directly. You:
- Shop for offers (flights + services + prices)
- Price / re-price a selected offer
- Create an order from that priced offer
- Pay / ticket that order
Some key data structures you will see in 21.3:
- DataLists – master lists (flights, segments, services, passengers, etc.)
- Offer – a priced set of services for given passengers
- Order – the “booking” created from an offer
3. NDC 21.3 messages you actually need
A typical NDC 21.3 implementation for flight shopping & booking will include at least these messages (naming varies slightly per provider, but the pattern is similar):
- AirShoppingRQ / RS – flight search (offers)
- OfferPriceRQ / RS – re-price / price confirmation
- OrderCreateRQ / RS – create an order (booking)
- OrderRetrieveRQ / RS – get order details
- OrderCancel / Change – cancel or change an order
- SeatAvailability / ServiceList – seatmaps and ancillaries
Most providers expose these as REST endpoints returning NDC XML payloads. You can either:
- Map XML directly to your domain models (recommended), or
- Store “raw” NDC XML and map only what you need for the UI
4. Typical NDC flow: from search to order
A basic end-to-end flow usually looks like this:
-
Search: send
AirShoppingRQwith origin, destination, dates, PAX and cabin preferences. Receive a list of offers. - Select: user picks one offer (or itinerary) from the result.
-
Price: send
OfferPriceRQfor the selected offer to confirm price and get final details (baggage, restrictions, etc.). -
Create Order: send
OrderCreateRQincluding passenger data, contact info and selected services. -
Pay / Ticket: depending on the provider, payment and ticketing
may be part of
OrderCreateor separate steps. -
Retrieve: use
OrderRetrieveRQto show booking details in “My Trips” screens or admin panels.
5. A minimal AirShoppingRQ example
Below is a simplified (provider-agnostic) example of an
AirShoppingRQ structure for one-way search with NDC 21.3 style
elements. Real implementations will include more namespaces, attributes and
additional sections.
<AirShoppingRQ Version="21.3">
<Document>
<Name>gosuware-ndc-client</Name>
</Document>
<Party>
<Sender>
<TravelAgencySender>
<Name>Gosuware Demo</Name>
<IATA_Number>12345678</IATA_Number>
</TravelAgencySender>
</Sender>
</Party>
<CoreQuery>
<OriginDestinations>
<OriginDestination>
<Departure>
<AirportCode>IST</AirportCode>
<Date>2025-06-01</Date>
</Departure>
<Arrival>
<AirportCode>LHR</AirportCode>
</Arrival>
</OriginDestination>
</OriginDestinations>
</CoreQuery>
<Travelers>
<Traveler>
<AnonymousTraveler>
<PTC>ADT</PTC>
</AnonymousTraveler>
</Traveler>
</Travelers>
</AirShoppingRQ>
Your backend should have a clear mapping layer that takes your own
SearchRequest model (origin, destination, dates, pax) and produces
this XML in a predictable and testable way.
6. Designing your backend around NDC 21.3
From a system design perspective, NDC should not leak into your entire codebase. Treat it as an integration layer with clearly defined boundaries.
6.1. Separate provider layer
- Create an internal model for search, pricing, offers and orders.
- Implement a
NdcProviderorNdcClientthat knows how to: - Build XML requests for each NDC message
- Send them over HTTP with proper auth
- Parse XML responses into internal models
- Keep XML and transport details inside that layer only.
6.2. Versioning & configuration
- Keep NDC version (21.3) and provider endpoints in config, not hard-coded.
- Plan for future versions (e.g. 20.2, 21.3, 22.x) using feature flags or adapter pattern.
6.3. Logging & observability
- Log correlation IDs from your system into the NDC calls.
- Store sanitized request/response snippets for debugging (without PII and payment data).
- Track latency and error codes per provider to identify problems quickly.
6.4. Error handling & idempotency
- Handle timeouts and transient network errors with controlled retries.
- Use idempotency keys for critical calls like
OrderCreate. - Design clear compensating actions when downstream calls fail half-way.
7. Testing NDC integrations
NDC providers usually offer sandbox or test environments, but they often have:
- Limited test data
- Unrealistic availability
- Different behaviour than production
A solid testing strategy should include:
- Contract tests for each NDC message type you use
- End-to-end flows: search → price → create order → retrieve
- Simulated failure scenarios (timeouts, “no fare”, “no seats”, etc.)
At Gosuware, I am working on a dedicated sandbox environment idea where real-world scenarios and edge cases can be tested against multiple GDS/NDC integrations with a single, unified interface.
8. Common pitfalls I see in real projects
- Leaking NDC XML everywhere: mixing provider-specific XML with business logic and UI code.
- No separation between search and booking: reusing search responses directly for booking without proper re-pricing or validation.
- Weak error handling: treating all errors as “try again later” instead of designing clear flows for user-visible and technical errors.
- No structured logging: impossible to trace a single customer journey across multiple NDC calls.
- Ignoring performance & cost: sending too many search calls, no caching, and no control over provider usage.
9. When to ask for help
NDC 21.3 is powerful, but it also adds complexity. If your team is already busy shipping features, designing a robust NDC integration from scratch can slow you down or lead to fragile code.
If you need help with:
- Designing a clean NDC integration architecture
- Mapping NDC 21.3 messages to your flight engine
- Improving an existing NDC or GDS integration
you can reach me through the contact form on this site or explore:
I build and maintain flight search and booking systems professionally, and Gosuware is where I combine that experience with focused, hands-on help for teams working in travel technology.
If you’d like to discuss your NDC 21.3 integration, feel free to get in touch.