Skip to content

Email

Send transactional emails, batch messages, and check delivery status. All email endpoints support idempotency via the Idempotency-Key header.

Send Email

POST
/email/send

Send a transactional email to one or more recipients

NameTypeRequiredDescription
tostring | string[]RequiredRecipient email address, or an array of up to 100 email addresses
subjectstringRequiredEmail subject line (max 998 characters)
htmlstringOptionalHTML body content. Required if text and template_id are not provided.
textstringOptionalPlain text body content. Required if html and template_id are not provided.
template_idstring (UUID)OptionalID of a saved template to use. Required if html and text are not provided.
template_dataRecord<string, string>OptionalKey-value pairs for template variable substitution using {{variable}} syntax
from_emailstringOptionalSender email address. Falls back to workspace default if not provided.
from_namestringOptionalSender display name (max 100 characters). Defaults to workspace setting or "TopMail".
reply_tostringOptionalReply-to email address
track_opensbooleanOptionalEnable open tracking. Defaults to true.
track_clicksbooleanOptionalEnable click tracking. Defaults to true.
send_atstring (ISO 8601)OptionalSchedule delivery for a future time. Must be within 72 hours.
curl -X POST https://api.topmail.so/api/v1/email/send \
-H "Authorization: Bearer tm_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Welcome to TopMail",
"html": "<h1>Hello {{first_name}}</h1><p>Thanks for signing up!</p>",
"from_email": "hello@yourdomain.com",
"from_name": "Your App",
"reply_to": "support@yourdomain.com",
"track_opens": true,
"track_clicks": true
}'
{
"data": {
"sent": 1,
"failed": 0,
"skipped": 0,
"total": 1,
"results": [
{
"to": "user@example.com",
"message_id": "ses-message-id-12345",
"success": true
}
]
}
}

Multiple Recipients

Pass an array of up to 100 email addresses in the to field. Each recipient is processed independently -- suppressed or invalid addresses are skipped without failing the entire request. The response includes per-recipient results.

Scheduled Sends

Include a send_at parameter with an ISO 8601 datetime to schedule an email for future delivery. The schedule must be within 72 hours from the current time.

curl -X POST https://api.topmail.so/api/v1/email/send \
-H "Authorization: Bearer tm_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Your weekly digest",
"html": "<h1>Weekly Digest</h1><p>Here are your updates...</p>",
"send_at": "2025-01-15T09:00:00Z"
}'

Sandbox Mode

When using a sandbox API key (prefixed with tm_test_), emails are not actually sent. The API returns mock success responses with simulated message IDs, allowing you to test your integration without sending real emails or consuming your email quota.

Batch Send

POST
/email/batch

Send up to 1,000 emails in a single request. Each message can have unique content, recipients, and settings.

Each item in the messages array accepts the same fields as the single send endpoint (except send_at), but with a single to address per message.

NameTypeRequiredDescription
messagesarrayRequiredArray of 1-1,000 message objects
messages[].tostringRequiredRecipient email address
messages[].subjectstringRequiredEmail subject line
messages[].htmlstringOptionalHTML body content
messages[].textstringOptionalPlain text body content
messages[].template_idstring (UUID)OptionalTemplate ID to use
messages[].template_dataRecord<string, string>OptionalTemplate variable substitution
messages[].from_emailstringOptionalSender email (defaults to workspace setting)
messages[].from_namestringOptionalSender display name
messages[].reply_tostringOptionalReply-to address
messages[].track_opensbooleanOptionalEnable open tracking (default: true)
messages[].track_clicksbooleanOptionalEnable click tracking (default: true)
curl -X POST https://api.topmail.so/api/v1/email/batch \
-H "Authorization: Bearer tm_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"to": "alice@example.com",
"subject": "Your order shipped!",
"html": "<p>Hi Alice, your order #1234 is on the way.</p>"
},
{
"to": "bob@example.com",
"subject": "Your order shipped!",
"html": "<p>Hi Bob, your order #5678 is on the way.</p>"
}
]
}'
{
"data": {
"batch_id": "batch-uuid-12345",
"status": "completed",
"total": 2,
"sent": 2,
"failed": 0
}
}

Batch Status

GET
/email/batch/:batchId

Check the status of a batch send

NameTypeRequiredDescription
batchIdstringRequiredThe batch ID returned from the batch send endpoint (URL parameter)
curl https://api.topmail.so/api/v1/email/batch/batch-uuid-12345 \
-H "Authorization: Bearer tm_live_abc123"
{
"data": {
"batch_id": "batch-uuid-12345",
"status": "completed",
"total": 100,
"sent": 98,
"failed": 2,
"created_at": "2025-01-15T08:30:00.000Z",
"completed_at": "2025-01-15T08:30:45.000Z"
}
}

Message Status

GET
/email/:messageId/status

Look up the delivery status of a sent message

NameTypeRequiredDescription
messageIdstringRequiredThe SES message ID returned from the send endpoint (URL parameter)
curl https://api.topmail.so/api/v1/email/ses-message-id-12345/status \
-H "Authorization: Bearer tm_live_abc123"
{
"data": {
"message_id": "ses-message-id-12345",
"status": "delivered",
"to": "user@example.com",
"sent_at": "2025-01-15T08:30:00.000Z",
"delivered_at": "2025-01-15T08:30:02.000Z",
"opened_at": "2025-01-15T09:15:30.000Z",
"clicked_at": "2025-01-15T09:16:00.000Z",
"bounced_at": null,
"bounce_type": null
}
}

Idempotency

The send and batch endpoints support idempotent requests to prevent duplicate sends caused by network retries. Include an Idempotency-Key header with a unique value (e.g., a UUID). If a request with the same key has already been processed, the original response will be returned without resending the email.

curl -X POST https://api.topmail.so/api/v1/email/send \
-H "Authorization: Bearer tm_live_abc123" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-12345" \
-d '{
"to": "user@example.com",
"subject": "Order confirmation",
"html": "<p>Your order has been confirmed.</p>"
}'
Developer Docs - TopMail