Developers

API reference

A small REST API over HTTPS. All endpoints are under /api/v1. There's also a Node SDK and an optional SMTP relay.

Authentication

Send your API key as a Bearer token. Live keys (smk_live_…) deliver; test keys (smk_test_…) validate and record but never deliver.

Authorization: Bearer smk_live_…

Send an email

POST /api/v1/email — requires the From domain to be registered & verified. Returns 202 with { id, status } where status is sent | test | suppressed.

curl -X POST https://sovmail.co.uk/api/v1/email \
  -H "Authorization: Bearer smk_live_…" -H "content-type: application/json" \
  -d '{
    "from": "noreply@mail.your-company.co.uk",
    "to": "user@example.org",
    "subject": "Welcome",
    "text": "Thanks for signing up.",
    "html": "<p>Thanks for signing up.</p>"
  }'

Send with a stored template instead of subject/body:

{ "from": "...", "to": "...", "templateId": "…", "variables": { "name": "Ada" } }

Add "track": true to record delivery status (a delivered status and delivered/deferred events) for a message — handy for confirming sends while testing. It's off by default and overrides your account default; it's delivery status only, never open/click tracking or link rewriting. Bounces and complaints are always recorded regardless.

Batch send

POST /api/v1/email/batch — up to 500 messages; each returns its own result.

{ "messages": [ { "from": "...", "to": "a@x.org", "subject": "Hi", "text": "1" }, … ] }

Templates

GET /api/v1/templates · POST /api/v1/templates — bodies support {{variables}}, {{#if}}/{{#unless}} conditionals, and layouts.

Messages & usage

GET /api/v1/messages — recent sends. Filter with ?status= (e.g. delivered, bounced), ?track=true|false (delivery-tracked messages only), ?q= (recipient/subject) and ?limit= (max 500). Each row includes track. GET /api/v1/usage — plan, monthly limit, used, remaining.

Webhooks

PUT /api/v1/webhook sets a receiver URL and returns a signing secret; we POST events signed with HMAC-SHA256 in X-Sovmail-Signature. We always send message.sent (accepted by the MTA); for messages with delivery tracking on we also send message.delivered when the recipient MTA confirms delivery.

Errors

Standard HTTP codes: 401 bad key · 402 over quota · 403 unverified/suspended/unverified domain · 404 template not found · 422 failed content checks · 429 rate limited. Bodies are { "error": "…" }.