Send, track, and manage transactional emails via SMTP.
Requires an SMTP account configured in the dashboard. Supports HTML/text content, attachments (multipart), batch sending with variable substitution, scheduling, and tracking.
Endpoints
| Method | Path | Permission |
|---|---|---|
POST | email.send | |
POST | email.send | |
POST | email.send | |
GET | email.history | |
GET | email.history | |
DELETE | email.send |
Send Email
POST /api/v1/emails/send
Request
Response
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"to": "user@example.com",
"subject": "Welcome!"
}
}Send with Attachments
POST /api/v1/emails/send/multipart • POST /api/v1/emails/send
Two ways to attach files to an email — pick the one that fits your client:
- multipart/form-data (
/emails/send/multipart): native file upload, up to 50 MB per file, max 10 files per request. Recommended for large files. - JSON with base64 (
/emails/send): inline base64-encoded content. Total body capped at ~1 MB by default (≈ 750 KB of raw file after base64 expansion). Recommended for small files where you don't want to deal with multipart.
Both methods produce the same Email record with attachments[] populated. The file part field name in multipart can be anything (attachments, file, files[], etc.) — the API picks up every file part regardless of name.
multipart/form-data
JSON with base64
Response (both methods)
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"scheduled_at": null
}
}Fetch the email via GET /api/v1/emails/:id to inspect the stored attachments[] (each with id, filename, contentType, sizeBytes). The worker reads each file from disk and attaches it to the outgoing SMTP message automatically.
Batch Send
POST /api/v1/emails/batch
Request
Response
{
"success": true,
"data": [
{ "id": "uuid-1", "to": "alice@example.com", "status": "queued" },
{ "id": "uuid-2", "to": "bob@example.com", "status": "queued" }
],
"meta": { "total": 2 }
}List & Get Emails
GET /api/v1/emails • GET /api/v1/emails/:id
Request
Response (single email)
status reflects the raw send state. For end-to-end engagement use unified_status — see the Tracking doc.
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"to": "user@example.com",
"subject": "Welcome!",
"status": "sent",
"unified_status": "replied",
"created_at": "2026-03-18T10:00:00Z",
"sent_at": "2026-03-18T10:00:05Z",
"delivered_at": "2026-03-18T10:00:08Z",
"first_opened_at": "2026-03-18T10:14:22Z",
"read_at": null,
"first_replied_at": "2026-03-18T11:02:17Z"
}
}