Skip to content

Documentation

Receiving email.

Mail sent to an address at your domain arrives in Mailtruss, at your webhook and in the API: support replies, inbound requests, anything people send you.

Set up receiving

  • Use a domain you have verified for sending. Receiving on a subdomain such as in.example.com is the safe choice: the MX record you add replaces any existing MX for that name, and your main domain’s mailboxes keep working.
  • Turn it on: in the dashboard open the domain, then Configuration, Receive email. Or with the API (below).
  • Publish the MX record it shows at your DNS provider: host in.example.com, priority 10, value inbound-smtp.us-east-1.amazonaws.com. Check MX now on the same page tells you when public DNS points at us.
  • Send a message to any address at that name. It shows under Received within seconds and is posted to your webhooks as email.received.
Turn receiving on with the API
curl -X PATCH https://mailtruss.com/api/v1/domains/$DOMAIN_ID \
-H "Authorization: Bearer $MAILTRUSS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "receiving": true }'

The email.received event

Subscribe an endpoint to email.received under Webhooks. The event is signed and retried like every other. It holds the sender, recipients, subject, threading fields, the attachment list and the authentication results, but not the bodies, so it stays small. Fetch the bodies with the API when you need them.

Request body
{
"type": "email.received",(highlighted line)
"created_at": "2026-11-15T10:02:11.402Z",
"data": {
"email_id": "87e7fba7-e5c5-4aa6-9fa1-539eb5a62597",
"from": "ana.novak@fabrikam.com",
"from_name": "Ana Novak",
"to": ["support@in.example.com"],
"cc": [],
"recipients": ["support@in.example.com"],
"subject": "Order 1042 never arrived",
"message_id": "<CA+f3k2@mail.fabrikam.com>",
"in_reply_to": null,
"thread_id": "<CA+f3k2@mail.fabrikam.com>",
"reply_to_email_id": null,
"attachments": [
{ "id": "4c0e…", "filename": "receipt-1042.pdf", "content_type": "application/pdf", "size": 48213, "inline": false, "content_id": null }
],
"spam_verdict": "pass",
"authentication": { "spf": "pass", "dkim": "pass", "dmarc": "pass" },
"received_at": "2026-11-15T10:02:11.000Z"
}
}
app/api/webhooks/mailtruss/route.ts
// app/api/webhooks/mailtruss/route.ts
import { verifyWebhook } from "mailtruss";
​
export async function POST(req: Request) {
const event = await verifyWebhook(await req.text(), req.headers, process.env.MAILTRUSS_WEBHOOK_SECRET!);
if (event.type === "email.received") {(highlighted line)
// The webhook carries who, what and the attachment list. Fetch the bodies when you need them.
const res = await fetch(`https://mailtruss.com/api/v1/inbound/${event.data.email_id}`, {
headers: { Authorization: `Bearer ${process.env.MAILTRUSS_API_KEY}` },
});
const email = await res.json(); // email.text, email.html, email.headers, email.attachments
await createSupportTicket({ from: email.from, subject: email.subject, body: email.text });
}
return new Response(null, { status: 200 });
}

Reading messages with the API

EndpointReturns
GET /api/v1/inboundReceived emails, newest first. q searches sender, subject and recipient; thread_id lists one conversation; before pages back.
GET /api/v1/inbound/:idThe text and HTML bodies, headers, SPF, DKIM and DMARC results, the spam verdict and the attachment list.
GET /api/v1/inbound/:id/attachments/:attachmentIdOne attachment, its bytes as base64 in content.
GET /api/v1/inbound/:id/rawThe original message exactly as received (message/rfc822), base64.
DELETE /api/v1/inbound/:idDeletes the message, its attachments and the original.
Examples
curl https://mailtruss.com/api/v1/inbound?q=1042 \
-H "Authorization: Bearer $MAILTRUSS_API_KEY"
​
curl https://mailtruss.com/api/v1/inbound/87e7fba7-e5c5-4aa6-9fa1-539eb5a62597 \
-H "Authorization: Bearer $MAILTRUSS_API_KEY"
​
# one attachment, base64 in "content"
curl https://mailtruss.com/api/v1/inbound/87e7fba7-…/attachments/4c0e… \
-H "Authorization: Bearer $MAILTRUSS_API_KEY"

These need a full-access API key. Sending-only keys cannot read received mail.

Replies and threads

When someone replies to an email you sent through Mailtruss, the received message carries reply_to_email_id: the ID of your sent email. Messages in the same conversation share a thread_id, built from the standard In-Reply-To and References headers, so you can show a ticket’s history without parsing headers yourself.

Safety, limits and retention

  • Messages flagged as carrying a virus are dropped and never stored. Messages flagged as spam are kept and marked (spam_verdict: "fail") so you can decide.
  • The authentication results (spf, dkim, dmarc) are what the receiving server found. A failed DMARC check means the sender may not be who the From line says; treat such a message with care before acting on it.
  • Each received message counts as one email toward your monthly plan, like a send. Received mail is never refused for quota: it has already arrived.
  • Messages up to 40 MB are accepted, attachments included.
  • Received mail is kept for 30 days, then deleted with its attachments and original. Copy anything you need to keep.
  • In the dashboard, a message’s HTML is shown in a sandbox with scripts off and remote images blocked until you load them, so opening it does not tell the sender.

Last updated

Something wrong or unclear on this page?

Report an issue