★ Enterprise Edition — not included in the Community Edition. Compare editions
Message Trace¶
Search mail delivery logs, follow a message's full delivery lifecycle, manage the quarantine, and search audit logs — the Exchange-style "message trace" surface used by the operations console.
Base path: /api/v1/message-trace Auth: platform scope with an operator role — every endpoint here is console-facing. Reads require an operator session at role support or above; releasing a quarantined message requires admin, blocking a sender requires operator. A tenant API key cannot call these endpoints.
Search Mail Delivery Logs¶
Search mail delivery logs with filters, newest first.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sender | string | -- | Filter by sender address |
recipient | string | -- | Filter by recipient address |
subject | string | -- | Filter by subject (partial match) |
status | string | -- | delivered, bounced, deferred, rejected |
message_id | string | -- | Filter by Message-ID |
organization_id | string | -- | Filter by organization |
start_date / end_date | string | -- | ISO 8601 date range |
limit | integer | 50 | 1–500 |
offset | integer | 0 | Pagination offset |
Example Request
curl -H "X-API-Key: YOUR_PLATFORM_KEY" \
"http://your-server:5000/api/v1/message-trace/trace?recipient=john@acme.com&status=bounced&limit=20"
Example Response
[
{
"id": "01J9AB2CD3EF4GH5JK6MN7PQ8R",
"timestamp": "2026-08-29T15:42:10",
"sender": "news@sender.io",
"recipient": "john@acme.com",
"subject": "Weekly digest",
"status": "bounced",
"message_id": "<20260829154210.ABC123@sender.io>",
"size": 48211,
"relay": "mx.acme.com",
"dsn": "5.1.1",
"spam_score": 0.4,
"bounce_reason": "user unknown"
}
]
Get Message Delivery Lifecycle¶
Full delivery lifecycle for one message by its Message-ID: all delivery log entries plus related audit events, in chronological order.
curl -H "X-API-Key: YOUR_PLATFORM_KEY" \
"http://your-server:5000/api/v1/message-trace/trace/%3C20260829154210.ABC123%40sender.io%3E"
The path parameter is the message's Message-ID (URL-encode the angle brackets and @).
List Quarantined Messages¶
Messages held pending review, with a threat level computed from the spam score. Headers and metadata only — the console is never shown a message body (ADR-002 §5), so storage_key (the pointer to the stored message) is never returned.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
organization_id | string | -- | Narrow to one organization |
status | string | quarantined | quarantined | released | deleted |
reason | string | -- | spam | virus | policy ... |
q | string | -- | Substring match on sender/recipient/subject |
limit | integer | 50 | 1–200 |
offset | integer | 0 | Pagination offset |
Example Request
curl -H "X-API-Key: YOUR_PLATFORM_KEY" \
"http://your-server:5000/api/v1/message-trace/quarantine?status=quarantined&reason=spam"
Example Response
{
"messages": [
{ "id": "01J9AB...", "status": "quarantined", "threat_level": "high", "...": "headers and metadata" }
],
"total": 3,
"limit": 50,
"offset": 0
}
Release Quarantined Message¶
Deliver a message a filter judged malicious. Requires a reason, and records which operator released it. Also the undo for a block.
Auth: operator session, role admin or above.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | Yes | Min 10 characters. Why this decision was made — recorded in the operator audit trail |
curl -X POST -H "X-API-Key: YOUR_PLATFORM_KEY" \
-H "Content-Type: application/json" \
-d '{"reason": "Verified with the recipient; legitimate invoice"}' \
http://your-server:5000/api/v1/message-trace/quarantine/01J9AB.../release
Block Quarantined Sender¶
Marks the held message as deleted and adds its sender to the organization's suppression list, so future mail from them is refused.
Auth: operator session, role operator or above.
Request Body: same { "reason": "..." } shape as release (min 10 characters).
curl -X POST -H "X-API-Key: YOUR_PLATFORM_KEY" \
-H "Content-Type: application/json" \
-d '{"reason": "Repeated phishing attempts from this sender"}' \
http://your-server:5000/api/v1/message-trace/quarantine/01J9AB.../block
Where the block lives
The quarantine status enum has no blocked member — deleted is its terminal state. The durable part of the block is the suppression entry, not the message status.
Search Audit Logs¶
Search audit logs with comprehensive filters, newest first.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
event_type | string | -- | Filter by event type |
event_source | string | -- | Filter by source service |
organization_id | string | -- | Filter by organization |
user_email | string | -- | Filter by user |
client_ip | string | -- | Filter by client IP |
severity | string | -- | info, warning, error, ... |
start_date / end_date | string | -- | ISO 8601 date range |
limit | integer | 100 | 1–1000 |
offset | integer | 0 | Pagination offset |
Example Request
curl -H "X-API-Key: YOUR_PLATFORM_KEY" \
"http://your-server:5000/api/v1/message-trace/audit?severity=warning&limit=50"
Example Response