What's in your webhook payload
Every email that arrives at your alias is transformed into structured JSON and delivered to your webhook endpoint. This reference covers every field you can expect, including the enrichment features available on each plan.
Full payload example
Below is a complete payload with all fields present. Your actual payload will vary depending on the email content and your plan. The payload has five top-level sections: spam, message, integrity, classification, and security.
{
"domainId": "cm1a2b3c4d5e6f7g8h9i0j1k2",
"aliasId": "cm9z8y7x6w5v4u3t2s1r0q9p8",
"spam": {
"score": -0.99,
"action": "default",
"engine": "rspamd",
"isSpam": false,
"report": "default: False [-0.99 / 0.00]; DMARC_POLICY_ALLOW(-0.50)[example.com,none]; R_DKIM_ALLOW(-0.20)[example.com:s=selector1]; R_SPF_ALLOW(-0.20)[+ip4:198.51.100.0/24]; ...",
"symbols": [
{
"name": "DMARC_POLICY_ALLOW",
"weight": -0.5,
"description": "example.com,none"
},
{
"name": "R_DKIM_ALLOW",
"weight": -0.2,
"description": "example.com:s=selector1"
},
{
"name": "R_SPF_ALLOW",
"weight": -0.2,
"description": "+ip4:198.51.100.0/24"
}
],
"threshold": 0,
"authentication": {
"spf": { "result": "pass" },
"dkim": { "result": "pass" },
"dmarc": { "result": "pass" }
}
},
"message": {
"date": "2026-02-12T10:30:00.000Z",
"sender": {
"name": "Alice Martin",
"email": "alice@example.com"
},
"content": {
"text": "Hi team,\n\nPlease find invoice #2026-0042 attached.\n\nBest,\nAlice",
"html": "<p>Hi team,</p><p>Please find invoice #2026-0042 attached.</p><p>Best,<br>Alice</p>",
"links": [
{
"url": "https://billing.example.com/inv/2026-0042",
"text": "View it online"
}
],
"markdown": "Hi team,\n\nPlease find invoice #2026-0042 attached.\n\n[View it online](https://billing.example.com/inv/2026-0042)\n\nBest,\nAlice"
},
"subject": "Invoice #2026-0042 attached",
"recipient": {
"name": null,
"email": "invoices@yourdomain.com"
},
"attachments": [
{
"filename": "invoice-2026-0042.pdf",
"contentType": "application/pdf",
"size": 245680,
"content": "JVBERi0xLjQK...",
"virusScan": {
"status": "clean"
}
}
]
},
"integrity": {
"contentHash": "a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1",
"rawEmailHash": "9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e"
},
"classification": {
"type": "normal",
"signals": ["has_attachment", "single_recipient"],
"confidence": "definite"
},
"security": {
"virusScan": {
"scanned": true,
"engine": "clamav",
"engineVersion": "1.5.1",
"definitionsUpdated": "2026-02-12T06:00:00.000Z",
"attachmentsScanned": 1,
"attachmentsSkipped": 0,
"threatsFound": 0
}
}
}
Routing metadata
Every payload includes two top-level identifiers so you can correlate deliveries back to specific resources in your account:
| Field | Type | Description |
|---|---|---|
domainId |
string | The ID of the domain that received the email |
aliasId |
string | The ID of the alias that matched the recipient |
These are useful when you have multiple aliases pointing to the same webhook endpoint and need to distinguish which one triggered the delivery.
Field reference by section
Message
| Field | Type | Description |
|---|---|---|
message.date |
string (ISO 8601) | When the email was sent |
message.sender.name |
string | Sender display name |
message.sender.email |
string | Sender email address |
message.recipient.name |
string | null | Recipient display name (the alias that received the email) |
message.recipient.email |
string | Recipient email address (the alias address) |
message.subject |
string | Email subject line |
Content
| Field | Type | Plan | Description |
|---|---|---|---|
message.content.text |
string | All | Plain text body |
message.content.html |
string | All | HTML body |
message.content.markdown |
string | Maker+ | HTML body converted to clean Markdown |
message.content.links |
array | All | URLs extracted from the email body, each with url and text |
Markdown is generated server-side from the HTML body. It's useful for LLM pipelines, content extraction, and readable logging without needing an HTML parser.
Links are extracted from both HTML and plain text bodies. Each entry includes the url and the link text (anchor text from HTML, or the URL itself for plain text links).
Attachments
| Field | Type | Description |
|---|---|---|
message.attachments[].filename |
string | Original filename |
message.attachments[].contentType |
string | MIME type |
message.attachments[].size |
number | Size in bytes |
message.attachments[].content |
string | Base64-encoded content (inline delivery) |
message.attachments[].url |
string | S3 download URL (offloaded delivery, Maker+) |
message.attachments[].status |
string | Upload status: pending, uploading, completed, failed, or expired |
message.attachments[].uploadType |
string | sync (immediate) or async (queued for large files) |
message.attachments[].virusScan.status |
string | Scan result: clean or infected (Business+) |
message.attachments[].virusScan.threat |
string | Threat name if infected (e.g. Eicar-Test-Signature) |
message.attachments[].virusScan.duration |
number | Scan duration in milliseconds |
message.attachments[].excluded |
boolean | true if attachment was excluded from delivery |
message.attachments[].excludeReason |
string | Reason for exclusion (e.g. virus-detected) |
Small files are uploaded synchronously (≤ 2MB for text/images/docs, ≤ 1MB for archives/media) — the download URL is immediately usable with status: "completed". Larger files are uploaded asynchronously via a queue with status: "pending". Poll GET /attachments/:fileId/download (returns 202 with retryAfter: 5 until ready, then 200 with presigned URL) or the lighter GET /attachments/:fileId/status for metadata only. See Attachment processing for details.
Spam analysis
Available on Maker+ plans. Powered by rspamd.
| Field | Type | Description |
|---|---|---|
spam.score |
number | rspamd composite score (negative = cleaner, higher = more suspicious) |
spam.isSpam |
boolean | Verdict based on the configured threshold |
spam.action |
string | Recommended action (default, greylist, add header, reject) |
spam.engine |
string | Spam engine used (currently rspamd) |
spam.symbols |
array | rspamd rules that matched, each with name (string), weight (number), and description (string) |
spam.threshold |
number | Score threshold used for the spam verdict |
spam.report |
string | Full rspamd text report for debugging |
spam.authentication.spf |
object | SPF result (pass, fail, softfail, none) |
spam.authentication.dkim |
object | DKIM result (pass, fail, none) |
spam.authentication.dmarc |
object | DMARC result (pass, fail, none) |
Classification
| Field | Type | Plan | Description |
|---|---|---|---|
classification.type |
string | All | Email type: normal, transactional, marketing, notification, automated |
classification.confidence |
string | Maker+ | Confidence level (e.g. definite, likely) |
classification.signals |
array | Maker+ | Signals that influenced classification (e.g. has_attachment, has_unsubscribe_link) |
Classification helps you route emails by type, filter out marketing, or prioritize transactional messages — all without writing your own heuristics.
Integrity
Available on Maker+ plans.
| Field | Type | Description |
|---|---|---|
integrity.contentHash |
string | SHA-256 hex hash of the processed payload content |
integrity.rawEmailHash |
string | SHA-256 hex hash of the raw email before processing |
Use integrity hashes to verify that the payload wasn't tampered with in transit, detect duplicate deliveries, or build audit trails.
Security
Available on Business+ plans. Powered by ClamAV.
| Field | Type | Description |
|---|---|---|
security.virusScan.scanned |
boolean | Whether virus scanning was performed |
security.virusScan.engine |
string | Scanning engine (currently clamav) |
security.virusScan.engineVersion |
string | Engine version |
security.virusScan.definitionsUpdated |
string | Virus definitions version |
security.virusScan.attachmentsScanned |
number | Number of attachments scanned |
security.virusScan.attachmentsSkipped |
number | Number of attachments skipped |
security.virusScan.threatsFound |
number | Number of threats detected |
Infected attachments are excluded from the webhook payload. The attachment entry remains with excluded: true, excludeReason: "virus-detected", and the virusScan object containing the threat name. No download URL is provided for infected files.
Features by plan
| Feature | Free | Maker | Business | Platform |
|---|---|---|---|---|
| Message basics (sender, recipient, subject, date) | + | + | + | + |
| Text + HTML body | + | + | + | + |
| Link extraction | + | + | + | + |
| Email classification (type only) | + | + | + | + |
| Attachments (inline base64) | + | + | + | + |
| Markdown conversion | - | + | + | + |
| Classification confidence + signals | - | + | + | + |
| Integrity hashes | - | + | + | + |
| Spam analysis (rspamd) | - | + | + | + |
| S3 attachment offloading | - | + | + | + |
| Virus scanning (ClamAV) | - | - | + | + |
| Custom payload builder | - | - | + | + |
Related topics
- Email processing — Full processing pipeline overview
- Attachment processing — Inline vs S3 delivery, file type support
- Webhook configuration — Set up and manage webhook endpoints