---
search:
  tags:
    - Orders
    - PUT
seo:
  description: >-
    Setting status to most values requires _policies.allow_status: true in the
    request body. Reference for the PUT /orders/{id} endpoint in the Bolder API
    v2.
sidebar:
  label: Update an order
  badge: PUT
title: Update an order
type: openapi-operation
---
Setting `status` to most values requires `_policies.allow_status: true`
in the request body.

### Recommended pattern for retry-safe order creation

`POST /v2/orders` has no idempotency mechanism (see its description).
The recommended way to create an order safely under retry is
**`PUT /v2/orders/{id}` with `_upsert: true` and an `external_id`**
in the body:

- If no order exists yet with that `external_id` (scoped to the
  seller resolved via `shop_id`), one is created (response status
  `201`) using the same request body fields as `POST /v2/orders`
  (`shop_id`, `contact`, `line_items`, etc). The order gets a normal
  system-generated `code` — the URL `:id` is **not** used as, or
  turned into, the order's code; a client cannot pick the public
  order code this way. `:id` can be any placeholder (e.g. the same
  `external_id` value, for readability), since matching is done by
  `external_id`, not by the URL.
- If an order already exists with that `external_id`, it's updated
  in place (response status `200`) — a retried request converges on
  the same order instead of creating a duplicate.
- Without `_upsert: true`, `PUT` to a nonexistent `:id` returns `404`
  as usual.
- `_upsert: true` without an `external_id` in the body returns `422`
  — the flag requires `external_id` so a typo in the URL `:id` alone
  can't silently create an unintended order.

This is the same `external_id` field documented on `Order` and on
`POST /v2/orders` — a collision there is rejected with `422`;
here, under `_upsert`, a "collision" is the intended match and
updates the existing order instead.

### Stock restoration on cancellation

Setting `status` to `cancelled` automatically restores/releases reserved
stock, but only when both of these hold:

- the order's `fulfillment_status` is still unsent (`queued`,
  `preparing`, or `ready` — not yet `shipped`/`delivered`), and
- stock was actually reserved for the order in the first place (line
  items on non-stock-tracked products, or without a `variant_id` at all,
  never reserved anything, so there's nothing to restore for them).

Cancelling an order that has already shipped does **not** auto-restore
stock. Restoration is independent of payment state — it isn't affected by
whether the order was paid or refunded.

`PUT /orders/{id}`

**cURL**

```bash
curl -s -X PUT \
  -H "Authorization: Bearer $BOLDER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tracking_code":"1Z9999W99999999999","courier_name":"UPS"}' \
  "https://api.onbolder.com/v2/orders/ORD-5001"
```

**Request body** (`application/json`, required)

- `_upsert` (boolean) — If \`true\`, requires \`external\_id\` in this same request body. Finds an order by \`external\_id\` (scoped to the seller); if none exists, creates one instead of returning 404 (with a system-generated \`code\`, not the URL \`:id\`). See "Recommended pattern for retry-safe order creation" above.
- `status` (string)
- `fulfillment_status` (string)
- `archived` (boolean)
- `external_id` (string) — Optional client-supplied reference, unique per seller. Can be set here if it wasn't given at create time; a colliding value is rejected with a 422.
- `tracking_code` (string)
- `courier_name` (string)
- `fulfillment_method` (string)
- `shipping_amount` (integer)
- `shipping_discount` (integer)
- `shipping_description` (string)
- `tags` (string[])
- `notify_status_change` (boolean)
- `notification_message` (string)
- `_policies` (object)

Request body example:

```json
{
  "tracking_code": "1Z9999W99999999999",
  "courier_name": "UPS",
  "fulfillment_status": "shipped"
}
```

**Responses**

- `200` — Order updated

Response example, 200:

```json
{
  "id": 5001,
  "code": "ORD-5001",
  "status": "pending",
  "fulfillment_status": "shipped",
  "tracking_code": "1Z9999W99999999999",
  "courier_name": "UPS",
  "_links": {
    "self": {
      "href": "https://api.onbolder.com/v2/orders/ORD-5001"
    }
  }
}
```
