# Quote the refund of an issued order

> Ask what cancelling an issued Duffel order would refund.

Endpoint: `POST /flights/cancel_quote`

Source: https://fx-port.com/docs/api/cancel-quote

`POST /api/v1/flights/cancel_quote`

Requires an API key with **Read** permission; a **Read+Write** key works too.

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

## Request

### Body

Required, JSON.

- `order_id` (string, optional): The 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_id` (string, optional): Another name of `order_id`: the PNR.
- `pnr` (string, optional): Another name of `order_id`: the airline record locator.
- `supplier_id` (string, optional): Default `duffel_1`. A value that does not start with `duffel` is `400`.
- `agency_id` (string, optional): 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.
- `orderId` (string, deprecated, optional): Legacy name: use `order_id`. The previous spelling of `order_id`: The supplier's order id (`ord_...`).
- `bookingId` (string, deprecated, optional): Legacy name: use `booking_id`. The previous spelling of `booking_id`: Another name of `order_id`: the PNR.
- `supplierId` (string, deprecated, optional): Legacy name: use `supplier_id`. The previous spelling of `supplier_id`: Default `duffel_1`.
- `agencyId` (string, deprecated, optional): Legacy name: use `agency_id`. The previous spelling of `agency_id`: Not needed: the agency of a call is always the one of your API key.

### Example request

```bash
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"
}'
```

## Response

### 200: The pending cancellation and its refund. Show the amount to your customer, then confirm with `cancellation.cancellationId`. `success: false` with `error` when the supplier refuses.

- `environment` (string): 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_id` (string): The id of the request, also in the `X-Request-Id` header.
- `warnings` (array of object): Present only when the request used a previous spelling of a field or something the endpoint ignored.
  - `code` (string): What the warning is about. One of `deprecated_field`, `ignored_field`, `coerced_value`, `deprecated_value`, `deprecated_endpoint`.
  - `field` (string): The request field the warning is about.
  - `replacement` (string): The name to use instead, for `deprecated_*` warnings.
  - `message` (string): A sentence that says what happened and what to do.
  - `documentation_url` (string): Where the naming rules are explained.
- `success` (boolean): `true` when the quote was created.
- `requestId` (string, deprecated): Legacy name: use `request_id`. The id of this request, 8 characters, for support.
- `orderId` (string, deprecated): Legacy name: use `order_id`. The supplier's order id.
- `order_id` (string): The supplier's order id. The snake_case twin of `orderId`, with the same value: use this name.
- `processingTime` (number, deprecated): Legacy name: use `processing_time`. Seconds spent.
- `processing_time` (number): Seconds spent. The snake_case twin of `processingTime`, with the same value: use this name.
- `cancellation` (object): A cancellation of an issued Duffel order.
  - `cancellationId` (string, deprecated): Legacy name: use `cancellation_id`. The `ore_...` id of the cancellation. Send it to `confirm_cancel`.
  - `cancellation_id` (string): The `ore_...` id of the cancellation. Send it to `confirm_cancel`. The snake_case twin of `cancellationId`, with the same value: use this name.
  - `orderId` (string, deprecated): Legacy name: use `order_id`. The supplier's order id.
  - `order_id` (string): The supplier's order id. The snake_case twin of `orderId`, with the same value: use this name.
  - `status` (string): `pending` for a quote, `confirmed` once confirmed.
  - `refund` (object): The refund of a cancellation.
    - `originalRefundCurrency` (string): Currency of the airline's refund.
    - `originalRefundAmount` (number): The airline's refund, in its currency.
    - `refundCurrency` (string): Currency of your balance.
    - `refundAmount` (number): What is credited to your balance.
    - `refundTo` (string): Where the refund goes: `FX-Port Balance`.
    - `refundToRaw` (string): `balance`.
    - `convertedSupplierRefundAmount` (number): The airline's refund converted to your currency.
    - `isFullBalanceRefund` (boolean): Whether the whole payment is refunded.
    - `kioskCommissionRefund` (number): Commission taken back.
  - `expiresAt` (string): A quote is valid until this moment (one hour).
  - `confirmedAt` (string, nullable): When it was confirmed.
  - `createdAt` (string): When the quote was created.
  - `airlineCredits` (object, nullable): Credits the airline issues instead of a refund.
  - `liveMode` (boolean): `false` in the sandbox.
  - `message` (string): A sentence about the result (`confirm_cancel`).
- `supplier` (object): The supplier of the order.
  - `id` (string, deprecated): Legacy name: use `supplier_id`. Id of the supplier.
  - `supplier_id` (string): Id of the supplier. The snake_case twin of `id`, with the same value: use this name.
  - `technology` (string): The technology of the supplier: `amadeus_aqc` or `duffel`.
  - `name` (string, deprecated): Legacy name: use `supplier_name`. Name of the supplier.
  - `supplier_name` (string): Name of the supplier. The snake_case twin of `name`, with the same value: use this name.
  - `offerId` (string, nullable, deprecated): Legacy name: use `supplier_offer_id`. The supplier's own id of the offer.
  - `supplier_offer_id` (string, nullable): The supplier's own id of the offer. The snake_case twin of `offerId`, with the same value: use this name.
- `agency` (object): Your agency. The id of the agency is not returned: you know it.
  - `currency` (string): ISO 4217 currency of your agency. Every amount of the response is in it.
- `exchangeRate` (object, deprecated): Legacy name: use `exchange_rate`. The exchange rate used for the refund.
  - `rate` (number): Units of the target currency for one unit of the source currency.
  - `marginPercent` (number): The margin included in the rate.
  - `fromCurrency` (string): Supplier currency.
  - `toCurrency` (string): Your currency.
- `exchange_rate` (object): . The snake_case twin of `exchangeRate`, with the same value: use this name.
  - `rate` (number): Units of the target currency for one unit of the source currency.
  - `marginPercent` (number): The margin included in the rate.
  - `fromCurrency` (string): Supplier currency.
  - `toCurrency` (string): Your currency.
- `meta` (object): `quoteValidUntil`, `isConfirmed`, `canConfirm`.
- `error` (object): Only when `success` is `false`: the refusal of the supplier for `cancel_quote`.
  - `message` (string): The supplier's message.
  - `code` (string): The supplier's code: a number as text for Amadeus (`4926`), a name for Duffel (`order_not_cancellable`).
  - `type` (string): The supplier's error type.
  - `details` (array of object): The supplier's details, in its own format.
  - `userMessage` (string): A sentence the supplier wrote for the traveler, when there is one.
- `errors` (array 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`.
  - `code` (string): Stable, machine-readable code in snake_case. Branch on this, never on the message.
  - `type` (string): 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`.
  - `title` (string): A short label of the error.
  - `message` (string): A sentence for a human: what is wrong and how to fix it. Wording can change; the code does not.
  - `field` (string, nullable): The request field the error is about, when there is one.
  - `details` (object, nullable): Structured extras of the error (for example `available` and `required` for an insufficient balance).
  - `documentation_url` (string): The documentation of this error code.

```json
{
  "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
  }
}
```

## 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' |

See [Errors](https://fx-port.com/docs/errors.md) for every code and how to react.

## Related guides

- [Quote a cancellation](https://fx-port.com/docs/flights/cancel-quote.md)
- [Confirm a cancellation](https://fx-port.com/docs/flights/confirm-cancel.md)
- [Post-booking operations](https://fx-port.com/docs/flights/post-booking.md)
