Skip to content
FX-Port/Docs
GuidesAPI referenceChangelog
Get API keys
  • Overview
  • Error object

Search and price

  • Search flightsPOST
  • Flexible datesPOST
  • Price an offerPOST
  • Airport autocompleteGET
  • Most searched airportsGET

Book, pay and cancel

  • Book an offerPOST
  • Quote a held orderPOST
  • Pay a held orderPOST
  • Cancel a held orderPOST

After booking

  • Get a bookingPOST
  • Ticket PDFPOST
  • Ticket numberPOST
  • Quote a refundPOST
  • Confirm a cancellationPOST

ACD documents

  • Get the document statePOST
  • Upload passportsPOST

Objects

  • Flight offer
  • Flight booking

Flights ยท After booking

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.

POST/api/v1/flights/confirm_cancel

Requires an API key with Read+Write permission: a Read key is refused with read_write_permission_required.

This 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"
}'
Response200
{
  "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
  }
}
Response200
{
  "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_idstringrequired

The ore_... id of cancel_quote (cancellation.cancellationId).

order_idstring

The 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_idstring

Another name of order_id.

pnrstring

Another name of order_id.

supplier_idstring

Default duffel_1.

agency_idstring

Not 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.

cancellationIdstringdeprecated

Legacy name, still accepted. Use cancellation_id instead.

The previous spelling of cancellation_id: The ore_... id of cancel_quote (cancellation.cancellationId).

orderIdstringdeprecated

Legacy 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).

bookingIdstringdeprecated

Legacy name, still accepted. Use booking_id instead.

The previous spelling of booking_id: Another name of order_id.

supplierIdstringdeprecated

Legacy name, still accepted. Use supplier_id instead.

The previous spelling of supplier_id: Default duffel_1.

agencyIdstringdeprecated

Legacy 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.

environmentstring

The 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_idstring

The id of the request, also in the X-Request-Id header.

warningsarray of object

Present only when the request used a previous spelling of a field or something the endpoint ignored.

ShowHide 5 attributes
codestring

What the warning is about.

One of deprecated_field, ignored_field, coerced_value, deprecated_value, deprecated_endpoint.

fieldstring

The request field the warning is about.

replacementstring

The name to use instead, for deprecated_* warnings.

messagestring

A sentence that says what happened and what to do.

documentation_urlstring

Where the naming rules are explained.

successboolean

true when the cancellation was confirmed.

requestIdstringdeprecated

Legacy name, still accepted. Use request_id instead.

The id of this request, 8 characters, for support.

orderIdstringdeprecated

Legacy name, still accepted. Use order_id instead.

The supplier's order id.

order_idstring

The supplier's order id. The snake_case twin of orderId, with the same value: use this name.

cancellationIdstring

Only when success is false: the cancellation you tried to confirm.

processingTimenumberdeprecated

Legacy name, still accepted. Use processing_time instead.

Seconds spent.

processing_timenumber

Seconds spent. The snake_case twin of processingTime, with the same value: use this name.

confirmationobject

A cancellation of an issued Duffel order.

ShowHide 12 attributes
cancellationIdstringdeprecated

Legacy name, still accepted. Use cancellation_id instead.

The ore_... id of the cancellation. Send it to confirm_cancel.

cancellation_idstring

The ore_... id of the cancellation. Send it to confirm_cancel. The snake_case twin of cancellationId, with the same value: use this name.

orderIdstringdeprecated

Legacy name, still accepted. Use order_id instead.

The supplier's order id.

order_idstring

The supplier's order id. The snake_case twin of orderId, with the same value: use this name.

statusstring

pending for a quote, confirmed once confirmed.

refundobject

The refund of a cancellation.

ShowHide 9 attributes
originalRefundCurrencystring

Currency of the airline's refund.

originalRefundAmountnumber

The airline's refund, in its currency.

refundCurrencystring

Currency of your balance.

refundAmountnumber

What is credited to your balance.

refundTostring

Where the refund goes: FX-Port Balance.

refundToRawstring

balance.

convertedSupplierRefundAmountnumber

The airline's refund converted to your currency.

isFullBalanceRefundboolean

Whether the whole payment is refunded.

kioskCommissionRefundnumber

