Docs
Get an API key

Flight API errors

The error envelope, every code and reason with what to do next, and request ids.

Every failure has the same shape:

{ "error": { "code": "unprocessable", "reason": "offer_expired", "message": "offer has expired; create a new booking", "request_id": "req_019ff4c40a7476d584985652b8e989f0" } }

code is the class of failure. reason is why. Branch on reason and fall back to code. reason is present on every 422 and 502, and on 500 result_unknown, which requires the recovery steps in Retry flight calls safely; a 400, 401, 404 or 409 carries none.

Codes

CodeStatusWhat happened, and what to do
validation_error400The body, query, path or a required header is wrong. Fix the request; details names the field. At prebook it also answers a traveller or contact name the supplier refused as a placeholder, such as Test: the booking is then FAILED with failure.code passenger_name_rejected, so send the real name with a new idempotency key.
unauthorized401Your API key is missing or invalid. Send it as x-api-key on every request.
not_found404No such resource, or it is not yours. Do not retry.
conflict409The booking or offer is not in a state that allows this: a book while another book is still running, a cancel on a booking that is neither confirmed nor already cancelling, bags on a booking that cannot take them, or a prebook of a Duffel offer another booking holds. Re-read the booking and act on its status; for a held offer, search again.
unprocessable422The request cannot be fulfilled as sent. Do not retry unchanged; reason says what to change.
internal_error500An error on our side, or a result we could not determine. Read result_unknown before doing anything else.
supplier_unavailable502A supplier did not answer and nothing was decided. Retry with backoff.

Reasons

ReasonStatusWhat happened, and what to do
offer_expired422Request a fresh offer when its reference has lapsed. For an existing LiteAPI checkout, contact support before replacing it because expiry does not establish whether your traveller paid.
price_changed422The airline re-priced between the offer and prebook; the booking is FAILED. Request offers again and prebook from the fresh reference.
passenger_mismatch422The party does not match the offer that was searched, or the Duffel offer carries loyalty accounts or names that an earlier booking of it left and that differ from yours. Search again.
document_required422The offer's documents_required is true and a passenger has no document. Collect one for every passenger and prebook again with a new key.
services_unavailable422An extra can no longer be bought as chosen: a bag is no longer sold or would take the booking past the supported amount, a seat is taken or priced differently, or two passengers named one seat. At prebook, list the extras again and prebook with a new key. At book the booking is FAILED and nothing is captured: search again.
payment_method_unsupported422For LiteAPI, set use_payment_sdk: true at prebook and send {} at book. For an OEX SDK booking, omit payment_instrument_id at book. You cannot mix SDK checkout and a saved instrument.
payment_failed422On OEX, the card was declined or the Payment SDK intent has not confirmed. At prebook the booking is FAILED: send a new key. At book, an unconfirmed intent leaves the booking READY_FOR_COMPLETE: confirm it and book again; a decline marks the booking FAILED.
supplier_operation_unsupported422The supplier cannot do this: the requested operation or paid bags and seats are unsupported, or no routed supplier can serve the search. Choose another offer or name another supplier.
booking_incomplete422The stored booking lacks something the operation needs, such as a bound price, a prebook hold, passenger ids or an itinerary, or it has an unsettled OEX payment that must resolve before it can be cancelled. Contact support for an incomplete LiteAPI booking before creating a replacement checkout.
supplier_rejected422The supplier answered, and the answer was no. message and details carry what it said; do not retry unchanged.
loyalty_membership_rejected422At book on Duffel, the airline did not recognise a loyalty number, so the booking is FAILED and no payment is captured. Search again and prebook the new offer without that number, with a new key.
cancellation_not_quotable422A cancellation quote on a booking that is not confirmed. Cancel is accepted with 202 before the airline is asked, so an airline refusal is never an HTTP reason: read it from the booking's failure.code instead.
supplier_unreachable502Retry with backoff when no stateful outcome is unknown. A failed Duffel prebook holds no inventory; an uncertain prebook instead returns result_unknown.
result_unknown500Re-read your booking because the supplier may have acted. Keep the booking and request ids and contact support before sending another book request. Never create a replacement LiteAPI checkout to bypass this state. A Duffel prebook that answers it holds no inventory and has charged nothing: replay its key to read it, then search again and prebook the new offer with a new key.

Request ids

Every response carries x-request-id, and every error body repeats it as error.request_id. Log it, and quote it when you contact support.

Keep learning

On this page