# POST /api/v1/inboxes/:id/messages/:msgId/reply

Auth: Bearer

HTML: https://cooperemail.com/docs/reference/reply

## Summary

Reply on the same thread. Inbound mail goes to Reply-To or From. Mail you sent goes to the original To. Subject is Re: unless it already starts with re:. In-Reply-To and References use the original Message-ID (the last 20 ids). One of text or html is required (400 missing_body). reply_all adds the other recipients, merges cc, drops this inbox, and dedupes (400 missing_to if nobody remains). Allow and block lists are checked; 403 recipient_blocked sends nothing. client_id retries return the original message with idempotent true and do not send again. Idempotency-Key works the same way as on send (example: Idempotency-Key: reply-001). A replay returns HTTP 200 with idempotent true and Idempotent-Replayed: true. The message id in the path is part of the request, so the same key on a different message is 409 idempotency_key_conflict. Unknown messages return 404 message_not_found. A paused inbox returns 403 inbox_paused.

## Request

```json
{
  "text": "Tuesday still works.",
  "cc": [
    "copy@example.com"
  ],
  "client_id": "reply-001"
}
```

## Response

HTTP 200. Sample values illustrate the schema.

```json
{
  "id": "inb_example",
  "inbox_id": "inb_example",
  "thread_id": "thr_example",
  "direction": "inbound",
  "from": "ada@example.com",
  "to": [
    "string"
  ],
  "subject": "Hello",
  "text": "Tuesday works.",
  "html": "string",
  "extracted_text": "string",
  "extracted_html": "string",
  "preview": "string",
  "delivery_events": [
    {
      "type": "string",
      "recipient": "string",
      "created_at": "2026-10-18T12:00:00.000Z",
      "detail": "string"
    }
  ],
  "cc": [
    "string"
  ],
  "bcc": [
    "string"
  ],
  "reply_to": "string",
  "in_reply_to": "string",
  "references": [
    "string"
  ],
  "labels": [
    "string"
  ],
  "auth": {
    "spf": "string",
    "dkim": "string",
    "dmarc": "string"
  },
  "safety": {
    "score": 0,
    "verdict": "clean",
    "signals": [
      {
        "type": "string",
        "detail": "string"
      }
    ],
    "mode": "off",
    "reason": "string"
  },
  "provider": "string",
  "client_id": "inb_example",
  "idempotent": true
}
```

## Errors

- HTTP 400 missing_body
- HTTP 400 missing_to
- HTTP 403 recipient_blocked
- HTTP 409 idempotency_key_conflict
- HTTP 404 message_not_found
- HTTP 403 inbox_paused

The live `message` is the sentence for that code. Branch on `code`.

```json
{
  "error": {
    "type": "invalid_request",
    "code": "missing_body",
    "docs_url": "https://cooperemail.com/docs#missing_body"
  }
}
```

## Idempotency

Idempotency-Key is 1 to 256 characters of letters, digits, and - . _ ~. The same key and the same request within 24 hours returns the original response with HTTP 200 and Idempotent-Replayed: true. A different request is HTTP 409 idempotency_key_conflict. A second call while the first is running is HTTP 409 idempotency_request_in_progress. An empty or invalid key is HTTP 400 invalid_idempotency_key. client_id is checked first when both are set.
