# Cancel a held reservation

> Cancel a held (unpaid) reservation: it is deleted at the supplier and the PNR is released.

Endpoint: `POST /flights/cancel_order`

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

`POST /api/v1/flights/cancel_order`

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

This is not a refund and it does not apply to issued tickets.

Only Amadeus Algeria and Travelport holds can be cancelled here; a Duffel order is answered `400`. Cancel a hold you abandon: the airline can refuse a new booking for the same passenger on the same route while the old reservation is pending. A booking that is not `awaiting_payment` (it is `confirmed` or already `cancelled`) is `409 invalid_booking_status`. To get money back for an issued Duffel order use `cancel_quote` then `confirm_cancel`; void, exchange and refund of an issued Amadeus Algeria ticket are manual (see Post-booking operations).

Send one of `order_id` (preferred), `booking_id` and `pnr`. An unknown order and the order of another agency answer the same `404 not_found`.

## Request

### Body

Required, JSON.

- `order_id` (string, optional): The supplier's order id (`booking.reference` of the booking response). **Preferred**: a PNR is not unique.
- `booking_id` (string, optional): The PNR of the booking.
- `pnr` (string, optional): The airline record locator.
- `supplier_id` (string, optional): Only used when the booking has no supplier of its own.
- `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 (`booking.reference` of the booking response).
- `bookingId` (string, deprecated, optional): Legacy name: use `booking_id`. The previous spelling of `booking_id`: The PNR of the booking.
- `supplierId` (string, deprecated, optional): Legacy name: use `supplier_id`. The previous spelling of `supplier_id`: Only used when the booking has no supplier of its own.
- `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_order \
  -H "Authorization: Bearer fxp_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "order_id": "eJzTd9ePNA90dHUGAAsuAlA"
}'
```

## Response

### 200: The reservation was deleted and the booking is `cancelled`.

- `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 reservation was deleted.
- `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.
- `booking` (object): The order as the supplier knows it.
  - `reference` (string, deprecated): Legacy name: use `order_id`. The supplier's order id (`ord_...` for Duffel, a base64-like text for Amadeus; for a cancelled hold of Amadeus Algeria the PNR). Send it as `order_id` to `pay_order`, `cancel_order` and `cancel_quote`.
  - `order_id` (string): The supplier's order id (`ord_...` for Duffel, a base64-like text for Amadeus; for a cancelled hold of Amadeus Algeria the PNR). Send it as `order_id` to `pay_order`, `cancel_order` and `cancel_quote`. The snake_case twin of `reference`, with the same value: use this name.
  - `status` (string): `confirmed`, `pending` (a hold that is not paid yet), `awaiting_payment`, `cancelled`, `failed` or `partial_refund`.
  - `pnr` (string): The airline record locator. Not unique across suppliers and airlines.
  - `type` (string): `instant`: ticketed at once. `hold`: reserved, not paid. One of `instant`, `hold`.
  - `createdAt` (string): When the order was created.
  - `cancelledAt` (string, nullable): When the order was cancelled.
  - `content` (string): Who manages the order: `managed`.
  - `syncedAt` (string): When FX-Port last synchronised the order with the supplier.
  - `availableActions` (array of string): What can still be done with the order.
  - `voidableUntil` (string, nullable): ISO 8601 UTC end of the same-day void window.
  - `cancellation` (object, nullable): How the order was cancelled: `type`, `deleted`, `deletedAt`.
- `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.
- `cancellation` (object): The result of the cancellation.
  - `status` (string): `deleted`.
  - `deleted` (boolean): `true` when the reservation was deleted at the supplier.
  - `deletedAt` (string): When it was deleted.
  - `refundAmount` (number): The refund: `0` for a hold (nothing was paid).
  - `refundCurrency` (string): Currency of the refund.
  - `refundTo` (string, nullable): Where a refund goes.
  - `message` (string): A sentence about the result.
