Cancel a booking
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.
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.
Empty on purpose. Cancelling is unconditional; get a cancellation quote first if the cost matters. Any field is a 400.
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/cancel" \ -H "Content-Type: application/json" \ -d '{}'{ "data": { "id": "bkg_0192f3a4b5c64d7e8f9a0b1c2d3e4f5b", "supplier": "DUFFEL", "status": "CREATED", "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" } ], "expires_at": "2026-11-01T12:49:56.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" } ] }, "failure": { "code": "book_failed", "description": "The offer is no longer available." }, "created_at": "2026-11-01T12:34:56.000Z", "updated_at": "2026-11-01T12:40:12.000Z" }}Book: pay and ticket POST
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.
Quote a cancellation GET
What cancelling right now would cost. It asks the airline for its own quote and moves no money; for a Duffel booking the airline prepares a cancellation that is never confirmed and lapses on its own. When the airline cannot answer, you receive an estimate from the fare terms stored on the booking instead, and `source` says which one you have. The quote is advisory: the airline decides the real fee when the cancel lands. When the money fields are absent, `unavailable_reason` says why; that is not a free cancellation. Every call asks the airline again, so do not poll it.