Quote the refund of an issued order
Ask what cancelling an issued Duffel order would refund.
/api/v1/flights/cancel_quoteThe call creates a pending cancellation at the supplier with the refund amount; nothing is cancelled and no money moves until you confirm it with confirm_cancel.
A quote is valid for one hour (cancellation.expiresAt) and the amount is the supplier's offer for that moment: ask again if you wait. Whether an order can be cancelled at all depends on the airline and the fare: many fares are refused with order_not_cancellable. Only Duffel orders are quoted; an order of another supplier is 400. Held reservations are cancelled with cancel_order.
Send one of order_id (the supplier's order id, ord_...), booking_id and pnr: FX-Port finds the booking of your agency and sends the supplier's own id to Duffel. An unknown order and the order of another agency answer the same 404 booking_not_found. Read success: a refusal of the supplier is HTTP 200 with success: false.
curl https://api.fx-port.com/api/v1/flights/cancel_quote \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"order_id": "ord_0000BC0VDONwA54LrfoCkm"
}'{
"environment": "sandbox",
"success": true,
"requestId": "2cb63f69",
"orderId": "ord_0000BC0VDONwA54LrfoCkm",
"processingTime": 0.128,
"cancellation": {
"cancellationId": "ore_0000BC0VG9WBaFAZ83u3yy",
"orderId": "ord_0000BC0VDONwA54LrfoCkm",
"status": "pending",
"refund": {
"originalRefundCurrency": "USD",
"originalRefundAmount": 76.86,
"refundCurrency": "DZD",
"refundAmount": 19215,
"refundTo": "FX-Port Balance",
"refundToRaw": "balance",
"convertedSupplierRefundAmount": 19215,
"isFullBalanceRefund": false,
"kioskCommissionRefund": 0
},
"expiresAt": "2026-11-01T15:28:32Z",
"confirmedAt": null,
"createdAt": "2026-11-01T14:28:32.488592Z",
"airlineCredits": null,
"liveMode": false
},
"supplier": {
"id": "duffel_1",
"technology": "duffel",
"name": "Duffel"
},
"agency": {
"currency": "DZD"
},
"exchangeRate": {
"rate": 250,
"marginPercent": 0,
"fromCurrency": "USD",
"toCurrency": "DZD"
},
"meta": {
"quoteValidUntil": "2026-11-01T15:28:32Z",
"isConfirmed": false,
"canConfirm": true
}
}{
"environment": "sandbox",
"requestId": "d0786d15",
"orderId": "ord_0000BC0VKb81MLN9OaFAhB",
"processingTime": 0.11,
"error": {
"message": "This order cannot be cancelled through the API.",
"code": "order_not_cancellable",
"type": "invalid_state_error",
"details": [
{
"documentation_url": "https://duffel.com/docs/api/overview/response-handling",
"title": "Order not cancellable",
"type": "invalid_state_error",
"message": "This order cannot be cancelled through the API.",
"code": "order_not_cancellable"
}
]
},
"supplier": {
"id": "duffel_1",
"technology": "duffel",
"name": "Duffel"
},
"meta": {
"request_id": "d0786d15",
"status": 200
},
"success": false,
"errors": [
{
"code": "order_not_cancellable",
"type": "supplier_error",
"title": "Order not cancellable",
"message": "This order cannot be cancelled through the API.",
"field": null,
"details": {
"supplier_type": "invalid_state_error",
"supplier_details": [
{
"documentation_url": "https://duffel.com/docs/api/overview/response-handling",
"title": "Order not cancellable",
"type": "invalid_state_error",
"message": "This order cannot be cancelled through the API.",
"code": "order_not_cancellable"
}
]
},
"documentation_url": "https://fx-port.com/docs/errors#order_not_cancellable"
}
],
"request_id": "d0786d15"
}Request
Body
Required, JSON.
order_idstringThe supplier's order id (ord_...). booking_id and pnr are accepted as other names; FX-Port sends the supplier's own id to Duffel.
booking_idstringAnother name of order_id: the PNR.
pnrstringAnother name of order_id: the airline record locator.
supplier_idstringDefault duffel_1. A value that does not start with duffel is 400.
agency_idstringNot needed: the agency of a call is always the one of your API key. The field is accepted so that older clients keep working, and it is ignored.
orderIdstringdeprecatedLegacy name, still accepted. Use order_id instead.
The previous spelling of order_id: The supplier's order id (ord_...).
bookingIdstringdeprecatedLegacy name, still accepted. Use booking_id instead.
The previous spelling of booking_id: Another name of order_id: the PNR.
supplierIdstringdeprecatedLegacy name, still accepted. Use supplier_id instead.
The previous spelling of supplier_id: Default duffel_1.
agencyIdstringdeprecatedLegacy name, still accepted. Use agency_id instead.
The previous spelling of agency_id: Not needed: the agency of a call is always the one of your API key.
Response
200The pending cancellation and its refund. Show the amount to your customer, then confirm with cancellation.cancellationId. success: false with error when the supplier refuses.
environmentstringThe environment of the key that made the call: sandbox for fxp_test_ keys, live for fxp_live_ keys. Present in every JSON body.
One of sandbox, live.
request_idstringThe id of the request, also in the X-Request-Id header.
warningsarray of objectPresent only when the request used a previous spelling of a field or something the endpoint ignored.
ShowHide 5 attributes
codestringWhat the warning is about.
One of deprecated_field, ignored_field, coerced_value, deprecated_value, deprecated_endpoint.
fieldstringThe request field the warning is about.
replacementstringThe name to use instead, for deprecated_* warnings.
messagestringA sentence that says what happened and what to do.
documentation_urlstringWhere the naming rules are explained.
successbooleantrue when the quote was created.
requestIdstringdeprecatedLegacy name, still accepted. Use request_id instead.
The id of this request, 8 characters, for support.
orderIdstringdeprecatedLegacy name, still accepted. Use order_id instead.
The supplier's order id.
order_idstringThe supplier's order id. The snake_case twin of orderId, with the same value: use this name.
processingTimenumberdeprecatedLegacy name, still accepted. Use processing_time instead.
Seconds spent.
processing_timenumberSeconds spent. The snake_case twin of processingTime, with the same value: use this name.
cancellationobjectA cancellation of an issued Duffel order.
ShowHide 12 attributes
cancellationIdstringdeprecatedLegacy name, still accepted. Use cancellation_id instead.
The ore_... id of the cancellation. Send it to confirm_cancel.
cancellation_idstringThe ore_... id of the cancellation. Send it to confirm_cancel. The snake_case twin of cancellationId, with the same value: use this name.
orderIdstringdeprecatedLegacy name, still accepted. Use order_id instead.
The supplier's order id.
order_idstringThe supplier's order id. The snake_case twin of orderId, with the same value: use this name.
statusstringpending for a quote, confirmed once confirmed.
refundobjectThe refund of a cancellation.
ShowHide 9 attributes
originalRefundCurrencystringCurrency of the airline's refund.
originalRefundAmountnumberThe airline's refund, in its currency.
refundCurrencystringCurrency of your balance.
refundAmountnumberWhat is credited to your balance.
refundTostringWhere the refund goes: FX-Port Balance.
refundToRawstringbalance.
convertedSupplierRefundAmountnumberThe airline's refund converted to your currency.
isFullBalanceRefundbooleanWhether the whole payment is refunded.
kioskCommissionRefundnumberCommission taken back.
expiresAtstringA quote is valid until this moment (one hour).
confirmedAtstringnullableWhen it was confirmed.
createdAtstringWhen the quote was created.
airlineCreditsobjectnullableCredits the airline issues instead of a refund.
liveModebooleanfalse in the sandbox.
messagestringA sentence about the result (confirm_cancel).
supplierobjectThe supplier of the order.
ShowHide 7 attributes
idstringdeprecatedLegacy name, still accepted. Use supplier_id instead.
Id of the supplier.
supplier_idstringId of the supplier. The snake_case twin of id, with the same value: use this name.
technologystringThe technology of the supplier: amadeus_aqc or duffel.
namestringdeprecatedLegacy name, still accepted. Use supplier_name instead.
Name of the supplier.
supplier_namestringName of the supplier. The snake_case twin of name, with the same value: use this name.
offerIdstringnullabledeprecatedLegacy name, still accepted. Use supplier_offer_id instead.
The supplier's own id of the offer.
supplier_offer_idstringnullableThe supplier's own id of the offer. The snake_case twin of offerId, with the same value: use this name.
agencyobjectYour agency. The id of the agency is not returned: you know it.
ShowHide 1 attribute
currencystringISO 4217 currency of your agency. Every amount of the response is in it.
exchangeRateobjectdeprecatedLegacy name, still accepted. Use exchange_rate instead.
The exchange rate used for the refund.
ShowHide 4 attributes
ratenumberUnits of the target currency for one unit of the source currency.
marginPercentnumberThe margin included in the rate.
fromCurrencystringSupplier currency.
toCurrencystringYour currency.
exchange_rateobject. The snake_case twin of exchangeRate, with the same value: use this name.
ShowHide 4 attributes
ratenumberUnits of the target currency for one unit of the source currency.
marginPercentnumberThe margin included in the rate.
fromCurrencystringSupplier currency.
toCurrencystringYour currency.
metaobjectquoteValidUntil, isConfirmed, canConfirm.
errorobjectOnly when success is false: the refusal of the supplier for cancel_quote.
ShowHide 5 attributes
messagestringThe supplier's message.
codestringThe supplier's code: a number as text for Amadeus (4926), a name for Duffel (order_not_cancellable).
typestringThe supplier's error type.
detailsarray of objectThe supplier's details, in its own format.
userMessagestringA sentence the supplier wrote for the traveler, when there is one.
errorsarray of objectOnly when success is false: the unified error list. errors[0].code is the supplier's code in lower case and errors[0].type is supplier_error.
ShowHide 7 attributes
codestringStable, machine-readable code in snake_case. Branch on this, never on the message.
typestringThe family of the error: tells you how to react.
One of authentication_error, permission_error, validation_error, not_found, conflict, payment_error, rate_limit_error, supplier_error, internal_error.
titlestringA short label of the error.
messagestringA sentence for a human: what is wrong and how to fix it. Wording can change; the code does not.
fieldstringnullableThe request field the error is about, when there is one.
detailsobjectnullableStructured extras of the error (for example available and required for an insufficient balance).
documentation_urlstringThe documentation of this error code.
Errors
| Status | Code | Example message |
|---|---|---|
| 400 | bad_request | Missing required parameter: order_id (or booking_id / pnr) |
| 400 | invalid_booking_id | `order_id` is not a valid identifier (letters, digits and - _ . : = ~ only, up to 128 characters). |
| 400 | bad_request | Cancellation quotes are currently only supported for Duffel. Received supplier_id: amadeus_aqc_dz_1 |
| 404 | booking_not_found | No booking found for 'ZZZZZZ' |
The shape of the error body depends on the endpoint. See Errors for every shape and code.