-
Notifications
You must be signed in to change notification settings - Fork 11
Offers and Orders
OTAIP supports both PNR-based and Order-based booking models. The travel industry is mid-transition — some carriers still issue PNRs via GDS, others have moved to IATA ONE Order. OTAIP speaks both through a unified BookingReference bridge.
A production distribution system cannot pick a side. An itinerary may contain:
- A GDS-ticketed leg on a legacy carrier (PNR)
- An NDC-ticketed leg on a progressive carrier (Order)
- An LCC leg on an ONE Order certified platform (Order)
Agents and the pipeline must not care which model is under a given booking. They accept a BookingReference and let the adapter decide.
OTAIP order terminology follows IATA's Airline Industry Data Model (AIDM) 24.1.
| AIDM message | OTAIP method | Purpose |
|---|---|---|
OrderCreate |
orderCreate() |
Create an order from an offer |
OrderRetrieve |
orderRetrieve() |
Fetch an existing order |
OrderChange |
orderChange() |
Modify an existing order |
OrderCancel |
orderCancel() |
Cancel an order |
Entity names (Offer, OfferItem, Order, OrderItem, Service) align with AIDM. The implementation is JSON — not the AIDM XML schema.
type BookingReference = PnrReference | OrderReference;
interface PnrReference {
type: 'pnr';
recordLocator: string;
gds?: 'AMADEUS' | 'SABRE' | 'TRAVELPORT';
}
interface OrderReference {
type: 'order';
orderId: string;
owner: string; // airline code
}Agents accept BookingReference. The GdsNdcRouter (3.1) chooses the path:
| Scenario | Model | Why |
|---|---|---|
| GDS booking (Amadeus, Sabre) | PNR | GDS systems create PNRs |
| NDC booking (Duffel) | Order | NDC uses offer/order |
| ONE Order certified (Navitaire) | Order | Native order ops |
| Mixed itinerary | Both | Each segment uses its channel's model |
A deliberate domain decision. Queues are a GDS construct. Orders use event-driven status through OrderEvent, not queues.
The OrderEventType union covers the full lifecycle:
order.createdorder.confirmedorder.ticketedorder.changedorder.cancelledorder.payment_receivedorder.payment_failedorder.refunded
// Atomic sellable unit — everything in an offer/order is a Service
interface Service {
serviceId: string;
type: 'flight' | 'seat' | 'baggage' | 'meal' | 'lounge' | 'insurance' | 'ancillary';
flight?: FlightService;
description?: string;
}
interface Offer {
offerId: string;
owner: string;
offerItems: OfferItem[]; // each references one or more Services
totalPrice: Money;
expiresAt: string;
}
interface Order {
orderId: string;
owner: string;
orderItems: OrderItem[]; // references OfferItems
passengers: OrderPassenger[];
tickets?: TicketDocument[]; // ET, EMD-A, EMD-S
payments?: OrderPayment[];
status: OrderStatus;
events: OrderEvent[];
}Money is a decimal string + ISO 4217 currency — never a number.
Two adapters ship with native order operations:
Navitaire is ONE Order certified. NavitaireOrderOperations implements OrderOperations by mapping dotREZ endpoints to AIDM 24.1. Orders get NAV-ORD-* IDs and full OrderEvent history tracking.
Duffel already uses orders as its native booking primitive. DuffelOrderBridge bridges Duffel's order model to OTAIP's Order types. Orders get DFL-ORD-* IDs.
Both capability manifests declare:
{
supportsOrders: true,
orderOperations: ['create', 'retrieve', 'change', 'cancel'],
}The other four adapters (Amadeus, Sabre, TripPro, HAIP) are PNR-only today.
import {
createPnrReference,
createOrderReference,
isPnrReference,
isOrderReference,
getBookingIdentifier,
pnrPassengerToOrderPassenger,
} from '@otaip/core';
const pnr = createPnrReference('ABC123', 'AMADEUS');
const order = createOrderReference('DFL-ORD-001', 'BA');
function handle(ref: BookingReference) {
if (isPnrReference(ref)) {
// PNR path — queues, GDS commands, ATPCO data
} else {
// Order path — OrderChange, event-driven status
}
}
// Identifier usable as a map key regardless of type
const id = getBookingIdentifier(ref);
// Convert a PNR passenger into the Order passenger shape
const orderPax = pnrPassengerToOrderPassenger(pnrPassenger, 'pax-1');Every type has a Zod schema for runtime validation and JSON Schema generation:
import {
orderSchema,
offerSchema,
orderChangeRequestSchema,
zodToJsonSchema,
} from '@otaip/core';
const result = orderSchema.safeParse(data);
// Feed an LLM tool directly
const jsonSchema = zodToJsonSchema(orderSchema);- Adapters — which adapters speak Orders natively
-
Pipeline Contract — the contracts at Stage 3 accept
BookingReference - Architecture — where order operations sit in the layered view