Commission taken back.

expiresAtstring

A quote is valid until this moment (one hour).

confirmedAtstringnullable

When it was confirmed.

createdAtstring

When the quote was created.

airlineCreditsobjectnullable

Credits the airline issues instead of a refund.

liveModeboolean

false in the sandbox.

messagestring

A sentence about the result (confirm_cancel).

supplierobject

The supplier of the order.

ShowHide 7 attributes
idstringdeprecated

Legacy name, still accepted. Use supplier_id instead.

Id of the supplier.

supplier_idstring

Id of the supplier. The snake_case twin of id, with the same value: use this name.

technologystring

The technology of the supplier: amadeus_aqc or duffel.

namestringdeprecated

Legacy name, still accepted. Use supplier_name instead.

Name of the supplier.

supplier_namestring

Name of the supplier. The snake_case twin of name, with the same value: use this name.

offerIdstringnullabledeprecated

Legacy name, still accepted. Use supplier_offer_id instead.

The supplier's own id of the offer.

supplier_offer_idstringnullable

The supplier's own id of the offer. The snake_case twin of offerId, with the same value: use this name.

agencyobject

Your agency. The id of the agency is not returned: you know it.

ShowHide 1 attribute
currencystring

ISO 4217 currency of your agency. Every amount of the response is in it.

exchangeRateobjectdeprecated

Legacy name, still accepted. Use exchange_rate instead.

The exchange rate used for the refund.

ShowHide 4 attributes
ratenumber

Units of the target currency for one unit of the source currency.

marginPercentnumber

The margin included in the rate.

fromCurrencystring

Supplier currency.

toCurrencystring

Your currency.

exchange_rateobject

. The snake_case twin of exchangeRate, with the same value: use this name.

ShowHide 4 attributes
ratenumber

Units of the target currency for one unit of the source currency.

marginPercentnumber

The margin included in the rate.

fromCurrencystring

Supplier currency.

toCurrencystring

Your currency.

metaobject

cancellationConfirmedAt and refundProcessing.

postProcessingobject

What FX-Port did after the supplier call.

ShowHide 5 attributes
bookingDbIdstring

The FX-Port id of the booking (a UUID). The best key to store: it is accepted as booking_id by get_booking.

bucketLinkstringnullable

Address of the PDF of the ticket, null until it is generated. A public link.

emailSentboolean

Whether the confirmation e-mail went out.

bookingStatusUpdatedboolean

cancel_order: whether the FX-Port booking was updated.

refundMethodstring

confirm_cancel: where the refund went: balance.

errorobject

Only when success is false: the refusal of the supplier for confirm_cancel.

ShowHide 5 attributes
messagestring

The supplier's message.

codestring

The supplier's code: a number as text for Amadeus (4926), a name for Duffel (order_not_cancellable).

typestring

The supplier's error type.

detailsarray of object

The supplier's details, in its own format.

userMessagestring

A sentence the supplier wrote for the traveler, when there is one.

errorsarray of object

Only 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
codestring

Stable, machine-readable code in snake_case. Branch on this, never on the message.

typestring

The 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.

titlestring

A short label of the error.

messagestring

A sentence for a human: what is wrong and how to fix it. Wording can change; the code does not.

fieldstringnullable

The request field the error is about, when there is one.

detailsobjectnullable

Structured extras of the error (for example available and required for an insufficient balance).

documentation_urlstring

The documentation of this error code.

Errors

StatusCodeExample message
400bad_requestMissing required parameter: cancellation_id
400missing_field`order_id` (or `booking_id` / `pnr`) is required together with `cancellation_id`.
400invalid_cancellation_id`cancellation_id` is not a valid identifier (letters, digits and - _ . : = ~ only, up to 128 characters).
403read_write_permission_requiredThis endpoint requires an API key with read_write permission.
404booking_not_foundNo booking found for 'ZZZZZZ'

The shape of the error body depends on the endpoint. See Errors for every shape and code.

Related guides

  • Confirm a cancellation
  • Quote a cancellation
  • Post-booking operations
PreviousQuote the refund of an issued orderNext Get the ACD document state of a booking

ยฉ 2026 FX-Port

TermsPrivacy[email protected]