Developer reference

DigitMailer API

A JSON API for sending transactional email. One endpoint to send, full delivery feedback per recipient, and guided domain verification. All requests are authenticated with your API key.

Basics

Base URLhttps://api.digitmailer.co.za
AuthenticationHeader Authorization: Bearer dm_<your key> on every request. Create keys in your dashboard.
Content typeapplication/json
ErrorsAll errors return {"error":{"code":"...","message":"..."}}

Send a message POST /v1/messages

curl -X POST https://api.digitmailer.co.za/v1/messages \
  -H "Authorization: Bearer dm_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Billing <billing@yourdomain.co.za>",
    "to": ["customer@example.com"],
    "subject": "Your invoice INV-1042",
    "html": "<p>Please find your invoice attached.</p>",
    "text": "Please find your invoice attached.",
    "attachments": [
      {"filename": "INV-1042.pdf", "content_type": "application/pdf", "content_b64": "JVBERi0x..."}
    ],
    "idempotency_key": "inv-1042-first-send"
  }'

Response 202:

{"id": "0d9c1c6e-8f2a-4c1e-9c1a-2b7e8f0a1d42", "status": "queued"}

Message status & delivery feedback GET /v1/messages/{id}

{
  "id": "0d9c1c6e-...",
  "status": "accepted",
  "recipients": [
    {"addr": "customer@example.com", "status": "delivered",
     "detail": "250 2.0.0 OK", "updated_at": "2026-08-20T21:41:43Z"}
  ],
  "opened": true, "open_count": 2, "first_opened_at": "2026-08-20T21:44:01Z",
  "events": [
    {"event": "queued", "at": "..."},
    {"event": "smtp_accepted", "detail": "5E77444DB7", "at": "..."},
    {"event": "delivered", "detail": "customer@example.com: 250 2.0.0 OK", "at": "..."},
    {"event": "opened", "at": "..."}
  ]
}

Domains verify before you send

Register the domain you send from, publish the DNS records we return, then verify. Sending is enabled the moment your DKIM record is live. The dashboard wizard does the same thing visually.

# Register — returns the DNS records to publish (DKIM required; SPF + DMARC recommended)
curl -X POST https://api.digitmailer.co.za/v1/domains \
  -H "Authorization: Bearer dm_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"domain": "yourdomain.co.za"}'

# Check DNS and activate
curl -X POST https://api.digitmailer.co.za/v1/domains/yourdomain.co.za/verify \
  -H "Authorization: Bearer dm_YOUR_KEY"

# List / inspect / remove
GET    /v1/domains
GET    /v1/domains/{domain}
DELETE /v1/domains/{domain}

Usage GET /v1/usage?month=2026-08

{"month": 202608, "accepted": 12480, "delivered_to_postfix": 12401, "failed": 12,
 "plan": {"code": "starter", "name": "Starter", "included_emails": 50000, "overage_policy": "block"},
 "remaining": 37520}

Per-key options set when creating a key in the dashboard

OptionDefaultEffect
Track openson Embeds a read pixel in HTML mail; opens appear on the message as opened/open_count.
Unsubscribe linkoff Appends an unsubscribe link to the email and emits one-click List-Unsubscribe headers (single-recipient messages). Recipients who unsubscribe are added to your suppression list automatically. Recommended for marketing/bulk mail; leave off for transactional mail like invoices and password resets.

Tip: create separate keys for transactional and marketing traffic so each gets the right behavior.

Suppressions automatic list hygiene

Addresses that report your mail as spam or hard-bounce (user unknown) are suppressed automatically and skipped on future sends — this protects your sender reputation.

GET    /v1/suppressions            # list: addr, reason (complaint|hard_bounce|unsubscribe|manual), detail
DELETE /v1/suppressions/{addr}     # remove an address (use with care)

Response codes

CodeMeaning
202Message accepted and queued.
400Invalid request — or all_recipients_suppressed.
401Missing or invalid API key.
402Monthly quota exhausted on a hard-capped plan.
403Sender domain not verified/active, or account suspended.
413Message exceeds the 20 MB size limit.
429Rate limit exceeded — honour the Retry-After header.

Questions or missing features? Contact us — the API is versioned under /v1 and breaking changes will only ever ship under a new version prefix.