Multi-tenant outbound email API with templates, campaigns, webhooks, scheduling, and MCP server.
curl -X POST https://mailserver.rodmena.co.uk/api/v1/emails \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"to": ["recipient@example.com"],
"subject": "Hello from Rodmena Mail API",
"html": "<h1>It works!</h1><p>Sent via the API.</p>",
"type": "transactional"
}'
Returns: {"track_id": "01H...", "status": "accepted", "eligible_start": "..."}
All endpoints require Authorization: Bearer <uuid4-api-key>. API keys are UUIDv4 tokens issued via the admin CLI and registered in auth.rodmena.app.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/emails | Send a transactional email |
| GET | /api/v1/emails/{track_id} | Get email status |
| GET | /api/v1/emails | List emails |
| GET | /api/v1/emails/{track_id}/events | Full event history |
| POST | /api/v1/campaigns | Create a bulk campaign |
| GET | /api/v1/campaigns/{campaign_id} | Get campaign status |
| POST | /api/v1/campaigns/{campaign_id}/cancel | Cancel a campaign |
| POST/GET/PATCH/DELETE | /api/v1/templates | Template CRUD |
| POST | /api/v1/templates/{id}/preview | Preview a template |
| GET/PUT | /api/v1/tenant/quotas | Manage quotas |
| GET/PUT | /api/v1/tenant/config | Manage tenant config |
| GET/DELETE | /api/v1/suppression | Suppression list |
| POST/GET/PATCH/DELETE | /api/v1/webhooks | Webhook endpoint CRUD |
| POST | /api/v1/webhooks/{id}/test | Test a webhook |
| POST | /api/v1/webhooks/{id}/rotate-secret | Rotate webhook secret |
| GET | /api/v1/webhooks/{id}/deliveries | Delivery history |
| POST | /api/v1/webhooks/deliveries/{id}/redeliver | Redeliver |
| GET | /api/v1/audit | Audit log |
| GET | /health | Health check |
| GET | /metrics | Prometheus metrics |
| Event | Description |
|---|---|
| email.accepted | Email accepted into the system |
| email.rendered | Template rendered |
| email.scheduled | Email scheduled for future dispatch |
| email.sending | SMTP send in progress |
| email.sent | SMTP accepted the message |
| email.delivered | Delivery confirmed |
| email.bounced | Bounce received |
| email.complained | Spam complaint received |
| email.failed | Dispatch failed |
| email.cancelled | Email cancelled |
| email.suppressed | Recipient on suppression list |
| campaign.* | Campaign lifecycle events |
Aliases: email.terminal, campaign.terminal. Wildcards: email.*, campaign.*, *.
import hmac, hashlib
def verify(signature_header, timestamp, body, secret):
expected = "sha256=" + hmac.new(
secret.encode(),
f"{timestamp}.".encode() + body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature_header, expected)
Register the MCP server at https://mailserver.rodmena.co.uk/mcp with your API key as the Bearer token.
Templates use Jinja2 in a SandboxedEnvironment. All client templates are untrusted — no import, no dunder access, no OS paths.
| Type | Allowed Window |
|---|---|
| transactional | Any time |
| notification | Any time |
| marketing | Mon-Fri 09:00-17:00, excluding UK holidays |
| legal | Mon-Fri 09:00-17:00, excluding UK holidays |