Skip to content

Offers and Orders

Dusan Milicevic edited this page Apr 17, 2026 · 1 revision

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.

Why both

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.

AIDM 24.1 alignment

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.

The BookingReference bridge

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

Queue management stays PNR-only

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.created
  • order.confirmed
  • order.ticketed
  • order.changed
  • order.cancelled
  • order.payment_received
  • order.payment_failed
  • order.refunded

Key types

// 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.

Adapter support today

Two adapters ship with native order operations:

Navitaire — NavitaireOrderOperations

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 — DuffelOrderBridge

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.

Working with references

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');

Zod schemas

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);

See also

  • Adapters — which adapters speak Orders natively
  • Pipeline Contract — the contracts at Stage 3 accept BookingReference
  • Architecture — where order operations sit in the layered view

Clone this wiki locally