---
title: "Cancel an order (synchronous)"
method: POST
path: "/api/v1/orders/{id}/cancel"
tags: ["orders"]
---

# Cancel an order (synchronous)

`POST /api/v1/orders/{id}/cancel`

Cancels an order as a CANCELLED transition validated by the order state machine version pinned at creation. A required free-text reason plus any free-form metadata are captured on an immutable timeline event (OrderTrackingEvent — the cancellation moment is previousStatus; the server-validated reason always wins over a same-named metadata key) and echoed back in the response metadata. The transition and the event are written in a single transaction. Orders past INVOICED have no declared edge to CANCELLED and are rejected with 422. accountCode and the actor (user or service account) come from the JWT.

## Path parameters

- `id` string, uuid, required

## Request body

- CancelOrder
  - `reason` string, required — Free-text reason for the cancellation. Recorded inside the timeline event metadata.
  - `metadata` object, nullable — Free-form cancellation context (e.g. refund_status). Merged verbatim into the timeline event; the server-validated reason always wins over a same-named key here.

## Response `200`

Order cancelled.

- CancelOrderResponse
  - `id` string, required
  - `status` string, required
  - `previous_status` string, required
  - `metadata` object, required
  - `updated_at` string, required
  - `event_id` string, required

## Other responses

- `400` — Invalid payload: missing/empty reason, reason over 500 chars, metadata is not an object, or id is not a UUID.
- `401` — Authentication is missing, malformed, expired, or refers to a session that is no longer active.
- `403` — The caller is authenticated but lacks the required permission for this action.
- `404` — Order not found in the caller account.
- `422` — The CANCELLED transition is not allowed by the order state machine from the current status.
- `500` — Unexpected server error. The response body never leaks internal details.

## Changes

- **2026-07-07** `a3b4750a505f` — 6 info
  - added the required property `event_id` to the response with the `200` status
  - added the required property `id` to the response with the `200` status
  - added the required property `metadata` to the response with the `200` status
  - added the required property `previous_status` to the response with the `200` status
  - …2 more
- **2026-07-07** `84194c31ab85` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/kruzer-corp/apis/oms-api/changes/api/v1/orders/:id/cancel/post.md)

---

[API](https://skmtc.dev/kruzer-corp/apis/oms-api.md) · [All operations](https://skmtc.dev/kruzer-corp/apis/oms-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/kruzer-corp/oms-api/revisions/38ef6e16a7a8/schema)
