---
title: "A recipient replied"
method: POST
path: "email.received"
tags: ["Webhooks"]
---

# A recipient replied

`POST email.received` (webhook)

Posted to the subscriptions to `email.received` when a recipient replies on `reply.<your domain>` — only for a domain where reply receiving is turned on (the domain's screen in the app, one MX record). The whole reply is in the body except attachments, which come as signed download links valid for 7 days. Replies over 150 KB are refused by Amazon and never arrive. Signed and retried like every event. The test event (`POST /api/v1/webhooks/{id}/test`) can arrive under this `type` too, with `data: { test: true, message }` and none of the fields of the real event: check `data.test` first.

## Headers

- `Mailcheer-Signature` string, required
- `Mailcheer-Timestamp` string, required
- `Mailcheer-Event-Id` string, required
- `Mailcheer-Event-Type` string, required
- `Mailcheer-Delivery-Id` string, required
- `Mailcheer-Attempt` string, required

## Payload

- union
  - EmailReceivedEvent: The body of an `email.received` call. A test event carries a different `data`: see `TestEvent`.
    - `id` string, required: `evt_…` — the same on every attempt and every replay of the event: the deduplication key.
    - `type` 'email.received', required
    - `created_at` string, date-time, required: When the event occurred (not when it was delivered).
    - `data` object, required
      - `reply_id` string, required: The reply's id in Mailcheer.
      - `email` string, required: The address of the person who replied — the same as `from`, so that `data.email` names the contact in every `email.*` event.
      - `from` string, required: The sender of the reply.
      - `from_name` string: Their display name, when they have one.
      - `to` string[], required: The `reply.<domain>` addresses that received the reply.
      - `cc` string[]: The visible copy addresses, when there are any.
      - `subject` string, required: The subject, decoded.
      - `text` string: The plain-text version, as is (including the quote of your email), when the reply has one.
      - `html` string: The HTML version, as is, when the reply has one. It comes from a stranger: never display it without sanitizing it.
      - `received_at` string, date-time, required: When Amazon received the reply.
      - `headers` object, required: `message_id`, `in_reply_to`, `references` (array), `date`, `auto_submitted` — `null` when absent.
      - `attachments` object[], required: One entry per attachment: `filename`, `content_type`, `size` (bytes), `content_id` (inline image), `url` — a signed download link that needs no key — and `url_expires_at` (7 days). Always present, possibly empty.
      - `message_id` string: When the original email is found: the `id` of the Mailcheer email being replied to, as in the other `email.*` events. Found through the reply address, or through `In-Reply-To` and `References` — never guessed.
      - `source` 'api' | 'campaign' | 'automation': With `message_id`: where the original email came from.
      - `campaign_id` string: Reply to a campaign email: the campaign.
      - `automation_id` string: Reply to an automation email: the automation.
      - `tags` object: Reply to an API email that carried `tags`: those tags, to file the reply on your side.
      - `spam` boolean, required: `true` when Amazon's filter judges the reply to be spam.
      - `automatic` boolean, required: `true` for an automatic reply: out of office, acknowledgement, delivery report (`Auto-Submitted`, `Precedence`…).
      - `authentication` object: `spf`, `dkim`, `dmarc`: Amazon's verdict on the sender (`PASS`, `FAIL`, `GRAY`…).
  - TestEvent: The body of the test event (`POST /api/v1/webhooks/{id}/test`, or Settings → API). Its `type` is the subscription's first event, but its `data` holds only `test` and `message` — **none of the fields of the real event**. Check `data.test === true` before reading anything else, and answer 2xx without processing it.
    - `id` string, required: `evt_…` — the same on every attempt and every replay of the event: the deduplication key.
    - `type` 'email.sent' | 'email.failed' | 'email.delivered' | 'email.opened' | 'email.clicked' | 'email.bounced' | 'email.complained' | 'email.received' | 'subscriber.created' | 'subscriber.unsubscribed' | 'quota.threshold_reached', required
    - `created_at` string, date-time, required: When the event occurred (not when it was delivered).
    - `data` object, required
      - `test` true, required: Always `true`: this is a test.
      - `message` string, required: A sentence in the language of the request (`Accept-Language`) or of the screen.

## Acknowledgement `2XX`

Any 2xx within 15 seconds acknowledges receipt. Anything else — another status, a redirect (not followed), no answer, a network error — is retried: 5 attempts in all, the next ones 30 s, 2 min, 10 min and 1 h after the previous failure.

---

[API](https://skmtc.dev/mailcheer/apis/mailcheer-api.md) · [All operations](https://skmtc.dev/mailcheer/apis/mailcheer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mailcheer/apis/mailcheer-api/revisions/ba64b7ef2170?raw)
