---
title: "Message Received"
method: POST
path: "webhooks_events_messageReceived"
---

# Message Received

`POST webhooks_events_messageReceived` (webhook)

## Headers

- `svix-id` string, required: ID of webhook message.
- `svix-signature` string, required: Signature of webhook message.
- `svix-timestamp` string, date-time, required: Timestamp of webhook message.

## Payload

- EventsMessageReceivedEvent: A message was received. Spam, blocked, and unauthenticated received-message events use the same payload shape with different `event_type` values.
  - `type` 'event', required
  - `event_type` 'message.received' | 'message.received.spam' | 'message.received.blocked' | 'message.received.unauthenticated', required
  - `event_id` string, required: ID of the event. It is the same on every retry and redelivery of the event and on every webhook or WebSocket subscription that receives it, so use it to deduplicate. The format varies by event type; treat it as an opaque string.
  - `message` EventsReceivedMessage, required: The received message. The body (`text`, `html`, `extracted_text`, and `extracted_html`) is included inline only when it is small enough. Webhooks omit it when the stored body is larger than 64 KiB; WebSocket events also omit it when the serialized event would be larger than 30 KiB. When the body is omitted, `body_url` and `body_expires_at` are set instead.
    - `inbox_id` string, required: The ID of the inbox.
    - `thread_id` string, required: ID of thread.
    - `message_id` string, required: ID of message.
    - `labels` string[], required: Labels of message.
    - `timestamp` string, date-time, required: Time at which message was sent or drafted.
    - `from` string, required: Address of sender. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `reply_to` string[]: Reply-to addresses. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `to` string[], required: Addresses of recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `cc` string[]: Addresses of CC recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `bcc` string[]: Addresses of BCC recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `subject` string: Subject of message.
    - `preview` string: Text preview of message.
    - `text` string: Plain text body of message.
    - `html` string: HTML body of message.
    - `extracted_text` string: Extracted new text content.
    - `extracted_html` string: Extracted new HTML content.
    - `attachments` AttachmentsAttachment[]: Attachments in message.
      - `attachment_id` string, required: ID of attachment.
      - `filename` string: Filename of attachment.
      - `size` integer, required: Size of attachment in bytes.
      - `content_type` string: Content type of attachment.
      - `content_disposition` 'inline' | 'attachment': Content disposition of attachment.
      - `content_id` string: Content ID of attachment.
    - `in_reply_to` string: ID of message being replied to.
    - `calendar_event_id` string: The calendar event this email's invitation was applied to: set when the email's calendar invitation, update, cancellation or attendee reply changed the inbox's calendar, a few seconds after the email arrives. For an email about one date of a recurring event, it is that date's event ID. Absent on other emails, and on invitations that were not imported. The `message.received` event for an email with a calendar attachment waits until this is set, at most 20 seconds, so it usually arrives with it. Calendar is available in US production.
    - `references` string[]: IDs of previous messages in thread.
    - `headers` MessagesMessageHeaders: Headers in message. `Authentication-Results` is never included, on received or sent messages: the header is unsigned, so a sender can plant a forged copy. Read `authentication_results` for the verdicts instead. Get Raw Message still returns every copy of the header.
    - `authentication_results` MessagesMessageAuthenticationResults: Per-mechanism SPF, DKIM, and DMARC verdicts for a received message, each with the domain it is about, kept only where they speak for the sender's From identity. A verdict that could not be computed is absent, so the field can be `{}`. The field is absent on sent messages and on messages received before 2026-09-09; the `*_domain` and `arc_sealer` keys appear on messages received after they were introduced. The verdicts are the ones Amazon SES computed when the message reached AgentMail, with one exception. Forwarded mail fails DMARC at the receiving hop by construction. When AgentMail delivers a forwarded message as authenticated because a trusted forwarder (such as Google or Microsoft) sealed a valid ARC chain vouching for the original, the field reports the verdicts that forwarder recorded for the original message, and `arc_sealer` names it. - `spf` is about the envelope MAIL FROM (Return-Path) domain, named in `spf_domain`. It is present only when that domain is aligned with the sender's domain (the From mailbox, or the Sender header when From spans domains), meaning the two share an organizational domain: `mail.example.com` is aligned with `example.com`. An unaligned SPF result is withheld whatever its value. - `dkim` is the DKIM verdict, and `dkim_domain` the signing domain (the `d=` tag). On directly received mail the domain is named only when every DKIM signature on the message is from the same domain; a message signed by more than one domain (a sender and its email provider, for instance) keeps the verdict and omits the domain. `dkim_domain` is the signing domain as written, so compare it with the From domain before relying on it. - `dmarc` is the DMARC verdict for the From domain, named in `dmarc_domain`. - `dkim` and `dmarc` are withheld when the From list spans more than one domain or could not be fully parsed. - On forwarded mail each sealed verdict is reported only when the domain the forwarder recorded it for matches the message's current From domain. If the forwarder rewrote From, or vouched for nothing, the field is `{}`. The `unauthenticated` label, not this field, is AgentMail's acceptance decision, and it uses a looser rule, so the two can disagree: a single-From message whose only pass is an unaligned envelope SPF is delivered without the label while this field shows no pass. Use the label to tell whether AgentMail accepted the message as legitimate, and this field to see which domain each mechanism authenticated. Do not reject mail on `dmarc: fail` alone.
      - `spf` 'pass' | 'fail' | 'none' | 'neutral' | 'softfail' | 'temperror' | 'permerror': Result of one email authentication mechanism, in the vocabulary of the `Authentication-Results` header (RFC 8601). `none` means there was nothing to evaluate (Amazon SES calls this GRAY): no SPF record for the envelope MAIL FROM domain, no DKIM signature to check, or no DMARC record for the From domain.
      - `dkim` 'pass' | 'fail' | 'none' | 'neutral' | 'softfail' | 'temperror' | 'permerror': Result of one email authentication mechanism, in the vocabulary of the `Authentication-Results` header (RFC 8601). `none` means there was nothing to evaluate (Amazon SES calls this GRAY): no SPF record for the envelope MAIL FROM domain, no DKIM signature to check, or no DMARC record for the From domain.
      - `dmarc` 'pass' | 'fail' | 'none' | 'neutral' | 'softfail' | 'temperror' | 'permerror': Result of one email authentication mechanism, in the vocabulary of the `Authentication-Results` header (RFC 8601). `none` means there was nothing to evaluate (Amazon SES calls this GRAY): no SPF record for the envelope MAIL FROM domain, no DKIM signature to check, or no DMARC record for the From domain.
      - `spf_domain` string: The domain an authentication verdict is about, lowercase. Present only beside its verdict: when the verdict is withheld, so is the domain.
      - `dkim_domain` string: The domain an authentication verdict is about, lowercase. Present only beside its verdict: when the verdict is withheld, so is the domain.
      - `dmarc_domain` string: The domain an authentication verdict is about, lowercase. Present only beside its verdict: when the verdict is withheld, so is the domain.
      - `arc_sealer` string: The domain an authentication verdict is about, lowercase. Present only beside its verdict: when the verdict is withheld, so is the domain.
    - `agent_armor` union: Agent Armor's result for this message. Present only on messages received while Agent Armor was on for your organization. A scan starts `pending` and usually completes within seconds. `message.security.completed` is sent only for `complete` results, so a message still `pending` at `deadline_at` reads `unavailable` with no event.
      - object
        - `status` 'pending', required: Discriminator value: pending
        - `started_at` string, date-time, required: When the message was received. The deadline counts from here.
        - `deadline_at` string, date-time, required: When the scan gives up. A result still pending then reads as `unavailable` with `deadline_exceeded`.
      - object
        - `status` 'complete', required: Discriminator value: complete
        - `verdict` 'clear' | 'review', required: What the scan concluded. `clear` means Agent Armor found no threat. It is advisory, not a guarantee that the message is safe. `review` means the message may try to manipulate an agent: inspect it before an agent acts on it.
        - `reason` string, required: A short explanation of the verdict.
        - `model` string, required: Identifies the Agent Armor release that produced the verdict. Opaque; it changes when Agent Armor is updated.
        - `completed_at` string, date-time, required: When the scan finished.
        - `manual_override` AgentArmorAgentArmorManualOverride: The record of a release of a message Agent Armor held for review.
          - `override_id` string, required: ID of the release, and the `event_id` of its `message.security.override` event.
          - `actor` union, required: Who released the message.
            - object
              - …
            - object
              - …
          - `reason` string, required: Why it was released, as given by whoever released it.
          - `original_verdict` 'review', required: The verdict that held the message.
          - `released_at` string, date-time, required: When it was released.
      - object
        - `status` 'unavailable', required: Discriminator value: unavailable
        - `unavailable_reason` 'unsupported_dsn' | 'payload_too_large' | 'no_scannable_content' | 'enqueue_failed' | 'scorer_failed' | 'contract_error' | 'deadline_exceeded', required: Why no verdict is available.
    - `size` integer, required: Size of message in bytes.
    - `updated_at` string, date-time, required: Time at which message was last updated.
    - `created_at` string, date-time, required: Time at which message was created.
    - `body_url` string: Pre-signed URL that downloads the stored body as a JSON object including `text`, `html`, `extracted_text`, and `extracted_html`. Present only when the body is omitted from the event. Valid until `body_expires_at`, one hour after the event was built. The body stays available through the get message endpoint after the URL expires.
    - `body_expires_at` string, date-time: Time at which `body_url` expires. Present only with `body_url`.
  - `thread` ThreadsThreadItem, required
    - `inbox_id` string, required: The ID of the inbox.
    - `thread_id` string, required: ID of thread.
    - `labels` string[], required: Labels of thread.
    - `timestamp` string, date-time, required: Timestamp of last sent or received message.
    - `received_timestamp` string, date-time: Timestamp of last received message.
    - `sent_timestamp` string, date-time: Timestamp of last sent message.
    - `senders` string[], required: Senders in thread. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `recipients` string[], required: Recipients in thread. In format `username@domain.com` or `Display Name <username@domain.com>`.
    - `subject` string: Subject of thread.
    - `preview` string: Text preview of last message in thread.
    - `attachments` AttachmentsAttachment[]: Attachments in thread.
      - `attachment_id` string, required: ID of attachment.
      - `filename` string: Filename of attachment.
      - `size` integer, required: Size of attachment in bytes.
      - `content_type` string: Content type of attachment.
      - `content_disposition` 'inline' | 'attachment': Content disposition of attachment.
      - `content_id` string: Content ID of attachment.
    - `last_message_id` string, required: ID of last message in thread.
    - `message_count` integer, required: Number of messages in thread.
    - `size` integer, required: Size of thread in bytes.
    - `updated_at` string, date-time, required: Time at which thread was last updated.
    - `created_at` string, date-time, required: Time at which thread was created.

## Acknowledgement `200`

Webhook received successfully

---

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