Invio batch
POST /v1/email/batches accetta fino a 100 payload di invio completi in una sola richiesta. Ogni elemento è un messaggio indipendente con mittente, destinatari e contenuto propri. Usa un batch per inviare ricevute, notifiche o altri messaggi per destinatario con meno richieste API. Per un singolo messaggio, vedi Invio di email.
Quando usare cosa
- Messaggi indipendenti già pronti. Usa un batch e consegnali tutti in una sola richiesta.
- Un flusso costante ad alto volume. Chiamare l'endpoint di invio singolo in un ciclo è un'architettura valida, e un batch non rende nessun singolo messaggio più economico o più veloce da recapitare. Quello che cambia è il throughput, perché le richieste batch attingono al gruppo di limitazione delle richieste email_batch anziché al gruppo email_send, e ciascuna può contenere fino a 100 messaggi.
- Una sola email a un pubblico salvato. Si tratta di un broadcast, che risolve il pubblico in destinatari e personalizza per contatto.
Invii batch
Il corpo della richiesta è un oggetto JSON il cui array messages contiene da 1 a 100 oggetti messaggio. Ogni elemento è una richiesta di invio completa e indipendente con i propri from, to, subject, contenuto e, facoltativamente, i propri category, ip_pool_id, tag e metadati. Lo schema dell'elemento è esattamente il payload di invio singolo, quindi tutto ciò che è descritto in invio di email si applica per elemento, incluso il valore predefinito category di marketing e l'invio tramite template.
Questo include scheduled_at, quindi un batch può mescolare messaggi da inviare subito con messaggi da inviare più tardi, ognuno al proprio orario. Le regole e i limiti descritti in invio programmato si applicano per elemento, e un elemento programmato viene annullato tramite il proprio ID come qualsiasi altro messaggio programmato.
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"
}
]
}'Validazione tutto-o-niente
Ogni elemento viene validato prima che qualsiasi elemento venga accodato. Se un messaggio fallisce, per un errore di validazione a livello di campo o un dominio mittente non verificato, l'intero batch viene rifiutato con un 422 e nulla viene inviato: correggi quell'elemento e reinvia il batch.
La soppressione non fa parte di quel controllo. Un elemento i cui destinatari sono tutti soppressi viene comunque accettato e riceve il proprio ID em_, e quei destinatari risultano come status: rejected una volta che il messaggio è stato elaborato (vedi soppressioni).
Gestire la risposta 202
Un batch riuscito restituisce 202 Accepted con una voce per messaggio, nell'ordine di invio:
Esempio di codice
{
"data": [
{ "id": "em_01ky7q1vmkerwa7fxyycfe5ks1", "status": "accepted", "category": "transactional" },
{ "id": "em_01ky7q1vmkesr9h1y52tkqng9f", "status": "accepted", "category": "marketing" },
{ "id": "em_01ky7q1vmkesyr1z1h4s48jjxm", "status": "accepted", "category": "transactional" }
]
}Ogni figlio è un messaggio ordinario: traccialo tramite il suo ID em_ attraverso GET /v1/email/messages/{message_id}, i suoi endpoint per destinatari ed eventi e i webhook, esattamente come se lo avessi inviato singolarmente. Si applica lo stesso modello asincrono, quindi 202 significa accettato in modo durevole e gli esiti per destinatario arrivano successivamente.
Ripetizioni idempotenti
Invia un header Idempotency-Key con il batch, come fa la richiesta di esempio. Se la richiesta è riuscita ma non hai mai visto la risposta, ripetendola con la stessa chiave ottieni il risultato originale, gli stessi ID dei messaggi figli e un header Idempotency-Replay, invece di inviare di nuovo tutti i messaggi. Un duplicato accidentale qui ti costa fino a 100 email, quindi considera la chiave obbligatoria in produzione. Vedi idempotenza.
Allegati e limite del corpo
Ogni elemento del batch può avere i propri attachments, con lo stesso contratto di campo e budget di dimensione per messaggio di un invio singolo (vedi allegati). Un ulteriore limite si applica al batch nel suo insieme: il corpo della richiesta JSON serializzato è limitato a 20 MB, e un corpo più grande viene rifiutato con un 413. Gli allegati codificati in Base64 contano in quel limite, quindi i batch con molti allegati lo raggiungono rapidamente. Suddividili in più batch oppure inviali uno alla volta.
Broadcast
Un broadcast invia una sola email a un pubblico salvato. Risolviamo i membri attuali del pubblico, meno le soppressioni, nella lista dei destinatari al momento dell'invio, e le proprietà di contatto di ciascun destinatario compilano le variabili del template. Avviane uno dalla dashboard, da /v1/email/broadcasts o con i comandi bird email broadcasts. Broadcast contiene la guida passo passo.
Prossimi passi
- Invio di email: il payload per elemento nel dettaglio, inclusi campi, limiti, tag e metadati a confronto
- Broadcast: una sola email a un pubblico salvato, personalizzata per contatto
- Categorie: marketing e transactional, e cosa comporta ciascuna per la politica di soppressione
- Idempotenza: formato della chiave, conservazione e semantica di ripetizione
- Riferimento API: gli schemi completi di richiesta e risposta del batch
- Inviare 100 email con una singola chiamata API: un video che mostra un batch in uscita e come ogni messaggio restituisce il suo esito
Risorse correlate
Prosegui con la documentazione, le guide e gli esempi per questo argomento. Le risorse sono in inglese.
Esplora la funzionalitàEmail batch sendingSegui il percorso di apprendimentoBuild your first integration
Ottieni un brief di implementazione