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

# Send a batch

> POST /v1/emails/batch — queue up to 100 emails in a single request.

Queue up to 100 emails in one request. Each item is an independent send — the batch returns a result per item, in order, so a single bad recipient never fails the rest.

**`POST /v1/emails/batch`**

The body is an `emails` array, where each element is exactly the same shape as a single [`POST /v1/emails`](/api-reference/emails/send) body. Counts as one request against your rate limit.

## Body parameters

<ParamField body="emails" type="object[]" required>
  Between 1 and 100 send objects. Each item accepts the full [send-email body](/api-reference/emails/send) — `from`, `to`, `subject`, `html`/`text` or `templateId` + `data`, attachments, tags, and so on.
</ParamField>

## Headers

<ParamField header="X-Drin-Product" type="header">
  Names the sending project for account-wide keys (alias: `X-Drin-Sender`). Project-scoped keys may omit it.
</ParamField>

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.drin.run/v1/emails/batch \
    -H "Authorization: Bearer $DRIN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "emails": [
        {
          "from": { "email": "hello@yourdomain.com" },
          "to": [{ "email": "a@example.com" }],
          "subject": "Receipt #1",
          "html": "<p>Thanks!</p>"
        },
        {
          "from": { "email": "hello@yourdomain.com" },
          "to": [{ "email": "b@example.com" }],
          "subject": "Receipt #2",
          "html": "<p>Thanks!</p>"
        }
      ]
    }'
  ```

  ```typescript Node.js theme={null}
  import { DrinClient } from "@drin00/sdk";

  const drin = new DrinClient({ apiKey: process.env.DRIN_API_KEY });

  const { data } = await drin.emails.sendMany([
    {
      from: { email: "hello@yourdomain.com" },
      to: [{ email: "a@example.com" }],
      subject: "Receipt #1",
      html: "<p>Thanks!</p>",
    },
    {
      from: { email: "hello@yourdomain.com" },
      to: [{ email: "b@example.com" }],
      subject: "Receipt #2",
      html: "<p>Thanks!</p>",
    },
  ]);

  for (const item of data) {
    if (item.error) console.error(item.error.type, item.error.message);
    else console.log("queued", item.id);
  }
  ```
</CodeGroup>

## Response

`207 Multi-Status` — a `data` array aligned to your input order. Each element either carries an `id` (the message was queued) or an `error` with the usual `{ type, message, param? }` envelope. Always inspect every element; a `207` does *not* mean every send succeeded.

```json 207 Multi-Status theme={null}
{
  "data": [
    { "id": "msg_01HZX9K3T2QF7P0M4N8B6C5D" },
    {
      "error": {
        "type": "suppressed",
        "message": "Recipient is on the suppression list.",
        "param": "to"
      }
    }
  ]
}
```

<Warning>
  **Per-item, not all-or-nothing.** The batch isn't transactional. Items that validate are queued even when siblings fail. Match results to inputs by array index, and retry only the failed items.
</Warning>

<Note>
  **One template, many recipients.** To send the same template to many people, set the same `templateId` on each item and vary `to` and `data`. See [Batch & scheduled](/sending/batch).
</Note>