- `meta` (object): Capabilities of the order and what the supplier reports about it.
  - `supportHold` (boolean, deprecated): Legacy name: use `support_hold`. Whether the supplier can hold.
  - `support_hold` (boolean): Whether the supplier can hold. The snake_case twin of `supportHold`, with the same value: use this name.
  - `supportVoid` (boolean, deprecated): Legacy name: use `support_void`. Whether the supplier can void the ticket the same day.
  - `support_void` (boolean): Whether the supplier can void the ticket the same day. The snake_case twin of `supportVoid`, with the same value: use this name.
  - `voidDeadline` (string, nullable, deprecated): Legacy name: use `void_deadline`. End of the same-day void window.
  - `void_deadline` (string, nullable): End of the same-day void window. The snake_case twin of `voidDeadline`, with the same value: use this name.
  - `voidWindowEndsAt` (string, nullable): End of the void window, when the supplier gives it.
  - `airlineInitiatedChanges` (array of object): Schedule changes the airline made.
  - `changes` (array of object): Changes of the order.
  - `users` (array of object): Users of the order.
  - `orderMetadata` (object, nullable): Supplier-specific metadata of the order.
- `postProcessing` (object): What FX-Port did after the supplier call.
  - `bookingDbId` (string): The FX-Port id of the booking (a UUID). **The best key to store**: it is accepted as `booking_id` by `get_booking`.
  - `bucketLink` (string, nullable): Address of the PDF of the ticket, `null` until it is generated. A public link.
  - `emailSent` (boolean): Whether the confirmation e-mail went out.
  - `bookingStatusUpdated` (boolean): `cancel_order`: whether the FX-Port booking was updated.
  - `refundMethod` (string): `confirm_cancel`: where the refund went: `balance`.

```json
{
  "environment": "sandbox",
  "success": true,
  "requestId": "11487aa1",
  "orderId": "eJzTd9ePNA90dHUGAAsuAlA",
  "processingTime": 2.147,
  "booking": {
    "reference": "Y7QAEC",
    "status": "cancelled",
    "pnr": "Y7QAEC",
    "type": "hold",
    "createdAt": "2026-11-01T15:26:27.977426+00:00",
    "cancelledAt": "2026-11-01T15:26:30.748257",
    "content": "managed",
    "syncedAt": "2026-11-01T15:26:30.748257",
    "availableActions": [],
    "voidableUntil": null,
    "cancellation": {
      "type": "void",
      "deleted": true,
      "deletedAt": "2026-11-01T15:26:30.748257"
    }
  },
  "supplier": {
    "id": "amadeus_aqc_dz_1",
    "technology": "amadeus_aqc",
    "name": "Amadeus Algeria",
    "offerId": null
  },
  "agency": {
    "currency": "DZD"
  },
  "cancellation": {
    "status": "deleted",
    "deleted": true,
    "deletedAt": "2026-11-01T15:26:30.748257",
    "refundAmount": 0,
    "refundCurrency": "DZD",
    "refundTo": null,
    "message": "Reservation deleted successfully."
  },
  "meta": {
    "supportHold": true,
    "supportVoid": true,
    "voidDeadline": "2026-11-01T23:00:00Z",
    "voidWindowEndsAt": null,
    "airlineInitiatedChanges": [],
    "changes": [],
    "users": [],
    "orderMetadata": {
      "supplierStatusCode": 204,
      "supplierDeleteErrorIgnored": false,
      "supplierDeleteErrorCode": 204,
      "supplierDeleteErrorMessage": null
    }
  },
  "postProcessing": {
    "bookingStatusUpdated": 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` | Delete reservation is currently only supported for Amadeus Algeria and Travelport hold bookings. Received supplier_id: duffel_1 |
| 403 | `read_write_permission_required` | This endpoint requires an API key with read_write permission. |
| 404 | `not_found` | Booking not found for order_id: ZZZZZZ |
| 409 | `invalid_booking_status` | Booking is 'confirmed', expected awaiting_payment |
| 500 | `booking_update_failed` | Reservation was deleted at the supplier, but local booking status could not be updated. |

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

## Related guides

- [Cancel a held reservation](https://fx-port.com/docs/flights/cancel-order.md)
- [Post-booking operations](https://fx-port.com/docs/flights/post-booking.md)
