Skip to content

Batch Send

POST /api/v1/messages/batch

Required permission: send

Send up to 500 emails in a single request. Each message is processed independently — a suppressed recipient in the batch does not block the others.


Request body

{
"messages": [
{
"from_email": "hello@yourdomain.com",
"from_name": "Your App",
"to_email": "alice@example.com",
"to_name": "Alice",
"subject": "Your weekly report",
"body": "<p>Hi Alice, here is your report.</p>"
},
{
"from_email": "hello@yourdomain.com",
"to_email": "bob@example.com",
"subject": "Your weekly report",
"body": "<p>Hi Bob, here is your report.</p>",
"reply_to": "reports@yourdomain.com"
}
]
}

Each message in the array supports the same fields as Send Email, including reply_to and attachments.

Limits:

  • Maximum 500 messages per request
  • Each message is validated and size-checked independently

Response

HTTP 202 Accepted

{
"status": "success",
"data": {
"accepted": 498,
"rejected": 2,
"message_ids": ["uuid-1", "uuid-2", "..."],
"suppressed": [
{ "email": "unsubscribed@example.com", "reason": "unsubscribe" },
{ "email": "bounced@example.com", "reason": "hard_bounce" }
]
}
}
FieldDescription
acceptedNumber of messages queued for delivery
rejectedNumber of messages skipped (suppressed recipients)
message_idsUUIDs for accepted messages, in order
suppressedList of skipped recipients with suppression reason

Code examples

const messages = users.map(user => ({
from_email: 'hello@yourdomain.com',
from_name: 'Your App',
to_email: user.email,
to_name: user.name,
subject: `Hi ${user.name}, your report is ready`,
body: `<p>Hello ${user.name},</p><p>Your weekly report is attached.</p>`,
}));
const response = await fetch('https://api.emitlo.com/api/v1/messages/batch', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ messages }),
});
const { data } = await response.json();
console.log(`Sent: ${data.accepted}, Skipped: ${data.rejected}`);

Handling suppressed recipients

Suppressed recipients are silently skipped — they don’t cause the whole batch to fail. Check the suppressed array in the response to identify which addresses were skipped and why:

ReasonDescription
hard_bounceAddress previously hard-bounced
complaintRecipient previously marked as spam
unsubscribeRecipient previously unsubscribed
manualManually added to suppression list

See Suppressions for more details.