# PUT /v1/orders/{orderId}/labels

**Service:** Orders  
**Operation:** `OrderService_SetOrderLabels`

The list you send becomes the order's complete label set: labels not listed are removed, and an empty list removes them all. Look up label ids with ListLabels. A label id that does not exist in your company is rejected with HTTP 404 (not_found) and nothing is changed.

## Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orderId` | path | string | yes | The id of the order, as returned by CreateOrder. |

## Request body

`SetOrderLabelsBody` (application/json)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `labelIds` | string[] | no | The order's desired complete label set. An empty list removes every label. Duplicate ids are rejected. |
| `fields` | string | no | Comma-separated response fields to include, using camelCase JSON names (e.g. `orderId,total.amountMicros`). Dot paths reach into nested objects and map transparently across arrays. Paths are relative to the resource, not the response envelope; envelope keys are always preserved. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Unknown names are silently ignored. Takes precedence over `excludeFields` when both are provided. |
| `excludeFields` | string | no | Comma-separated response fields to exclude, using camelCase JSON names. Dot paths and array-transparency work the same as `fields`. Paths are relative to the resource, not the response envelope. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Ignored when `fields` is also provided. |

## Responses

| Status | Schema | Description |
| --- | --- | --- |
| 200 | `SetOrderLabelsResponse` | A successful response. |
| 400 | `Error` | The request was rejected because it failed validation — for example a badly formed or duplicated label id. The body is a validation-failure envelope: an overall type and message and one entry per field-level problem (each with a stable code, a message, and a param pointing at the offending field). |
| 401 | `Error` | The request is missing a valid bearer token, or the token is invalid or expired. |
| 403 | `Error` | The token is valid but does not permit this action, or the resource belongs to a company the token cannot act for. The error type is permission_denied. |
| 404 | `Error` | No order with the given id exists for the authenticated company, the order is archived (archived orders are read-only), or the document is still a quote — label it with SetQuoteLabels. Also returned when a label id does not exist in your company: nothing is changed and the order's labels are left as they were. |
| 429 | `Error` | The request was throttled (rate_limited) or exceeded a size limit (resource_exhausted). When throttled, the Retry-After header says how many seconds to wait before retrying; a resource_exhausted request will fail the same way if retried unchanged. |
| default | `Error` | Any other error. The body is the same error envelope every error uses: a short stable type identifying the kind of failure (for example "rate_limited" or "internal"), a human-readable message, and the request's idempotency key echoed back when one was supplied. |

## Returns

`SetOrderLabelsResponse`

| Field | Type | Description |
| --- | --- | --- |
| `labels` | Label[] | The order's labels after the change, oldest attachment first. |
| `labels.labelId` | string | The label's id. |
| `labels.name` | string | Display name of the label. Unique within your company. |
| `labels.colour` | string | Display colour of the label, as a hex string (for example "#FF69B4"). |

---

Source: https://developer.factory.app/reference/orders/set-order-labels · Factory Sales API v1
