Skip to content
machinemail

Inbound

Raw message injection and the inbound webhooks of the mail providers.

MethodPathSummary
POST/inbound/rawInject Raw Message
POST/inbound/resendResend Webhook
POST/inbound/sesSES Notification (SNS)

Inject Raw Message

http
POST /inbound/raw

Stores a raw RFC 5322 message (the request body, any Content-Type, at most 40 MB) as if it had been received, once per recipient inbox in the credential’s scope. The recipient is X-Recipient, otherwise every To and Cc address.

Injected messages are marked received_via: "raw". Their trust report never believes the authentication results they carry (headers and provider verdicts are ignored): authentication is none, so the trust level is at most unknown.

An unrestricted key (*) does not imply inbound_raw; it must be granted by name.

Authentication: Authorization: Bearer <api key> or the dashboard mm_session cookie.

Headers

X-Recipientstring
Recipient address. Defaults to the To and Cc addresses of the message.

Request body

Content type: message/rfc822. Required.

Type: string (binary)

Response

201 Stored (application/json)

countintegerRequired
Number of messages stored (one per recipient inbox that accepted it).
messagesMessage[]Required
The stored messages, marked received_via: "raw".
errorsobject[]
Recipients that could not be delivered to, when there were several and at least one succeeded.

Each item of messages is a Message:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
message_idstringRequired
ID of the message.
labelsstring[]Required
Labels of the message.
timestampstring (date-time)Required
Time at which the message was sent or received.
fromstringRequired
Address of the sender. In format username@domain.com or Display Name <username@domain.com>.
tostring[]Required
Addresses of the recipients. In format username@domain.com or Display Name <username@domain.com>.
ccstring[]
Addresses of the CC recipients. In format username@domain.com or Display Name <username@domain.com>.
bccstring[]
Addresses of the BCC recipients. In format username@domain.com or Display Name <username@domain.com>.
subjectstring
Subject of the message.
previewstring
Text preview of the message.
attachmentsAttachment[]
Attachments of the message.
in_reply_tostring
ID of the message being replied to.
referencesstring[]
IDs of previous messages in the thread.
headersRecord<string, string>
Headers of the message.
sizeintegerRequired
Size of the message in bytes.
updated_atstring (date-time)Required
Time at which the message was last updated.
created_atstring (date-time)Required
Time at which the message was created.
pod_idstringRequired
ID of the pod.
direction"inbound" | "outbound"Required
Whether the message was received or sent.
delivery_status"sent" | "delivered" | "bounced" | "complained"
Outbound only: last delivery state reported by the transport.
trust_level"verified" | "known" | "unknown" | "suspicious" | "quarantined"
Inbound only: trust.level, for list badges.
reply_tostring[]
Reply-to addresses. In format username@domain.com or Display Name <username@domain.com>.
textstring
Plain text body. Untrusted: agents should read trust.content.text or extracted_text.
htmlstring
HTML body. Untrusted.
extracted_textstring
New text content, without quoted replies.
extracted_htmlstring
New HTML content, without quoted replies.
received_via"raw"
raw when the message was injected with POST /inbound/raw (authentication not verified).
Trust report of an inbound message.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X POST "https://api.machinemail.dev/inbound/raw" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: message/rfc822" \
  --data-binary @body
Response 201
{
  "count": 1,
  "messages": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "from": "Support Agent <agent@machinemail.dev>",
      "to": ["customer@example.com"],
      "cc": ["team@example.com"],
      "bcc": ["audit@example.com"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "in_reply_to": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "references": ["string"],
      "headers": {
        "key": "value"
      },
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "direction": "inbound",
      "delivery_status": "sent",
      "trust_level": "verified",
      "reply_to": ["agent@machinemail.dev"],
      "text": "Thanks for the quick reply.",
      "html": "<p>Thanks for the quick reply.</p>",
      "extracted_text": "Thanks for the quick reply.",
      "extracted_html": "<p>Thanks for the quick reply.</p>",
      "received_via": "raw",
      "trust": {
        "level": "verified",
        "score": 0.8,
        "authentication": {
          "spf": "pass",
          "dkim": "pass",
          "dmarc": "pass",
          "aligned": false
        },
        "sender": {
          "address": "agent@machinemail.dev",
          "domain": "example.com",
          "prior_correspondence": false,
          "on_allow_list": false,
          "on_block_list": false,
          "free_mail_provider": false
        },
        "content": {
          "text": "Thanks for the quick reply.",
          "html": "<p>Thanks for the quick reply.</p>",
          "segments": [{}],
          "hidden_text_found": false,
          "zero_width_found": false,
          "tracking_pixels": 1
        },
        "links": [
          {
            "href": "string",
            "text": "Thanks for the quick reply.",
            "final_url": "https://example.com",
            "domain": "example.com",
            "display_mismatch": false,
            "shortener": false,
            "suspicious": false,
            "reasons": []
          }
        ],
        "attachments": [
          {
            "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
            "filename": "invoice.pdf",
            "content_type": "application/pdf",
            "risk": "low",
            "reasons": [],
            "extracted_text": "Thanks for the quick reply."
          }
        ],
        "classification": {
          "is_spam": 0.8,
          "is_phishing": 0.8,
          "contains_instructions_to_agent": 0.8,
          "requests_credentials_or_payment": 0.8,
          "urgency": 0.8,
          "category": "transactional",
          "language": "string",
          "backend": "string",
          "input_hash": "string",
          "cached": false
        },
        "reasons": ["string"],
        "computed_at": "2026-10-01T12:00:00.000Z"
      }
    }
  ],
  "errors": [
    {
      "recipient": "string",
      "message": "string"
    }
  ]
}

Resend Webhook

http
POST /inbound/resend

Called by Resend, not by API clients. The body is a Resend webhook event signed with Svix (svix-id, svix-timestamp, svix-signature, verified against RESEND_WEBHOOK_SECRET, 5 minute tolerance).

email.received fetches the raw message from Resend and stores it for each to address; email.delivered, email.bounced and email.complained record delivery feedback; email.sent (and the feedback events) record the Message-ID the message went out with, which Amazon SES assigns, so replies thread; other types are acknowledged and ignored.

Without RESEND_WEBHOOK_SECRET the answer is 501 with the API error envelope.

Authentication: None.

Request body

Content type: application/json. Required.

Type: object

Response

200 Processed (application/json)

processedintegerRequired
Recipients stored (email.received) or feedback events recorded.
errorsstring[]
Per-recipient failures.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
500Unexpected server error.
501email.received while RESEND_API_KEY is not configured (nothing stored).

Example

Request
curl -X POST "https://api.machinemail.dev/inbound/resend" \
  -H "Content-Type: application/json" \
  -d '{}'
Response 200
{
  "processed": 1,
  "errors": ["string"]
}

SES Notification (SNS)

http
POST /inbound/ses

Called by Amazon SNS, not by API clients: SES receipt notifications and subscription confirmations. The SNS signature is verified, and the topic must match the configured one when set. Also served at SES_ENDPOINT when that is a different path. Answers are plain text.

Authentication: None.

Request body

Content type: text/plain. Required.

Type: string

Response

200 OK or Subscription confirmed (text/plain)

Errors

StatusMeaning
400Not a valid SNS message, or a bad SubscribeURL
403Invalid signature or Unexpected topic
500Processing failed

Example

Request
curl -X POST "https://api.machinemail.dev/inbound/ses" \
  -H "Content-Type: text/plain" \
  --data-binary @body