Book: pay and ticket
Charge the traveller and issue the ticket: the saved payment_instrument_id is authorized, the airline issues the order, and the authorization is captured. The 200 is the booking as CONFIRMED with supplier_reference and, when the airline provides one, airline_pnr. Send {} when prebook set use_payment_sdk. A 202 returns the booking as COMPLETE_IN_PROGRESS: LiteAPI is still ticketing. Wait for flight.booking.confirmed or read the booking, and do not book again: a repeat book returns the same 202. If it stays COMPLETE_IN_PROGRESS, contact support with your booking id. Booking an already confirmed booking returns it unchanged; a 500 result_unknown means the outcome could not be established and must not be retried.
Your API key. Issued and revoked from the TrustPixel dashboard; the gateway resolves it to an owning organization on every request.
In: header
Path Parameters
Header Parameters
Correlation id echoed to the upstream service and returned on the response. Generated as req_<uuid> when omitted.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
For Duffel, send your saved payment_instrument_id or an empty object after OEX SDK checkout. For LiteAPI, send an empty object after its checkout, because the supplier collects payment.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/flight/bookings/string/book" \ -H "Content-Type: application/json" \ -d '{}'{ "data": { "id": "bkg_0192f3a4b5c64d7e8f9a0b1c2d3e4f5b", "supplier": "DUFFEL", "status": "CONFIRMED", "total_amount": { "amount": 260.67, "currency": "USD" }, "fare_amount": { "amount": 220.67, "currency": "USD" }, "fare_tax_amount": { "amount": 50, "currency": "USD" }, "services_amount": { "amount": 40, "currency": "USD" }, "services": [ { "id": "svc_0192f3a4b5c6", "status": "PENDING", "passenger_id": "string", "segment_ids": [ "string" ], "quantity": 1, "unit_amount": { "amount": 40, "currency": "USD" }, "total_amount": { "amount": 40, "currency": "USD" }, "payment_id": "pay_0192f3a4b5c64d7e8f9a0b1c2d3e4f61", "type": "BAGGAGE", "baggage": { "type": "CHECKED", "max_weight_kg": 23 } } ], "payments": [ { "id": "pay_0192f3a4b5c64d7e8f9a0b1c2d3e4f60", "status": "CAPTURED", "amount": { "amount": 180.67, "currency": "USD" }, "collected_by": "OEX", "payment_method": { "type": "CARD", "card": { "brand": "VISA", "last4": "4242", "funding": "CREDIT", "wallet": "APPLE_PAY" } }, "created_at": "2026-11-01T12:40:12.000Z" } ], "cancellation_policy": { "refundable": false, "penalty": { "amount": 150, "currency": "USD" } }, "fare_conditions": { "refund": { "allowed": true, "penalty": { "amount": 75, "currency": "USD" } }, "change": { "allowed": true, "penalty": { "amount": 75, "currency": "USD" } } }, "passengers": [ { "id": "string", "first_name": "Amira", "last_name": "Haddad", "loyalty_accounts": [ { "airline_iata_code": "BA", "membership_number": "•••••1014" } ] } ], "journeys": [ { "id": "string", "origin": "LHR", "destination": "CDG", "direction": "OUTBOUND", "fare_brand": "Premium", "departure_time": "2026-11-10T06:58:00", "arrival_time": "2026-11-10T09:15:00", "duration_minutes": 137, "stops": 0, "segments": [ { "id": "string", "origin": "LHR", "destination": "CDG", "departure_time": "2026-11-10T06:58:00", "arrival_time": "2026-11-10T09:15:00", "marketing_flight": "AF1681", "marketing_carrier": "Air France", "marketing_carrier_logo_url": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AF.svg", "operating_carrier": "KLM", "operating_carrier_logo_url": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/KL.svg", "duration_minutes": 137, "passengers": [ { "passenger_id": "psg_0192f3a4b5c64d7e8f9a0b1c2d3e4f5c", "cabin_class": "BUSINESS", "cabin_name": "Business", "checked_bags": 1, "carry_on_bags": 1 } ] } ] } ], "supplier_reference": "ord_0000B9M0HSU2oNVmKw0UKj", "airline_pnr": "J6AK3S", "confirmed_at": "2026-11-01T12:40:12.000Z", "canceled_at": "2026-11-02T09:15:00.000Z", "cancellation": { "fee": { "amount": 95, "currency": "USD" }, "refunded_by": "SUPPLIER", "refund_amount": { "amount": 286.14, "currency": "USD" }, "refund_to": [ { "payment_id": "pay_0192f3a4b5c64d7e8f9a0b1c2d3e4f61" } ] }, "created_at": "2026-11-01T12:34:56.000Z", "updated_at": "2026-11-01T12:40:12.000Z" }}Get a booking GET
One booking with its itinerary, passengers, services, payments and money, in whatever status it has. `expires_at` is present while the booking can still be completed, `failure` when it is `FAILED` or when a cancellation was refused, and `cancellation` once it is `CANCELED`. Each payment carries its card in `payment_method` when the card can be read; a card that could not be read in time can appear when you read the booking again. `airline_initiated_changes` lists the airline's recorded changes to your booked flights, beside the flights you booked in `journeys`. A booking you do not own is a `404`.
Cancel a booking POST
Starts a background cancellation and returns immediately. Poll GET /v1/flight/bookings/{id} for supplier cancellation: CANCELED means the ticket was released; CONFIRMED means it remains valid after a rejected cancellation. The cancellation block contains the supplier fee and intended refund_amount, not refund settlement. After supplier success, the workflow submits refund requests to Payment and completes when they are accepted. Payment owns subsequent processing. A repeated request does not restart an active or completed run; it can restart a failed run, including refund submission for an already canceled booking. Canceled bookings return 200; cancellations in progress return 202. Validation failures return 4xx.