Skip to main content
POST /v1/email/messages/batch sends up to 100 messages in one call: an order confirmation to each of a hundred customers, each with its own recipients, subject and body. It takes the application’s live key with email:send, like a single send.
The body is a JSON array of 1 to 100 messages, or { "emails": [...] }; both are read the same way. Each message has the fields of a send: from, to, cc, bcc, reply_to, subject, html, text, reference, headers, tags and scheduled_at. No attachments in a batch: a message with files is refused (`emails[3].attachments` is not supported in a batch); send it on its own. The whole body is at most 10 MiB, else 413 request_too_large. A partner’s key names the application once, as ?application= in the query string, or on every message, the same for all.

The answer

202 Accepted with data: one message per item, in the order sent, each in the extended shape of a send’s answer.
Each message gets its own id, recipients, status and webhooks, and carries the batch’s id as batch_id when you read it.

All or nothing, or the valid ones

By default a batch is all or nothing. Every message is judged before anything is written: when any is refused, the answer is 422 batch_invalid, nothing is sent and nothing is charged, and errors names each refused message by its index (its place in the batch, from 0), with field and field_index for the value at fault:
With the header Tawked-Batch-Validation: permissive (Resend’s x-batch-validation: permissive works too), the valid messages are sent and the refused ones are listed in errors beside data. A refused item carries the extra fields of its error, such as host on a content_blocked (a link to a host on Tawked’s list of blocked hosts). A message whose every recipient is on the account’s suppression list is not a refusal: it is answered in data with the status failed, charges nothing, and never trips an all-or-nothing batch. A refusal about the account itself (early access, a pause, a hold on all of Tawked Email (503 service_unavailable), the rate, the daily limit, the balance) answers that refusal for the whole batch.

Limits and price

  • One request: a batch counts once against the account’s per-second rate, however many messages it holds.
  • Every recipient counts: the daily limit and the balance apply to all the batch’s e-mails together, each recipient one e-mail; the whole batch is charged in one go.
  • The same price as single sends: 3,000 emails free every month, then 100 halalas per 1,000.

Idempotency

One Idempotency-Key covers the whole batch. Sending the same batch again under it answers the first 202 exactly as it was, with Idempotent-Replayed: true, and sends nothing; another batch under the same key answers 409 idempotency_key_reused. A batch’s keys and single sends’ keys are separate: the same key used on both is two keys. A key is held for 24 hours.
Last modified on October 20, 2026