# Label a received message

PATCH /v1/messages/{message_id}

Source: https://cherami.to/docs/api/labels/update-message-labels



{/* Generated from apps/web/openapi. Edit the contract, not this file. */}

`PATCH /v1/messages/{message_id}`

Requires a [Claim-issued API key](https://cherami.to/docs/api#authentication): `Authorization: Bearer YOUR_CREDENTIAL`.

Adds or removes labels on a received message. Use `Content-Type: application/json` with a body up to 20 KiB.

At least one array must contain a label. Unknown fields are rejected. Duplicate names within an array are ignored. A name cannot appear in both arrays after trimming.

Names must contain 1–128 UTF-8 bytes after trimming surrounding whitespace, with no control characters or malformed Unicode. Case is preserved: `Receipts` and `receipts` are different tags. Labels are a set; do not rely on their order.

A successful update returns `200` with the message ID and resulting labels. Additions and removals apply together without replacing unrelated labels. Repeating the same update does not duplicate labels. Concurrent changes to different labels are preserved; opposite changes to the same label follow write order. Labels are not a work-claiming lock.

Invalid changes return `400 invalid_labels`. Missing, deleted, or other-account messages return `404`. Label updates do not require sending or deletion permission and consume no sending allowance.

## Parameters [#parameters]

| Parameter    | Location | Required | Type   | Meaning                                        |
| ------------ | -------- | -------- | ------ | ---------------------------------------------- |
| `message_id` | path     | Yes      | string | Owned Cherami resource ID returned by the API. |

## Request body [#request-body]

JSON object. Total UTF-8 request body limit: 20480 bytes.

### Schema: LabelChange [#schema-labelchange]

At least one array must contain a label. A normalized label cannot occur in both arrays.

| Field           | Required | Type                            | Meaning and constraints                                                              |
| --------------- | -------- | ------------------------------- | ------------------------------------------------------------------------------------ |
| `add_labels`    | No       | array of [Label](#schema-label) | Trimmed, deduplicated and case-sensitive. Order is not significant. `maxItems`: `32` |
| `remove_labels` | No       | array of [Label](#schema-label) | Trimmed, deduplicated and case-sensitive. Order is not significant. `maxItems`: `32` |

Unknown fields are rejected.

## curl example [#curl-example]

Replace resource-ID placeholders with returned IDs. Supply `CHERAMI_API_KEY` through your private shell environment.

Save the intended payload as a private `request.json` file and replace illustrative values. For an uncertain response, follow the [operation-specific recovery rules](https://cherami.to/docs/api/errors#retry-by-operation).

```json
{
  "add_labels": [
    "handled"
  ],
  "remove_labels": [
    "needs-review"
  ]
}
```

```sh
curl --silent --show-error --include --request PATCH \
  "https://cherami.to/v1/messages/MESSAGE_ID" \
  --header "Authorization: Bearer $CHERAMI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data-binary @request.json
```

## Responses [#responses]

### HTTP 200 [#http-200]

Successful operation; inspect resource state and outcome fields.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[LabelResult](#schema-labelresult)

```json
{
  "id": "11111111-1111-4111-8111-111111111111",
  "labels": []
}
```

### HTTP 400 [#http-400]

`invalid_json`: Send a valid UTF-8 JSON object, not an array or scalar.

`invalid_labels`: Correct label names, changes, filter groups, or discovery prefix.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 401 [#http-401]

`unauthorized`: Provide a valid bearer credential. Use [human-approved recovery](https://cherami.to/docs/guides/recovery) if access is lost.

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `WWW-Authenticate`: `"Bearer"`

Content type: `application/json`.

[Error](#schema-error)

### HTTP 404 [#http-404]

`not_found`: Resource is absent or inaccessible to this account. Reply targets must be in the sending inbox.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 413 [#http-413]

`body_too_large`: Reduce the JSON request to the endpoint's body limit.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 415 [#http-415]

`unsupported_media_type`: Send `Content-Type: application/json`.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 500 [#http-500]

`internal_error`: Operation failed; a write may already have happened. Follow the operation-specific recovery below.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

## Schema: LabelResult [#schema-labelresult]

| Field    | Required | Type            | Meaning and constraints                                                        |
| -------- | -------- | --------------- | ------------------------------------------------------------------------------ |
| `id`     | Yes      | string          | Cherami resource ID, distinct from the RFC Message-ID. Use the returned value. |
| `labels` | Yes      | array of string |                                                                                |

## Schema: Error [#schema-error]

| Field   | Required | Type   | Meaning and constraints |
| ------- | -------- | ------ | ----------------------- |
| `error` | Yes      | object |                         |

### `error` fields [#error-fields]

| Field     | Required | Type   | Meaning and constraints                                                                       |
| --------- | -------- | ------ | --------------------------------------------------------------------------------------------- |
| `code`    | Yes      | string | Programmatic error code. Handle unrecognized codes by status and operation-specific recovery. |
| `message` | Yes      | string | Human-readable context, not a stable string to match.                                         |

## Schema: Label [#schema-label]

1–128 UTF-8 bytes after trimming. Well-formed Unicode without control characters; case-sensitive.

string. `x-max-utf8-bytes`: `128`

[HTTP conventions, errors and pagination](https://cherami.to/docs/api/errors) · [Download OpenAPI 3.1](https://cherami.to/openapi.json)
