# Send a batch

> POST /emails/batch — send up to 100 emails in one request.

`POST /emails/batch`

Send up to 100 emails in a single request. The body is a JSON **array** of email objects, each with the same shape as a [single send](https://www.sendping.co/docs/api/emails-send). Every item is validated before any email is sent; if one fails validation, the whole batch is rejected and nothing is sent. See [Batch sending](https://www.sendping.co/docs/emails/batch).

> **Note:** A small batch returns `200` once every email has been sent; a large one returns **`202`** with `queued: true` and is delivered by the background sender. Both bodies carry `data` with one id per email in request order, so a client that reads `data` needs no change. [Batch delivery modes](https://www.sendping.co/docs/api/emails-batch-delivery) covers the boundary, following a queued batch, and the `batch_incomplete` case.

## Body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `(array)` | object[] | Yes | An array of 1–100 email objects. Each object accepts the same fields as `POST /emails` (`from`, `to`, `subject`, `html`/`text`, `cc`, `bcc`, `reply_to`, `headers`, `topic_id`, `template`). |

> **Warning:** The `attachments` and `scheduled_at` fields are **not supported** on the batch endpoint. An optional `Idempotency-Key` header (max 255 characters, expires after 24 hours) applies to the whole batch.

## Request

**Node.js**

```js
import { SendPing } from 'sendping';

const mb = new SendPing('mb_xxxxxxxxx');

const { data, error } = await mb.batch.send([
  { "from": "Acme <hello@yourdomain.com>", "to": ["delivered+a@test.sendping.co"], "subject": "Hi A", "html": "<p>Hello A</p>" },
  { "from": "Acme <hello@yourdomain.com>", "to": ["delivered+b@test.sendping.co"], "subject": "Hi B", "html": "<p>Hello B</p>" }
]);
console.log({ data, error });
```

**Ruby**

```ruby
require "sendping"

SendPing.api_key = "mb_xxxxxxxxx"

SendPing::Batch.send([
  {
    "from": "Acme <hello@yourdomain.com>",
    "to": [
      "delivered+a@test.sendping.co"
    ],
    "subject": "Hi A",
    "html": "<p>Hello A</p>"
  },
  {
    "from": "Acme <hello@yourdomain.com>",
    "to": [
      "delivered+b@test.sendping.co"
    ],
    "subject": "Hi B",
    "html": "<p>Hello B</p>"
  }
])
```

**PHP**

```php
<?php
require 'vendor/autoload.php';

use SendPing\SendPing;

$sendping = SendPing::client('mb_xxxxxxxxx');

$sendping->batch->send([
  [
    'from' => "Acme <hello@yourdomain.com>",
    'to' => [
      "delivered+a@test.sendping.co"
    ],
    'subject' => "Hi A",
    'html' => "<p>Hello A</p>"
  ],
  [
    'from' => "Acme <hello@yourdomain.com>",
    'to' => [
      "delivered+b@test.sendping.co"
    ],
    'subject' => "Hi B",
    'html' => "<p>Hello B</p>"
  ]
]);
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Batch.send([
  {
    "from": "Acme <hello@yourdomain.com>",
    "to": [
      "delivered+a@test.sendping.co"
    ],
    "subject": "Hi A",
    "html": "<p>Hello A</p>"
  },
  {
    "from": "Acme <hello@yourdomain.com>",
    "to": [
      "delivered+b@test.sendping.co"
    ],
    "subject": "Hi B",
    "html": "<p>Hello B</p>"
  }
])
```

**Go**

```go
import "github.com/shekhu10/sendping-sdks/sendping-go"

client := sendping.NewClient("mb_xxxxxxxxx")

batch, err := client.Batch.SendEmails([]*sendping.BatchEmailRequest{
    {
        From:    "Acme <hello@yourdomain.com>",
        To:      []string{"delivered+a@test.sendping.co"},
        Subject: "Hi A",
        Html:    "<p>Hello A</p>",
    },
    {
        From:    "Acme <hello@yourdomain.com>",
        To:      []string{"delivered+b@test.sendping.co"},
        Subject: "Hi B",
        Html:    "<p>Hello B</p>",
    },
})
```

**Rust**

```rust
use sendping::{BatchEmailOptions, SendPing};

let mb = SendPing::new("mb_xxxxxxxxx");

let items = vec![
    BatchEmailOptions::new(
        "Acme <hello@yourdomain.com>",
        ["delivered+a@test.sendping.co"],
        "Hi A",
    )
    .with_html("<p>Hello A</p>"),
    BatchEmailOptions::new(
        "Acme <hello@yourdomain.com>",
        ["delivered+b@test.sendping.co"],
        "Hi B",
    )
    .with_html("<p>Hello B</p>"),
];
let _batch = mb.batch.send_emails(items).await?;
```

**Java**

```java
import co.sendping.SendPing;
import co.sendping.SendPingResponse;
import co.sendping.requests.BatchEmailRequest;
import java.util.List;

SendPing sendping = new SendPing("mb_xxxxxxxxx");

List<BatchEmailRequest> requests = List.of(
        BatchEmailRequest.builder()
                .from("Acme <hello@yourdomain.com>")
                .to("delivered+a@test.sendping.co")
                .subject("Hi A")
                .html("<p>Hello A</p>")
                .build(),
        BatchEmailRequest.builder()
                .from("Acme <hello@yourdomain.com>")
                .to("delivered+b@test.sendping.co")
                .subject("Hi B")
                .html("<p>Hello B</p>")
                .build());

SendPingResponse response = sendping.batch().sendEmails(requests);
```

**.NET**

```csharp
using SendPing;

ISendPing sendping = SendPingClient.Create("mb_xxxxxxxxx");

var resp = await sendping.EmailBatchSendAsync(new List<BatchEmailMessage>
{
    new()
    {
        From = "Acme <hello@yourdomain.com>",
        To = "delivered+a@test.sendping.co",
        Subject = "Hi A",
        HtmlBody = "<p>Hello A</p>",
    },
    new()
    {
        From = "Acme <hello@yourdomain.com>",
        To = "delivered+b@test.sendping.co",
        Subject = "Hi B",
        HtmlBody = "<p>Hello B</p>",
    },
});
```

**cURL**

```bash
curl -X POST 'https://www.sendping.co/api/emails/batch' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '[
  { "from": "Acme <hello@yourdomain.com>", "to": ["delivered+a@test.sendping.co"], "subject": "Hi A", "html": "<p>Hello A</p>" },
  { "from": "Acme <hello@yourdomain.com>", "to": ["delivered+b@test.sendping.co"], "subject": "Hi B", "html": "<p>Hello B</p>" }
]'
```

**CLI**

```bash
sendping emails batch \
  --data '[{"from":"Acme <hello@yourdomain.com>","to":["delivered+a@test.sendping.co"],"subject":"Hi A","html":"<p>Hello A</p>"},{"from":"Acme <hello@yourdomain.com>","to":["delivered+b@test.sendping.co"],"subject":"Hi B","html":"<p>Hello B</p>"}]'
```

## Response

A `data` array of created emails, in request order.

```json
{
  "data": [
    { "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794" },
    { "id": "1b2c3d4e-5f60-7a8b-9c0d-1e2f3a4b5c6d" }
  ]
}
```

## Errors

Returns `validation_error` if the body is not a non-empty array, if it contains more than 100 emails, or if any item fails validation (the failing item's error is returned and nothing is sent). See the [error reference](https://www.sendping.co/docs/api/errors).
