Messages API
All endpoints on this page authenticate with an API key. Scoped keys (all_domains = false) see only messages whose domain_id is in their allowlist.
List Messages
GET /api/v1/messages?page=1&per_page=20
Authorization: Bearer {api_key}Required scope: email:read.
Response
json
{
"messages": [
{
"id": "msg_abc123",
"from": "[email protected]",
"to": "[email protected]",
"subject": "Hello World",
"status": "delivered",
"provider": "ses",
"created_at": "2026-03-07T12:00:00Z",
"delivered_at": "2026-03-07T12:00:05Z"
}
],
"total": 150,
"page": 1,
"per_page": 20
}Get Message
GET /api/v1/messages/{id}
Authorization: Bearer {api_key}Required scope: email:read.
Get Message Events
GET /api/v1/messages/{id}/events
Authorization: Bearer {api_key}Required scope: email:read.
json
{
"events": [
{ "type": "queued", "timestamp": "2026-03-07T12:00:00Z" },
{ "type": "sending", "timestamp": "2026-03-07T12:00:01Z", "provider": "ses" },
{ "type": "sent", "timestamp": "2026-03-07T12:00:02Z" },
{ "type": "delivered", "timestamp": "2026-03-07T12:00:05Z" }
]
}Get Stats
GET /api/v1/messages/stats?days=30
Authorization: Bearer {api_key}Required scope: email:read. Returns aggregate statistics for messages sent in the given time window.
| Parameter | Required | Description |
|---|---|---|
| days | No | Number of past days to include (default: 30) |
Response
json
{
"total": 500,
"sent": 490,
"delivered": 480,
"failed": 10,
"opened": 120,
"pending": 0,
"delivery_rate": 97.96,
"open_rate": 25.0,
"failure_rate": 2.04
}Cancel Scheduled Message
POST /api/v1/messages/{id}/cancel
Authorization: Bearer {api_key}Required scope: email:send. Cancels an email message that is still pending and whose scheduled_at is in the future.
Errors
| Status | Code | Meaning |
|---|---|---|
| 404 | NOT_FOUND | Message missing or not owned by the caller |
| 400 | NOT_CANCELLABLE | Target is not an email message |
| 409 | ALREADY_PROCESSED | Message is no longer pending |
| 400 | NOT_SCHEDULABLE | Message has no scheduled_at, or it is already past |
| 403 | DOMAIN_NOT_ALLOWED | Scoped key; target message's domain is not allowlisted (also returned for legacy messages with no recorded domain) |
Message Status
| Status | Description |
|---|---|
| queued | In task queue, waiting to be processed |
| sending | Being sent via provider |
| sent | Provider accepted the message |
| delivered | Confirmed delivered to recipient |
| bounced | Delivery failed (hard or soft bounce) |
| failed | Permanent failure |
| opened | Recipient opened the email (tracked) |