Batch Send
Send up to 100 emails in a single API call with per-message validation and partial success support. Drains to AWS SES at ~12 emails/sec.
The batch endpoint queues multiple emails in a single request. Each message is validated independently — invalid messages are skipped and reported in the response without affecting valid ones.
Key features:
• Up to 100 messages per batch
• Per-message validation and error reporting
• Template resolution per message
• Idempotency support via X-Idempotency-Key header
• Rate limits are consumed atomically for the batch size
• Scheduled emails (scheduledFor) are NOT supported in batch mode
---
## Throughput & SES rate limit
AWS SES enforces a per-account **maximum send rate** — currently **14 emails per second** for the Posthawk Cloud account. Exceeding this rate triggers `ThrottlingException` errors from SES, and repeated throttling can affect your sending reputation.
To stay safely under the SES ceiling, the Posthawk worker rate-limits SES dispatch to **12 emails per second** across all queue workers (configured via BullMQ `limiter: { max: 12, duration: 1000 }`). This leaves a small headroom for retries and avoids brushing against the SES limit.
What this means for batch sends:
• A 100-message batch is **accepted instantly** (validated and queued in BullMQ) but **drains to SES over ~8 seconds** (100 ÷ 12 ≈ 8.3s).
• The API responds with `success: true, queued: N` as soon as messages are queued, not when they hit SES.
• Status tracking via `GET /v1/send/:jobId` lets you observe the drain in real time.
• If you need higher throughput, contact AWS to request an SES sending-rate increase. After approval, the Posthawk worker limit can be raised to match (the ceiling is configurable per deployment).
The same 12/sec ceiling applies to **all** outbound paths combined — API `/v1/send`, batch `/v1/batch`, scheduled emails firing, broadcast fan-out, newsletter issue sends, and SMTP relay all share the queue.POST
/v1/batchAPI KeySend a batch of up to 100 emails. Each message is validated independently. Returns per-message results with success/failure status.
| Parameter | Type | In | Description |
|---|---|---|---|
messagesrequired | array | body | Array of email objects (1-100). Each object has the same fields as POST /v1/send (from, to, subject, html, text, templateId, variables, headers, metadata, tags). |
Request
bash
{
"messages": [
{
"from": "hello@yourdomain.com",
"to": ["user1@example.com"],
"subject": "Welcome!",
"html": "<h1>Hello User 1</h1>"
},
{
"from": "hello@yourdomain.com",
"to": ["user2@example.com"],
"subject": "Welcome!",
"templateId": "welcome-template",
"variables": { "name": "User 2" }
}
]
}Response
json
{
"success": true,
"results": [
{ "index": 0, "success": true, "jobId": "abc123" },
{ "index": 1, "success": true, "jobId": "def456" }
],
"total": 2,
"queued": 2,
"failed": 0
}