Generic JSON
Table of contents
This mapper emits payloads that conform to mailwebhook.generic@1. Attachments stay out of the HTTP body and no URLs are embedded. See Fetch email attachments from webhook payloads for download details.
For product context around structured email payloads, see Email to JSON.
Shape
- Top-level keys:
schema,event,message,body,meta, optionalenvelope. schema:{ "name": "mailwebhook.generic", "version": "1" }event:{ id, project_id, route_id, created_at }(all strings;created_atis RFC3339 UTC, no fractional seconds).message: includesmessage_id,message_id_type(original|synthetic),subject,date, people arrays (from,to, optionalreply_to|cc|bcc), optional normalizedheaders.body:attachments(required array) plus optionaltext/html.meta:source(imap|gmail|hosted|ms365|api|cli),raw_size_bytes,received_at(RFC3339 UTC), optionalspam(for hosted mailboxes only).envelope(optional):mail_fromandrcpt_to(unique, sorted).
Determinism rules enforced
- People arrays are sorted by email; emails are lowercased and trimmed.
- Attachments are sorted by
(filename, size)and include{id, filename, content_type, size, is_inline, content_id?, sha256?}. - Headers are lowercased, unfolded, trimmed; duplicates are joined with
", ". Empty values are dropped. - Times are UTC (
Z), whole seconds. - Optional fields are omitted when empty.
- Sorting/dedup behaviors above are enforced at runtime; JSON Schema cannot express ordering constraints (it enforces non-empty headers, unique attachments/rcpt_to).
Schema definition
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.mailwebhook.dev/transform/generic@1",
"title": "mailwebhook.generic v1",
"type": "object",
"additionalProperties": false,
"required": ["schema", "event", "message", "body", "meta"],
"properties": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["name", "version"],
"properties": {
"name": { "const": "mailwebhook.generic" },
"version": { "const": "1" }
}
},
"event": {
"type": "object",
"additionalProperties": false,
"required": ["id", "project_id", "route_id", "created_at"],
"properties": {
"id": { "type": "string", "minLength": 1 },
"project_id": { "type": "string", "minLength": 1 },
"route_id": { "type": "string", "minLength": 1 },
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
}
}
},
"message": {
"type": "object",
"additionalProperties": false,
"required": ["message_id", "message_id_type", "subject", "date", "from", "to"],
"properties": {
"message_id": { "type": "string", "minLength": 1 },
"message_id_type": { "enum": ["original", "synthetic"] },
"subject": { "type": "string" },
"date": {
"type": "string",
"format": "date-time",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
},
"from": { "$ref": "#/$defs/people" },
"reply_to": { "$ref": "#/$defs/people" },
"to": { "$ref": "#/$defs/people" },
"cc": { "$ref": "#/$defs/people" },
"bcc": { "$ref": "#/$defs/people" },
"headers": {
"type": "object",
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "string",
"minLength": 1,
"pattern": "^\\S(.*\\S)?$"
}
},
"additionalProperties": false
}
}
},
"envelope": {
"type": "object",
"additionalProperties": false,
"required": ["mail_from", "rcpt_to"],
"properties": {
"mail_from": { "type": "string", "format": "idn-email" },
"rcpt_to": {
"type": "array",
"items": { "type": "string", "format": "idn-email" },
"uniqueItems": true,
"minItems": 0
}
}
},
"body": {
"type": "object",
"additionalProperties": false,
"required": ["attachments"],
"properties": {
"text": { "type": "string" },
"html": { "type": "string" },
"attachments": {
"type": "array",
"items": { "$ref": "#/$defs/attachment" },
"uniqueItems": true,
"minItems": 0
}
}
},
"meta": {
"type": "object",
"additionalProperties": false,
"required": ["source", "raw_size_bytes", "received_at"],
"properties": {
"source": { "enum": ["imap", "gmail", "hosted", "ms365", "api", "cli"] },
"raw_size_bytes": { "type": "integer", "minimum": 0 },
"received_at": {
"type": "string",
"format": "date-time",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
},
"spam": {
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"flag": { "type": "boolean" },
"score": { "type": "number" },
"quarantined": { "type": "boolean" },
"status": { "type": "string" },
"details": { "type": "object" }
}
}
}
}
},
"$defs": {
"people": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["email"],
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "idn-email" }
}
}
},
"attachment": {
"type": "object",
"additionalProperties": false,
"required": ["id", "filename", "content_type", "size", "is_inline"],
"properties": {
"id": { "type": "string", "minLength": 1 },
"filename": { "type": "string" },
"content_type": { "type": "string" },
"size": { "type": "integer", "minimum": 0 },
"is_inline": { "type": "boolean" },
"content_id": { "type": "string" },
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
}
}
}
}
Example
Find example of default email here.