Guides · Orders
Orders Lifecycle
How an offer becomes a booking: price it, create the order, pay, and follow its status.
D-221Order states, as a railway
Booking flow
1
Search
POST /v1/shopping/offers returns offers from every connected airline.
2
Seats and extras (optional)
GET /v1/offers/{offerID}/seats and GET /v1/offers/{offerID}/services.
3
Price
POST /v1/offers/price with { offer_ids: [...] } confirms the price and returns the offer_id to book, valid until price_guaranteed_until.
4
Create the order
POST /v1/orders with the priced offer_id, passengers, contact and any seats and ancillaries. With a payment the tickets are issued in the same call; without one the order is a hold.
5
Pay a hold
POST /v1/orders/{orderID}/commit with a payment, before expires_at.
Card, amount and currency rules are in Payment Flow; changes, cancellations and refunds in Post-Booking Servicing.
Order states
| Status | Meaning |
|---|---|
| pending | Created, not yet confirmed by the airline. |
| confirmed | Reserved at the airline with a PNR (passenger name record), not ticketed. An unpaid hold is confirmed with expires_at. |
| ticketed | Tickets issued; the numbers are in tickets[]. |
| partially_cancelled | Some flights cancelled; the rest stands. |
| disrupted | The airline has disrupted the booking. |
| cancelled | Cancelled, by you or by the airline. |
| refunded | Refund recorded; the airline returns the money to the original card. |
| failed | The airline reports the order as failed. |
Do not tell the traveller they are ticketed until the status is ticketed and tickets[] is not empty.
The order object
Returned by POST /v1/orders, GET /v1/orders/{orderID} and every servicing write. GET /v1/orders lists orders newest first (filters: airline, pnr, status; paginate with limit and cursor).
| Field | What it holds |
|---|---|
| airline · status · environment | The carrier holding the booking, the current state, and sandbox or production. |
| expires_at | On an unpaid hold, the airline's payment deadline. |
| history[] | A brief timeline, on GET /v1/orders/{orderID}. The full record is GET /v1/orders/{orderID}/history. |
| order_id | The id every later call takes in the path. |
| passengers[] | The travellers. Use each passenger's id from here in later calls; it may differ from the one you sent. type is the code the airline files (e.g. CNN for a child). |
| pnr · airline_order_id | The airline's record locator and its own order id. |
| slices[] · seats[] · ancillaries[] | The itinerary and the extras on it. |
| tickets[] · payments[] | Issued tickets and EMDs (Electronic Miscellaneous Documents), and the payments the airline reports, plus any refund recorded. |
| total_amount · currency | What the order comes to, your service_fee included. |
| trip_id · trip[] | On a self-transfer trip: the trip id, and on a single-order read every ticket of the trip. |
| warnings[] | Notices on a successful answer, such as a document the airline could not issue. Only on that response. |
GET /v1/orders/{orderID} returns the stored copy; ?refresh=true asks the airline for the current state.
Holds and the payment deadline
- Create the order without a payment to hold it. It comes back confirmed, with expires_at set to the airline's payment deadline.
- Pay before expires_at with POST /v1/orders/{orderID}/commit. An order is paid once; paying it again is 409 already_paid.
- After expires_at the airline releases the hold: payments, seats and extras are refused with 422 hold_expired. Search again to rebook. Cancelling is always allowed.
Self-transfer trips
- A priced self-transfer trip (offer_id starting CONN-P) is booked with the same POST /v1/orders. It makes one order per airline and returns a Trip: trip_id, status (held or paid), total_amount, transfers[] and orders[].
- Every ticket is booked or none. If one fails, the tickets already made are cancelled; the error's trip object names failed_ticket, failed_airline, released_orders and unreleased_orders (tickets the airline kept).
- Seats and extras are added on each order once the trip is booked (422 extras_not_supported on the trip booking).
Important notes
- Book the offer_id that POST /v1/offers/price returned, never the one from search. A payment needs the offer priced in the last 30 minutes (409 offer_not_priced).
- Give each passenger's own email and phone, not the agency's.
- Infants must not outnumber adults, and an infant on a lap holds no seat.
- Never resend a booking answered 502 booking_outcome_unknown: read GET /v1/orders instead.
- Send an Idempotency-Key on POST /v1/orders (required with a payment) and reuse it on every retry. Booking the same travellers on the same offer again is 409 offer_already_ordered.
Retries are in Servicing, every error code in Errors, order events in Webhooks.