Docs
Get an API key

Cancel a flight booking

Quote, cancel a confirmed ticket, and read what the refund did.

In short

3 calls, in the order this page makes themFor people and agents
  1. 1GET/v1/flight/bookings/{id}/cancellation-quoteQuote a cancellation
  2. 2POST/v1/flight/bookings/{id}/cancelCancel a booking
  3. 3GET/v1/flight/bookings/{id}Get a booking

The same list heads this page's Markdown:/flight/flight-cancel.md

You have a confirmed ticket to release, and you need the traveller refunded whatever the fare's terms allow.

Cancel is two calls: a quote that shows what cancelling would cost right now, then the cancel itself, which is accepted immediately and completes in the background.

Quote first

Request
curl "$BASE_URL/v1/flight/bookings/bkg_0192f3a4b5c64d7e8f9a0b1c2d3e4f5b/cancellation-quote" \
  -H "x-api-key: $API_KEY"
Response
{ "data": { "source": "SUPPLIER_QUOTE", "is_free": false, "fee": { "amount": 95.00, "currency": "USD" }, "refundable_amount": { "amount": 286.14, "currency": "USD" }, "quoted_at": "2026-11-01T09:12:44.000Z" } }

The quote asks the airline what cancelling would cost right now, and moves no money. source says where the numbers come from: SUPPLIER_QUOTE is the airline's own quote; POLICY_ESTIMATE is an estimate from the fare terms stored when you booked, which you receive when the airline cannot answer. For a Duffel booking, the airline prepares a cancellation that is never confirmed and lapses on its own; the quote cancels nothing. Every quote asks the airline again, so do not poll it.

When the money fields are absent, read unavailable_reason: refund_not_cash (the airline would not refund to your traveller's original payment, and a cancel is refused for the same reason), no_policy (the airline published no terms), no_total, fee_unknown or currency_mismatch. A quote without a fee is not a free cancellation. A POLICY_ESTIMATE is not the airline's answer: the airline can still refuse the cancel, and the booking's failure then says why.

A quote on a booking that is not confirmed is 422 cancellation_not_quotable.

The airline decides the real fee when the cancel lands. The quote is advisory, and the cancel is unconditional: nothing refuses it on your behalf if the fee turns out higher.

Cancel

For the OEX refund flow:

Quote, then cancel: the airline first, the money second, then the booking is canceled and reports what happened

Request
curl -X POST "$BASE_URL/v1/flight/bookings/bkg_0192f3a4b5c64d7e8f9a0b1c2d3e4f5b/cancel" \
  -H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
  -d '{}'

The body is empty on purpose; a field in it is a 400. The 202 is the booking as CANCEL_IN_PROGRESS. You wait for the workflow to establish cancellation before a refund is requested. OEX uses Payment for its refunds; LiteAPI handles refunds itself.

A booking that is neither confirmed nor already cancelling is a 409. For an unsettled OEX payment you receive 422 booking_incomplete: wait for it to resolve, then cancel. LiteAPI refreshes payment evidence before cancel; an unsettled supplier payment does not block cancellation. A supplier that cannot cancel through the API is 422 supplier_operation_unsupported.

Read what happened

Poll the booking:

Request
curl "$BASE_URL/v1/flight/bookings/bkg_0192f3a4b5c64d7e8f9a0b1c2d3e4f5b" \
  -H "x-api-key: $API_KEY"
  • CANCELED with a cancellation block: the ticket is gone. cancellation.fee is what the airline kept and cancellation.refund_amount is the intended refund. Read cancellation.refunded_by for who handles it: OEX or SUPPLIER. Zero means no refund was due. An absent amount means a person must review it; contact support with the request id.
  • CONFIRMED again: the airline refused. Your ticket is still valid; cancellation refusal does not establish its payment status. failure.code on the booking says why: refund_not_cash when the airline would not refund to your traveller's original payment, cancellation_not_quotable when it did not state a cash amount we could settle against, or supplier_rejected.
  • CANCEL_IN_PROGRESS for longer than a few minutes: the workflow is retrying or has stopped. Repeat the cancel call; it can restart a stopped run. OEX refund requests keep stable keys. For a LiteAPI booking the airline confirms the cancellation after you call, so it can stay CANCEL_IN_PROGRESS until the airline does; repeating the call then sends nothing new.

You cannot infer settlement from refund_amount. For refunded_by: "OEX", Payment handles the refund. For SUPPLIER, LiteAPI handles it; contact support for its progress. If the amount is absent, it remains unknown even though your ticket is canceled.

cancellation.refund_to names the payments the refund returns to, each to its original payment method; their cards, where known, are in payments. A payment the fee used up is not listed: with $100 paid on one card, $40 of bags on another and a $120 fee, only the bags' payment gets money back. An empty list means nothing is refunded. An absent one means the refund is not established, and the money can then return only to one of your CAPTURED payments.

"cancellation": { "refunded_by": "OEX", "fee": { "amount": 95.00, "currency": "USD" }, "refund_amount": { "amount": 286.14, "currency": "USD" }, "refund_to": [{ "payment_id": "pay_0192f3a4b5c64d7e8f9a0b1c2d3e4f60" }] }

Keep learning

On this page