> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chataigne.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Status management

> Apply idempotent, bidirectional order status transitions from a connected POS.

A connected POS updates a Chataigne order with:

```http theme={null}
PUT /v1/locations/{location_id}/orders/{order_id}/status
Idempotency-Key: pos-transition-0189
Content-Type: application/json

{
  "status": "accepted",
  "reason": "Accepted by the kitchen"
}
```

`Idempotency-Key` is required. Reusing a key with the same body returns the original response; reusing it with another body is rejected. Generate a durable key for each intended transition and persist it until the request has completed.

## Canonical status lifecycle

The current canonical values are:

* `received`
* `accepted`
* `in_preparation`
* `awaiting_shipment`
* `awaiting_collection`
* `in_delivery`
* `completed`
* `rejected`
* `cancelled`
* `delivery_failed`

`received` is created by Chataigne and cannot be submitted as a target. Completed, rejected, cancelled, and failed delivery states are terminal. `awaiting_collection` is not valid for delivery orders; `awaiting_shipment` is not valid for collection orders. A transition outside the allowed lifecycle is rejected.

<Info>
  Submitting the order's current status is a successful no-op. It does not increment
  `status_version` or emit a duplicate status event.
</Info>

## Bidirectional updates

Status changes can originate from the POS, Chataigne operators, scheduled automation, the ordering flow, or a delivery provider. Every accepted transition passes through the same state machine, becomes the canonical order status, and increments `status_version`.

Use `status_version` to reject stale webhook updates in your system. Webhook delivery is at least once and can occur out of order after retries. A payload with a version lower than or equal to the highest version already processed for that order can be acknowledged and ignored.

When a POS integration or API receiver submits a status, Chataigne applies the first valid transition that reaches the database. A concurrent writer that observed the previous version receives `409 order_status_conflict`; it must retrieve the current order before deciding whether to retry. Accepted `order.status.updated` events are delivered to the primary receiver and subscribed observers, including when the source is a synchronous POS.

## Conflict handling

| Response | Meaning                                                    | Action                                                        |
| -------- | ---------------------------------------------------------- | ------------------------------------------------------------- |
| `200`    | Applied, replayed, or already at that status               | Store the returned order and version                          |
| `400`    | Malformed body or invalid lifecycle transition             | Correct the target status                                     |
| `404`    | Order is outside the authorized location or does not exist | Reconcile the order identifier and scope                      |
| `409`    | Idempotency conflict or concurrent status change           | Retrieve the order and decide from its current status/version |

A `2xx` webhook response only acknowledges receipt. If your POS cannot accept an order, acknowledge the webhook, then submit `rejected` through the status endpoint with a durable idempotency key and an optional reason.
