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
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.
{
"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
{
"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
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
# 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
| Status | Code | Meaning | How to fix |
|---|---|---|---|
| Client error400 | VALIDATION_ERROR | Invalid recipients, missing subject, or bad attachment data. | Check the request body against the fields above. |
| Client error400 | SUPPRESSED | All recipients are on a suppression/DND list. | Remove suppressed recipients from your list. |
| Client error402 | INSUFFICIENT_BALANCE | Wallet balance is below the cost of the send. | Top up your wallet and retry. |
| Client error403 | FORBIDDEN | Your email/phone isn't verified, or the sender identity isn't allowed. | Verify your identity; use a permitted from_address. |
| Client error429 | RATE_LIMITED | Sending faster than 2 emails/sec. | Throttle to below the rate limit or batch larger payloads. |
| Server error502 | PROVIDER_ERROR | The upstream SMTP provider failed. | Wait and retry; your balance is refunded on failure. |