# Reply to visible participants

POST /v1/inboxes/{inbox_id}/reply-all

Source: https://cherami.to/docs/api/sending/reply-all-message



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

`POST /v1/inboxes/{inbox_id}/reply-all`

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

Replies to the source's visible participants using the [reply request and derivation rules](https://cherami.to/docs/api/sending/reply-message). Select a ready received or accepted sent message in the sending inbox with a usable RFC Message-ID. Missing, deleted, other-inbox or other-account sources return `404`; unready or unaccepted sources return `409 reply_not_ready`.

For received mail, To recipients come from Reply-To (or From) plus original To; Cc comes from original Cc. For sent mail, original To and Cc are used. Groups are flattened and addresses are deduplicated case-insensitively across To/Cc, excluding the sending inbox. Other inboxes in the account are not excluded. If only Cc participants remain, the first is promoted to To; no remaining recipient returns `409 reply_recipients_unavailable`.

Original Bcc is never reused. Reply-all from a blind recipient can reveal that recipient's own participation. Source headers are untrusted suggestions: check the recipients against your authorized assignment before sending.

Supply your response and any new attachments; original files and quoted history are not automatically included. Subject and reply-header derivation follow [reply](https://cherami.to/docs/api/sending/reply-message). Use [explicit send](https://cherami.to/docs/api/sending/send-message) with `in_reply_to` to override recipients or subject; this endpoint rejects those overrides.

HTTP success can report `rejected` or `unknown`; `accepted` means provider acceptance, not delivery. Inspect `message.status` and preserve the immediate receipt when `outcome_persisted` is false. See [sending outcomes](https://cherami.to/docs/api/sending/send-message#response-and-outcomes).

### Recover a helper send [#recover-a-helper-send]

Retain the operation, inbox, exact payload, key and first request time. Recover an uncertain result with those same inputs within 24 hours; never switch operations or generate a new key to resolve uncertainty. A replay retrieves the reserved attempt without resubmitting, even if its source was deleted. Follow the shared [helper recovery contract](https://cherami.to/docs/api/sending/reply-message#recover-a-helper-send) for conflicts, deleted results and expiry.

## Parameters [#parameters]

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

## Request body [#request-body]

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

### Schema: ReplyInput [#schema-replyinput]

| Field             | Required | Type                                                        | Meaning and constraints                                                                                                                                                              |
| ----------------- | -------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `message_id`      | Yes      | string                                                      | Received or accepted sent resource ID in this inbox. The source must have usable reply headers. `pattern`: `^[a-f0-9-]{36}$`                                                         |
| `text`            | Yes      | string                                                      | Nonblank reply text; history is not automatically quoted.                                                                                                                            |
| `html`            | No       | string                                                      | HTML alternative. Untrusted content, not sanitized markup.                                                                                                                           |
| `attachments`     | No       | array of [AttachmentInput](#schema-attachmentinput) or null | Omitted or null means no attachments; an empty array also clears draft attachments.                                                                                                  |
| `labels`          | No       | array of [Label](#schema-label)                             | Trimmed, deduplicated and case-sensitive. Order is not significant. `maxItems`: `32`                                                                                                 |
| `idempotency_key` | No       | string                                                      | Retain a unique key, exact payload and first request time for this intended operation. Account-scoped protection lasts 24 hours without renewal. `pattern`: `^[A-Za-z0-9_-]{1,128}$` |

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
{
  "message_id": "22222222-2222-4222-8222-222222222222",
  "text": "Thanks for the notes.",
  "idempotency_key": "RETAIN_A_UNIQUE_SEND_KEY"
}
```

```sh
curl --silent --show-error --include --request POST \
  "https://cherami.to/v1/inboxes/INBOX_ID/reply-all" \
  --header "Authorization: Bearer $CHERAMI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data-binary @request.json
```

## Responses [#responses]

### HTTP 200 [#http-200]

Matching replay: current resource or saved attempt, without another allocation or provider submission.

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `Location`: Relative URL of the resulting resource.

Content type: `application/json`.

All of these schemas apply.

### Part 1 [#part-1]

[SendReceipt](#schema-sendreceipt)

### Part 2 [#part-2]

| Field                    | Required | Type   | Meaning and constraints                                                                                                              |
| ------------------------ | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `replayed`               | Yes      | `true` |                                                                                                                                      |
| `idempotency_expires_at` | Yes      | string | UTC service instant with milliseconds and Z suffix. `format`: `date-time` `pattern`: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$` |

```json
{
  "limited": false,
  "message": {
    "id": "33333333-3333-4333-8333-333333333333",
    "inbox_id": "11111111-1111-4111-8111-111111111111",
    "created_at": "2026-10-01T00:00:00.000Z",
    "recipient_count": 1,
    "status": "unknown",
    "provider_message_id": null,
    "error_code": null,
    "thread_id": "44444444-4444-4444-8444-444444444444",
    "in_reply_to": null,
    "labels": []
  },
  "outcome_persisted": true,
  "replayed": true,
  "idempotency_expires_at": "2026-10-02T00:00:00.000Z"
}
```

### HTTP 201 [#http-201]

Successful operation; inspect resource state and outcome fields.

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `Location`: Relative URL of the resulting resource.

Content type: `application/json`.

All of these schemas apply.

### Part 1 [#part-1-1]

[SendReceipt](#schema-sendreceipt)

### Part 2 [#part-2-1]

| Field      | Required | Type    | Meaning and constraints |
| ---------- | -------- | ------- | ----------------------- |
| `replayed` | No       | `false` |                         |

### HTTP 400 [#http-400]

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

`invalid_message`: Correct the send fields, recipients, reply ID, or attachments using the message's guidance.

`invalid_name`: Correct the inbox, sender or recipient display name using the returned guidance.

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

`invalid_idempotency_key`: Use 1–128 ASCII letters, digits, hyphens or underscores.

* `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 403 [#http-403]

`operation_not_allowed`: This account cannot send mail, delete mail, or delete inboxes. Contact support if unexpected.

`recipient_not_allowed`: The inbox’s sending rules block one or more recipients. Nothing was submitted or charged. Use allowed recipients or ask the human to review [Sending rules](https://cherami.to/account/sending-rules); do not bypass them through another inbox.

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

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 409 [#http-409]

`reply_not_ready`: A received reply or forward source must be ready; a sent source must have confirmed provider acceptance.

`reply_headers_unavailable`: The target has no usable RFC Message-ID. Send a new message without `in_reply_to`.

`idempotency_conflict`: The key belongs to different input. Recover with the original inbox and payload, not a replacement key.

`idempotency_result_unavailable`: The key was used but its inbox, draft or sent copy is unavailable. No replacement was created or submitted; do not bypass protection with a new key.

`reply_recipients_unavailable`: No other visible reply recipients remain after self-exclusion. Use explicit send with human-authorized recipients.

* `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.

`message_too_large`: Reduce message content and attachments. Passing local checks does not guarantee generated MIME fits the provider 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 429 [#http-429]

`outbound_limit_reached`: Read `quota`, `reason` and `sufficient_capacity_at`. Waiting cannot fix `message_exceeds_allowance`; see [sending recovery](https://cherami.to/docs/api/sending/get-outbound-quota).

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `Retry-After`: Delay in seconds when supplied. Quota uses sufficient\_capacity\_at; absent when waiting cannot make the message fit.

Content type: `application/json`.

[QuotaError](#schema-quotaerror)

### HTTP 503 [#http-503]

`content_unavailable`: Expected stored content is unavailable. Retry the read later.

`outbound_unavailable`: Outbound operation failed and a send's outcome may be unknown. Recover using the original key and unchanged payload within its window, or inspect sent messages.

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

Content type: `application/json`.

[Error](#schema-error)

## Schema: SendReceipt [#schema-sendreceipt]

Inspect message.status even on HTTP 201. accepted is provider acceptance, not delivery. Preserve a known outcome when outcome\_persisted is false; later reads may lag. Keyed receipts add replayed and expiry. Draft-association recovery adds replayed without requiring an expiry.

| Field                    | Required | Type                                 | Meaning and constraints                                                                                                              |
| ------------------------ | -------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `limited`                | Yes      | `false`                              |                                                                                                                                      |
| `message`                | Yes      | [SentMetadata](#schema-sentmetadata) |                                                                                                                                      |
| `outcome_persisted`      | Yes      | boolean                              |                                                                                                                                      |
| `replayed`               | No       | boolean                              |                                                                                                                                      |
| `idempotency_expires_at` | No       | string                               | UTC service instant with milliseconds and Z suffix. `format`: `date-time` `pattern`: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$` |

## Schema: SentMetadata [#schema-sentmetadata]

| Field                 | Required | Type                                        | Meaning and constraints                                                                                                              |
| --------------------- | -------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                  | Yes      | string                                      | Cherami resource ID, distinct from the RFC Message-ID. Use the returned value.                                                       |
| `inbox_id`            | Yes      | string                                      | Cherami resource ID, distinct from the RFC Message-ID. Use the returned value.                                                       |
| `created_at`          | Yes      | string                                      | UTC service instant with milliseconds and Z suffix. `format`: `date-time` `pattern`: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$` |
| `recipient_count`     | Yes      | integer                                     | `minimum`: `0`                                                                                                                       |
| `status`              | Yes      | `"accepted"` or `"rejected"` or `"unknown"` |                                                                                                                                      |
| `provider_message_id` | Yes      | string or null                              |                                                                                                                                      |
| `error_code`          | Yes      | string or null                              |                                                                                                                                      |
| `thread_id`           | Yes      | string or null                              |                                                                                                                                      |
| `in_reply_to`         | Yes      | string or null                              |                                                                                                                                      |
| `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: QuotaError [#schema-quotaerror]

| Field                    | Required | Type                                                      | Meaning and constraints |
| ------------------------ | -------- | --------------------------------------------------------- | ----------------------- |
| `error`                  | Yes      | object                                                    |                         |
| `quota`                  | Yes      | [Quota](#schema-quota)                                    |                         |
| `requested_recipients`   | Yes      | integer                                                   | `minimum`: `0`          |
| `reason`                 | Yes      | `"temporary_exhaustion"` or `"message_exceeds_allowance"` |                         |
| `sufficient_capacity_at` | Yes      | string or null                                            |                         |
| `guidance`               | Yes      | string                                                    |                         |

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

| Field     | Required | Type                       | Meaning and constraints |
| --------- | -------- | -------------------------- | ----------------------- |
| `code`    | Yes      | `"outbound_limit_reached"` |                         |
| `message` | Yes      | string                     |                         |

## Schema: Quota [#schema-quota]

| Field                  | Required | Type                     | Meaning and constraints |
| ---------------------- | -------- | ------------------------ | ----------------------- |
| `allowance`            | Yes      | integer                  | `minimum`: `0`          |
| `used`                 | Yes      | integer                  | `minimum`: `0`          |
| `remaining`            | Yes      | integer                  | `minimum`: `0`          |
| `next_capacity_at`     | Yes      | string or null           |                         |
| `next_capacity_amount` | Yes      | integer                  | `minimum`: `0`          |
| `window_hours`         | Yes      | `24`                     |                         |
| `unit`                 | Yes      | `"recipient_deliveries"` |                         |
| `increase_request`     | Yes      | string                   |                         |
| `policy_url`           | Yes      | string                   |                         |

## Schema: AttachmentInput [#schema-attachmentinput]

| Field      | Required | Type   | Meaning and constraints                                                                                                                                                           |
| ---------- | -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `filename` | Yes      | string | Nonempty, no control characters, slash or backslash. At most 255 UTF-8 bytes. `minLength`: `1` `x-max-utf8-bytes`: `255`                                                          |
| `type`     | Yes      | string | MIME type without parameters. `maxLength`: `127` `pattern`: `^[A-Za-z0-9!#$&^_.+-]+/[A-Za-z0-9!#$&^_.+-]+$`                                                                       |
| `content`  | Yes      | string | Padded base64 original bytes, no whitespace; encoded length must be a multiple of four. Empty files are accepted. `contentEncoding`: `base64` `pattern`: `^[A-Za-z0-9+/]*={0,2}$` |

Unknown fields are rejected.

## 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)
