Batch Send
Send up to 100 separate emails in a single API request. Every item in the batch is its own message with its own sender, recipients, subject and body — so this is not a mailing list blast, it is 100 individually addressed sends. Perfect for newsletters, campaign fan-out and bulk notifications.
400 BATCH_LIMIT_EXCEEDED. Each individual message in the batch is still capped at 50 recipients, the same per-message limit that applies on POST /email/send.Batch items support a subset of the send fields
Each item accepts to, subject, html, text, from, replyTo and tags. cc, bcc, attachments, custom headers and idempotency keys are only honoured on POST /email/send — send those messages one at a time.
Select Language
curl -X POST \
https://api.sendcomms.com/api/v1/email/batch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
{
"to": "user1@example.com",
"subject": "Welcome!",
"html": "<h1>Welcome User 1!</h1>",
"from": "Your App <hello@yourdomain.com>"
},
{
"to": "user2@example.com",
"subject": "Your receipt",
"text": "Thanks for your order.",
"from": "Billing <billing@yourdomain.com>",
"replyTo": "support@yourdomain.com"
},
{
"to": ["user3@example.com", "user4@example.com"],
"subject": "Team Update",
"html": "<p>Important team update...</p>",
"tags": [{ "name": "campaign", "value": "august" }]
}
]
}'Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| emails | array | Required | Non-empty array of email objects, maximum 100 per request |
| emails[].to | string | string[] | Required | Recipient email(s) for this message, up to 50 |
| emails[].subject | string | Required | Email subject line |
| emails[].html | string | Conditional | HTML content (required if no text) |
| emails[].text | string | Conditional | Plain text content (required if no html) |
| emails[].from | string | Optional | Sender for this message. Must be on a domain verified for your account, otherwise the whole batch is rejected with 400 UNVERIFIED_SENDER_DOMAIN. Display names are supported: "Acme <hello@acme.com>". If omitted, your primary verified domain is used |
| emails[].replyTo | string | Optional | Reply-To address for this message |
| emails[].tags | object[] | Optional | Per-message labels, each { name, value } |
Response Codes
Common Errors
| Code | Status | When it happens |
|---|---|---|
| BATCH_LIMIT_EXCEEDED | 400 | More than 100 emails in one request |
| INVALID_INPUT | 400 | emails is missing, not an array, or empty |
| MISSING_FIELD | 400 | An item is missing to or subject. The message names the offending index |
| MISSING_CONTENT | 400 | An item has neither html nor text |
| UNVERIFIED_SENDER_DOMAIN | 400 | A from address is not on a domain verified for your account |
Validation runs across the whole array before anything is sent, so a single bad item rejects the entire request and nothing is charged.
Response
Success Response
results comes back in the same order you submitted, each entry carrying its original index and the email_id you can match against webhook events.
{
"success": true,
"data": {
"batch_id": "batch_mjgc0ejr_3ca715bfb7a0",
"status": "sent",
"total_emails": 3,
"total_recipients": 4,
"from": "Your App <hello@yourdomain.com>",
"price": { "amount": 0.03, "currency": "USD" },
"results": [
{
"index": 0,
"email_id": "msg_8f21c0d4a97b",
"to": "user1@example.com",
"subject": "Welcome!"
},
{
"index": 1,
"email_id": "msg_1b7ee3390c42",
"to": "user2@example.com",
"subject": "Your receipt"
},
{
"index": 2,
"email_id": "msg_44de90ab1f05",
"to": ["user3@example.com", "user4@example.com"],
"subject": "Team Update"
}
],
"created_at": "2026-08-23T10:30:00.000000+00:00"
}
}