Confirm the cancellation of an order
Confirm the cancellation you quoted with cancel_quote: the Duffel order is cancelled at the airline and the refund is credited to your FX-Port balance.
/api/v1/flights/confirm_cancelThis cannot be undone.
Show the amount of cancel_quote to your customer before you call this endpoint, and call it once: a second call answers already_cancelled. Send cancellation_id (the ore_... id of the quote) and order_id (or booking_id or pnr): the order id makes FX-Port check that the booking is yours and update the booking and the balance, so a call without it is 400 missing_field and nothing is cancelled. 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/confirm_cancel \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"cancellation_id": "ore_0000BC0VG9WBaFAZ83u3yy",
"order_id": "ord_0000BC0VDONwA54LrfoCkm"
}'{
"environment": "sandbox",
"success": true,
"requestId": "64666d3c",
"orderId": "ord_0000BC0VDONwA54LrfoCkm",
"processingTime": 0.245,
"confirmation": {
"cancellationId": "ore_0000BC0VG9WBaFAZ83u3yy",
"orderId": "ord_0000BC0VDONwA54LrfoCkm",
"status": "confirmed",
"refund": {
"originalRefundCurrency": "USD",
"originalRefundAmount": 76.86,
"refundCurrency": "DZD",
"refundAmount": 19215,
"refundTo": "FX-Port Balance",
"refundToRaw": "balance",
"convertedSupplierRefundAmount": 19215,
"isFullBalanceRefund": false,
"kioskCommissionRefund": 0
},
"confirmedAt": "2026-11-01T14:30:04.851325Z",
"createdAt": "2026-11-01T14:28:32.488592Z",
"airlineCredits": null,
"liveMode": false,
"message": "Order cancellation confirmed. Refund will be processed."
},
"supplier": {
"id": "duffel_1",
"technology": "duffel",
"name": "Duffel"
},
"agency": {
"currency": "DZD"
},
"exchangeRate": {
"rate": 250,
"marginPercent": 0,
"fromCurrency": "USD",
"toCurrency": "DZD"
},
"meta": {
"cancellationConfirmedAt": "2026-11-01T14:30:04.851325Z",
"refundProcessing": {
"method": "FX-Port Balance",
"estimatedDays": "Immediate",
"description": "Refund credited to your FX-Port balance"
}
},
"postProcessing": {
"refundMethod": "balance",
"emailSent": false
}
}{
"environment": "sandbox",
"requestId": "c2eb0461",
"orderId": "ord_0000BC0VDONwA54LrfoCkm",
"cancellationId": "ore_0000BC0VG9WBaFAZ83u3yy",
"processingTime": 0.126,
"error": {
"message": "This order has already been cancelled.",
"code": "already_cancelled",
"type": "invalid_state_error",
"details": [
{
"documentation_url": "https://duffel.com/docs/api/overview/response-handling",
"title": "Order already cancelled",
"type": "invalid_state_error",
"message": "This order has already been cancelled.",
"code": "already_cancelled"
}
],
"userMessage": "This order has already been cancelled."
},
"supplier": {
"id": "duffel_1",
"technology": "duffel",
"name": "Duffel"
},
"meta": {
"request_id": "c2eb0461",
"status": 200
},
"success": false,
"errors": [
{
"code": "already_cancelled",
"type": "supplier_error",
"title": "Already cancelled",
"message": "This order has already been cancelled.",
"field": null,
"details": {
"supplier_type": "invalid_state_error",
"supplier_details": [
{
"documentation_url": "https://duffel.com/docs/api/overview/response-handling",
"title": "Order already cancelled",
"type": "invalid_state_error",
"message": "This order has already been cancelled.",
"code": "already_cancelled"
}
]
},
"documentation_url": "https://fx-port.com/docs/errors#already_cancelled"
}
],
"request_id": "c2eb0461"
}Request
Body
Required, JSON.
cancellation_idstringrequiredThe ore_... id of cancel_quote (cancellation.cancellationId).
order_idstringThe supplier's order id of the booking (booking_id and pnr are accepted as other names). Required: it makes FX-Port check that the booking is yours and update it.
booking_idstringAnother name of order_id.
pnrstringAnother name of order_id.
supplier_idstringDefault duffel_1.
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.
cancellationIdstringdeprecatedLegacy name, still accepted. Use cancellation_id instead.
The previous spelling of cancellation_id: The ore_... id of cancel_quote (cancellation.cancellationId).
orderIdstringdeprecatedLegacy name, still accepted. Use order_id instead.
The previous spelling of order_id: The supplier's order id of the booking (booking_id and pnr are accepted as other names).
bookingIdstringdeprecatedLegacy name, still accepted. Use booking_id instead.
The previous spelling of booking_id: Another name of order_id.
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 order is cancelled and the refund is on its way to your balance. 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 cancellation was confirmed.
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.
cancellationIdstringOnly when success is false: the cancellation you tried to confirm.
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.
confirmationobjectA 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.
metaobjectcancellationConfirmedAt and refundProcessing.
postProcessingobjectWhat FX-Port did after the supplier call.
ShowHide 5 attributes
bookingDbIdstringThe FX-Port id of the booking (a UUID). The best key to store: it is accepted as booking_id by get_booking.
bucketLinkstringnullableAddress of the PDF of the ticket, null until it is generated. A public link.
emailSentbooleanWhether the confirmation e-mail went out.
bookingStatusUpdatedbooleancancel_order: whether the FX-Port booking was updated.
refundMethodstringconfirm_cancel: where the refund went: balance.
errorobjectOnly when success is false: the refusal of the supplier for confirm_cancel.
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: cancellation_id |
| 400 | missing_field | `order_id` (or `booking_id` / `pnr`) is required together with `cancellation_id`. |
| 400 | invalid_cancellation_id | `cancellation_id` is not a valid identifier (letters, digits and - _ . : = ~ only, up to 128 characters). |
| 403 | read_write_permission_required | This endpoint requires an API key with read_write permission. |
| 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.