Create a batch of email messages
/v1/email/batchesconst batch = await bird.email.sendBatch({
messages: [
{
from: { email: "onboarding@messagebird.dev", name: "Bird" },
to: ["alice@example.com"],
subject: "Your receipt",
html: "<p>Thanks, Alice.</p>",
},
{
from: { email: "onboarding@messagebird.dev", name: "Bird" },
to: ["bob@example.com"],
subject: "Your receipt",
html: "<p>Thanks, Bob.</p>",
},
],
});
for (const item of batch.data) console.log(item.id, item.status);batch = client.email.send_batch(
messages=[
{
"from_": {"email": "onboarding@messagebird.dev", "name": "Bird"},
"to": ["delivered@messagebird.dev"],
"subject": "Hello from Bird",
"html": "<p>My first Bird email.</p>",
},
{
"from_": {"email": "onboarding@messagebird.dev", "name": "Bird"},
"to": ["someone-else@messagebird.dev"],
"subject": "Hello again from Bird",
"text": "My second Bird email.",
},
],
)
for item in batch.data:
print(item.id, item.status)package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
batch, err := client.Email.SendBatch(context.Background(), bird.EmailSendBatchParams{
Messages: []bird.EmailSendParams{
{
From: "onboarding@messagebird.dev",
To: []string{"alice@example.com"},
Subject: "Hello, Alice",
HTML: "<p>Welcome!</p>",
},
{
From: "onboarding@messagebird.dev",
To: []string{"bob@example.com"},
Subject: "Hello, Bob",
HTML: "<p>Welcome!</p>",
},
},
})
if err != nil {
log.Fatal(err)
}
for _, item := range batch.Data {
fmt.Println(item.Id)
}
}$batch = $bird->email->sendBatch(messages: [
(new EmailMessageSendRequest())
->setFrom((new EmailAddress())->setEmail('onboarding@messagebird.dev')->setName('Bird'))
->setTo([(new EmailAddress())->setEmail('delivered@messagebird.dev')])
->setSubject('Hello from Bird')
->setHtml('<p>My first Bird email.</p>'),
(new EmailMessageSendRequest())
->setFrom((new EmailAddress())->setEmail('onboarding@messagebird.dev')->setName('Bird'))
->setTo([(new EmailAddress())->setEmail('someone-else@messagebird.dev')])
->setSubject('Hello again from Bird')
->setText('My second Bird email.'),
]);
foreach ($batch->getData() ?? [] as $item) {
echo $item->getId(), ' ', $item->getStatus(), "\n";
}bird email send-batch --body-file - <<'JSON'
{
"messages": [
{
"from": {
"email": "noreply@acme.com",
"name": "Acme Support"
},
"to": [
{
"email": "delivered@messagebird.dev",
"name": "Jane Doe"
}
],
"subject": "Your receipt for order #1234",
"text": "Thanks for your purchase! Your receipt is attached."
},
{
"from": {
"email": "noreply@acme.com",
"name": "Acme Support"
},
"to": [
{
"email": "delivered@messagebird.dev",
"name": "John Roe"
}
],
"subject": "Your receipt for order #1235",
"text": "Thanks for your purchase! Your receipt is attached."
}
]
}
JSONcurl -X POST "https://us1.platform.bird.com/v1/email/batches" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"from": {
"email": "noreply@acme.com",
"name": "Acme Support"
},
"to": [
{
"email": "delivered@messagebird.dev",
"name": "Jane Doe"
}
],
"subject": "Your receipt for order #1234",
"text": "Thanks for your purchase! Your receipt is attached."
},
{
"from": {
"email": "noreply@acme.com",
"name": "Acme Support"
},
"to": [
{
"email": "delivered@messagebird.dev",
"name": "John Roe"
}
],
"subject": "Your receipt for order #1235",
"text": "Thanks for your purchase! Your receipt is attached."
}
]
}'{
"data": [
{
"id": "em_01krdgeqcxet5s7t44vh8rt9mg",
"status": "accepted",
"category": "marketing",
"requested_language": "pt-BR",
"resolved_language": "pt-BR",
"template_id": "emt_01krdgeqcxet5s7t44vh8rt9mg",
"template_version_id": "emv_01krdgeqcxet5s7t44vh8rt9mg"
},
{
"id": "em_01krdgeqcxet5s7t44vh8rt9mh",
"status": "accepted",
"category": "transactional",
"scheduled_at": "2026-05-22T09:00:00Z"
}
]
}
Accepts up to 100 independent email messages and queues them for delivery.
All items are validated before any are queued: if one fails validation, the
entire batch is rejected. Field-level validation failures and business-rule
failures, such as sending from a domain that is not verified, both return
422. An item can set scheduled_at to send it later, on the same terms as
a single scheduled send, and one batch can mix scheduled and immediate
messages. Cancel a scheduled item before it sends with
Cancel an email message.
Suppression is evaluated per recipient after acceptance, never as a
synchronous error. The 202 response returns one entry per message in
submission order, each with its own id you can use to fetch that message
or match it against webhook events. Attachments are allowed per message.
Each message must stay within the 20 MB estimated generated message-size
cap, and the serialized JSON request body for the whole batch has a hard
20 MB cap.
Supply caller values in template.parameters for each message.
Template sends support contact attributes on the same terms as individual
sends. Each To receives its own personalized email, and Cc and Bcc receive a
copy for each To. Copies do not need matching contacts. If a To address has
no matching contact when the template reads contact attributes, the entire
batch is rejected with 422 (E04099) before any item is accepted. Liquid
defaults do not waive that requirement. Values are saved at acceptance,
including for scheduled items.
Request Payload
messagesEmail message send requests, up to 100. All items are validated before any are queued. Attachments are allowed on individual messages. Each message must stay within the 20 MB estimated generated message-size cap. The serialized JSON request body for the batch has a hard 20 MB cap.
Response Payload
dataOne entry per message in the batch, in submission order.
संबंधित संसाधन
इस विषय के लिए दस्तावेज़, गाइड और उदाहरणों के साथ आगे बढ़ें।