Batchverzending
POST /v1/email/batches accepteert tot 100 complete verzendpayloads in één request. Elk item is een onafhankelijk bericht met een eigen afzender, ontvangers en inhoud. Gebruik een batch om bonnen, meldingen of andere per-ontvanger-berichten met minder API-requests te versturen. Zie E-mail verzenden voor één bericht.
Wanneer wat gebruiken
- Onafhankelijke berichten die je al klaar hebt. Gebruik een batch en lever ze in één request aan.
- Een constante stroom met hoog volume. Het single-send-endpoint in een lus aanroepen is een degelijke architectuur, en een batch maakt geen enkel bericht goedkoper of sneller om te bezorgen. Wat het verandert is doorvoer, omdat batchrequests de email_batch-rate-limitgroep gebruiken in plaats van de email_send-groep, en elk request tot 100 berichten bevat.
- Eén e-mail naar een opgeslagen doelgroep. Dat is een broadcast, die de doelgroep omzet in ontvangers en per contact personaliseert.
Batch versturen
De request-body is een JSON-object waarvan de messages-array 1 tot 100 berichtobjecten bevat. Elk item is een volledig, onafhankelijk verzendrequest met een eigen from, to, subject, inhoud, en optioneel een eigen category, ip_pool_id, tags en metadata. Het itemschema is exact de single-send-payload, dus alles in e-mail verzenden geldt per item, inclusief de category-standaard van marketing en verzending per template.
Dat omvat scheduled_at, dus een batch kan berichten die nu uitgaan mengen met berichten die later uitgaan, elk op een eigen tijdstip. De regels en ruimte in geplande verzending gelden per item, en een gepland item wordt geannuleerd via zijn eigen ID, net als elk ander gepland bericht.
const 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."
}
]
}
JSON{
"name": "email_send_batch",
"arguments": {
"messages": [
{
"from": {
"email": "noreply@acme.com",
"name": "Acme Support"
},
"subject": "Your receipt for order #1234",
"text": "Thanks for your purchase! Your receipt is attached.",
"to": [
{
"email": "delivered@messagebird.dev",
"name": "Jane Doe"
}
]
},
{
"from": {
"email": "noreply@acme.com",
"name": "Acme Support"
},
"subject": "Your receipt for order #1235",
"text": "Thanks for your purchase! Your receipt is attached.",
"to": [
{
"email": "delivered@messagebird.dev",
"name": "John Roe"
}
]
}
]
}
}curl -X POST https://us1.platform.bird.com/v1/email/batches \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-07-23-001" \
-d '{
"messages": [
{
"from": "hello@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"subject": "Your receipt",
"html": "<p>Thanks for your order.</p>",
"category": "transactional"
},
{
"from": "newsletter@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"subject": "June product news",
"html": "<p>What shipped this month.</p>",
"category": "marketing"
},
{
"from": "alerts@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"subject": "Usage threshold reached",
"text": "You have used 80% of your quota.",
"category": "transactional"
}
]
}'Alles-of-nietsvalidatie
Elk item wordt gevalideerd voordat een item in de wachtrij komt. Als één bericht faalt, een validatiefout op veldniveau of een niet-geverifieerd afzenderdomein, wordt de hele batch afgewezen met een 422 en er wordt niets verstuurd: los dat item op en verstuur de batch opnieuw.
Suppressie maakt geen deel uit van die controle. Een item waarvan alle ontvangers onderdrukt zijn, wordt toch geaccepteerd en krijgt een eigen em_-ID, en die ontvangers komen terug als status: rejected zodra het bericht is verwerkt (zie suppressies).
Het 202-antwoord verwerken
Een geslaagde batch retourneert 202 Accepted met één item per bericht, in inzendvolgorde:
Codevoorbeeld
{
"data": [
{ "id": "em_01ky7q1vmkerwa7fxyycfe5ks1", "status": "accepted", "category": "transactional" },
{ "id": "em_01ky7q1vmkesr9h1y52tkqng9f", "status": "accepted", "category": "marketing" },
{ "id": "em_01ky7q1vmkesyr1z1h4s48jjxm", "status": "accepted", "category": "transactional" }
]
}Elk child is een gewoon bericht: volg het aan de hand van zijn em_-ID via GET /v1/email/messages/{message_id}, de ontvanger- en event-endpoints, en webhooks, precies alsof je het apart had verstuurd. Hetzelfde asynchrone model geldt, dus 202 betekent duurzaam geaccepteerd en per-ontvanger-uitkomsten komen daarna binnen.
Idempotent opnieuw proberen
Stuur een Idempotency-Key-header mee met de batch, zoals het voorbeeldrequest doet. Als het request is geslaagd maar je het antwoord nooit hebt gezien, levert het opnieuw versturen met dezelfde sleutel het oorspronkelijke resultaat op, dezelfde child-bericht-ID's en een Idempotency-Replay-header, in plaats van elk bericht opnieuw te versturen. Eén per ongeluk dubbel request kost je hier tot 100 e-mails, dus behandel de sleutel als verplicht in productie. Zie idempotency.
Bijlagen en de body-limiet
Elk batchitem kan eigen attachments hebben, met hetzelfde veldcontract en dezelfde groottelimiet per bericht als een enkele verzending (zie bijlagen). Er geldt nog een limiet voor de batch als geheel: de geserialiseerde JSON-request-body is begrensd op 20 MB, en een grotere body wordt afgewezen met een 413. Base64-gecodeerde bijlagen tellen mee, dus bijlage-intensieve batches bereiken de limiet snel. Splits ze over meerdere batches, of verstuur ze één voor één.
Broadcasts
Een broadcast stuurt één e-mail naar een opgeslagen doelgroep. We zetten de huidige leden van de doelgroep om in de ontvangerslijst, minus suppressies, wanneer de verzending start, en de contacteigenschappen van elke ontvanger vullen de variabelen van het template. Start er een vanuit het dashboard, vanuit /v1/email/broadcasts, of met de bird email broadcasts-commando's. Broadcasts bevat de stapsgewijze uitleg.
Vervolgstappen
- E-mail verzenden: de volledige per-item-payload, inclusief velden, limieten, en tags vs. metadata
- Broadcasts: één e-mail naar een opgeslagen doelgroep, gepersonaliseerd per contact
- Categorieën: marketing en transactional, en wat elk doet met het suppressiebeleid
- Idempotency: sleutelformaat, retentie en replay-semantiek
- API-referentie: de volledige batch-request- en response-schema's
- 100 e-mails verzenden in één API-aanroep: een video die laat zien hoe een batch uitgaat en hoe elk bericht terugrapporteert
Gerelateerde bronnen
Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.