> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tawked.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sending in batches

> Send up to 100 different e-mails in one call, all or nothing by default, with one idempotency key for the whole batch.

`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.

```bash theme={"dark"}
curl -X POST https://tawked.com/v1/email/messages/batch \
  -H "Authorization: Bearer $TAWKED_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: orders-2026-10-21-0900" \
  -d '[
    {
      "from": "متجر أكمي <orders@acme.sa>",
      "to": ["sara@example.com"],
      "subject": "طلبك رقم 1042 قيد التجهيز",
      "html": "<p>استلمنا طلبك رقم 1042.</p>",
      "reference": "order-1042",
      "tags": [{ "name": "category", "value": "order" }]
    },
    {
      "from": "متجر أكمي <orders@acme.sa>",
      "to": ["ali@example.com"],
      "subject": "طلبك رقم 1043 قيد التجهيز",
      "html": "<p>استلمنا طلبك رقم 1043.</p>",
      "reference": "order-1043",
      "tags": [{ "name": "category", "value": "order" }]
    }
  ]'
```

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](https://docs.tawked.com/email/messages.md#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](https://docs.tawked.com/email/messages.md#recipients) of a send's answer.

```json theme={"dark"}
{
  "data": [
    {
      "id": "0199f1c2-8b01-7a20-9c3d-4e5f6a7b8c9d",
      "status": "accepted",
      "from": { "name": "متجر أكمي", "address": "orders@acme.sa" },
      "to": ["sara@example.com"],
      "cc": [],
      "bcc": [],
      "reply_to": [],
      "subject": "طلبك رقم 1042 قيد التجهيز",
      "reference": "order-1042",
      "tags": [{ "name": "category", "value": "order" }],
      "scheduled_at": null,
      "recipients": [
        { "id": "0199f1c2-8b02-7d41-8e5f-6a7b8c9d0e1f", "address": "sara@example.com", "name": null, "type": "to", "status": "queued" }
      ],
      "price_halalas": 0,
      "cost": { "emails": 1, "suppressed": 0, "free": 1, "billed": 0, "halalas": "0" },
      "created_at": "2026-10-21T12:00:00+03:00"
    }
  ]
}
```

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:

```json theme={"dark"}
{
  "error": "batch_invalid",
  "message": "No email was sent: fix the emails listed",
  "errors": [
    { "index": 1, "error": "invalid_destination", "message": "`to[0]` is not a valid e-mail address", "field": "to", "field_index": 0 }
  ]
}
```

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](https://docs.tawked.com/email/messages.md#the-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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.