Update order status
http
PATCH /v1/orders/:id/statusMoves an order to a new status. Transitions follow a strict state machine;
illegal jumps are rejected with 422 and nothing is written.
Paid plans only
The Orders API is available on the paid plans (Duckling and Golden
Duck). On the free Egg plan, requests are rejected with
403 Forbidden and the message
"The Orders API requires a paid plan".
Request body#
| Field | Type | Required | Values |
|---|---|---|---|
status | string | Yes | new | confirmed | preparing | delivering | completed | cancelled |
State machine#
| Current status | Allowed next statuses |
|---|---|
new | confirmed, cancelled |
confirmed | preparing, cancelled |
preparing | delivering, completed, cancelled |
delivering | completed, cancelled |
completed | — (terminal) |
cancelled | — (terminal) |
Side effects on transition:
- first move to
confirmedsetsconfirmedAt; - first move to
completedsetscompletedAt; - the venue dashboard updates in real time.
Idempotent — safe to retry
Sending the order's current status again returns
200 OK with the unchanged order and writes nothing. Your
POS can retry a status update after a timeout without checking state
first.
Example#
bash
curl -X PATCH \
https://api.duck-hub.com/v1/orders/cml9x2f4a0001abcd1234efgh/status \
-H "Authorization: Bearer dk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"status": "confirmed"}'javascript
const orderId = 'cml9x2f4a0001abcd1234efgh'
const response = await fetch(
`https://api.duck-hub.com/v1/orders/${orderId}/status`,
{
method: 'PATCH',
headers: {
Authorization: 'Bearer dk_live_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: 'confirmed' }),
},
)
if (response.status === 422) {
const error = await response.json()
console.warn('Illegal transition:', error.message)
}
const updated = await response.json()Response#
200 OK:
json
{
"id": "cml9x2f4a0001abcd1234efgh",
"orderNumber": "1024",
"status": "confirmed",
"updatedAt": "2026-07-05T12:01:05.000Z"
}Errors#
422 on an illegal transition — the message names the current status and
what is allowed from it:
json
{
"statusCode": 422,
"message": "Invalid status transition: 'completed' -> 'preparing'. Allowed transitions from 'completed': none (terminal state)",
"timestamp": "2026-07-05T12:00:00.000Z",
"path": "/v1/orders/cml9x2f4a0001abcd1234efgh/status"
}400 Validation failed—statusmissing or not one of the six values401— see Authentication403— free plan (no Orders API access)404Order not found— unknown id for this venue