Outbound email

Sending Email

Send transactional email programmatically — single messages, batches, attachments, and templates — from the platform sender or your own verified sending domain.


Send transactional email (receipts, OTPs, invoices, alerts) with a single call. Sends are debited from your wallet before dispatch at a flat 5 TZS per recipient — platform sender or your own verified domain, no difference — and refunded if delivery fails. No subscription plans.

Send one message

bash
curl -X POST https://api.mailafrica.online/api/outbound/emails \
  -H "X-API-Key: MAIL_<your_api_key_here>" \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["customer@example.com"],
    "subject": "Your receipt",
    "text_body": "Thanks for your order #482.",
    "html_body": "<p>Thanks for your order <strong>#482</strong>.</p>",
    "from_domain_id": 2,
    "from_address": "noreply@yourcompany.co.tz"
  }'

Fields: to (array of recipients; cc/bcc arrays also accepted), subject, html_body and/or text_body, attachments (max 10), template_id + variables, from_domain_id, from_address.

json
{
  "success": true,
  "data": {
    "id": 3100,
    "user_id": 7,
    "from_address": "noreply@yourcompany.co.tz",
    "to_addresses": ["customer@example.com"],
    "subject": "Your receipt",
    "html_body": "...",
    "status": "sent",
    "provider_message_id": "external-id",
    "amount_tzs": 5,
    "created_at": "2026-08-15T10:00:00Z"
  }
}

Sending from your own verified domain requires the from_domain_id and a matching from_address (the domain's default local part or one of its sender addresses). Without a from_domain_id, mail goes out from the platform sender — and you can still customize the local part by passing a from_address on the platform domain, e.g. food@mailafrica.online (any other domain is rejected).

Attachments

json
{
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content_type": "application/pdf",
      "size": 20480,
      "data_base64": "JVBERi0xLjQK..."
    }
  ]
}

Limit 10 attachments per message, each up to 10 MiB, 20 MiB total. Provide the file content base64-encoded in data_base64.

Batch sending

bash
curl -X POST https://api.mailafrica.online/api/outbound/emails/batch \
  -H "X-API-Key: MAIL_<your_api_key_here>" \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["a@example.com", "b@example.com"],
    "subject": "System notice",
    "text_body": "Scheduled maintenance tonight."
  }'

Batch is a flat recipient list (no cc/bcc), automatically chunked into groups of 50. The response reports total, sent, failed, and the per-message list.

History

bash
# Paginated list
curl "https://api.mailafrica.online/api/outbound/emails?page=1&per_page=20" \
  -H "X-API-Key: MAIL_<your_api_key_here>"

# One message + per-recipient status
curl https://api.mailafrica.online/api/outbound/emails/3100 \
  -H "X-API-Key: MAIL_<your_api_key_here>"

The detail response includes recipients, each with its own status (sent | failed), provider code, and timestamps.

Errors

StatusCodeMeaningHow to fix
Client error400VALIDATION_ERRORInvalid recipients, missing subject, or bad attachment data.Check the request body against the fields above.
Client error400SUPPRESSEDAll recipients are on a suppression/DND list.Remove suppressed recipients from your list.
Client error402INSUFFICIENT_BALANCEWallet balance is below the cost of the send.Top up your wallet and retry.
Client error403FORBIDDENYour email/phone isn't verified, or the sender identity isn't allowed.Verify your identity; use a permitted from_address.
Client error429RATE_LIMITEDSending faster than 2 emails/sec.Throttle to below the rate limit or batch larger payloads.
Server error502PROVIDER_ERRORThe upstream SMTP provider failed.Wait and retry; your balance is refunded on failure.