Invio email

Un'unica API per ogni email che invii.

Configura in:

Transazionale o di marketing, un solo messaggio o un centinaio, inviati attraverso la stessa Email API, con idempotenza, soppressione e webhook integrati. Passa HTML grezzo o renderizza i tuoi template React Email.

welcome.tsx
200 · 1.2s
import { BirdClient } from "@messagebird/sdk";
import { render } from "@react-email/render";
import { WelcomeEmail } from "./emails/welcome";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const { data, error } = await bird.email.send({
  from:    "Bird <hello@bird.com>",
  to:      ["ada@example.com"],
  subject: "Your invite is ready",
  html:    await render(<WelcomeEmail name="Ada" />),
}).safe();

if (error) throw error;
console.log(data.id);
// → "em_2bX91Yk8h..."

Invia la tua prima email in cinque minuti.

Dal linguaggio che già usi.

L'invio è il cuore della Bird Email API. Il primo invio può andare a un indirizzo di test autorizzato (delivered@messagebird.dev), così puoi provare l'intera piattaforma (invii, webhook, soppressione) prima di verificare un dominio.

1
2
3
4
5
6
7
8
9
10
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const { data, error } = await bird.email.send({
  from:    "you@yourdomain.com",
  to:      ["delivered@bird.dev"],
  subject: "Hello from Node",
  html:    "<p>It works.</p>",
}).safe();

Cinque cose che non devi costruire tu.

Lo stesso contratto su ogni canale Bird.

  1. 01

    Transazionale e marketing.

    Lo stesso endpoint invia un reset della password o una campagna. Un campo category determina come si applicano soppressione e disiscrizioni.

  2. 02

    Template a modo tuo.

    Passa HTML grezzo, oppure renderizza i template React Email in HTML nella tua app e invia il risultato. La tua toolchain, invariata.

  3. 03

    Batch fino a 100.

    Fino a 100 messaggi indipendenti per chiamata, ciascuno con destinatario e variabili propri, validati come un'unica unità così da non inviare mai a metà.

  4. 04

    Idempotente per contratto.

    Ogni invio accetta una chiave di idempotenza, così una richiesta riprovata dopo un timeout restituisce il risultato originale invece di inviare due volte.

  5. 05

    Un webhook a ogni cambio di stato.

    Accettata, recapitata, aperta, cliccata, respinta, segnalata come spam. Ognuna firmata in HMAC, protetta dai replay, idempotente, con la stessa struttura su ogni canale.

Invii già da un'altra parte? Passa a Bird in un pomeriggio.

La chiamata che fai già cambia appena: sostituisci il client, mantieni i tuoi template, punta i tuoi webhook a un solo endpoint. Le guide alla migrazione coprono SendGrid, Amazon SES, Mailgun e Resend.

sendgrid.ts
SendGrid
import sgMail from "@sendgrid/mail";

sgMail.setApiKey(process.env.SENDGRID_API_KEY!);

await sgMail.send({
  from:    "hello@bird.com",
  to:      "ada@example.com",
  subject: "Your invite is ready",
  html:    "<p>Welcome aboard, Ada.</p>",
});
bird.ts
Bird
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

await bird.email.send({
  from:    "hello@bird.com",
  to:      ["ada@example.com"],
  subject: "Your invite is ready",
  html:    "<p>Welcome aboard, Ada.</p>",
});

Un messaggio o un centinaio, una sola chiamata.

Raggruppa fino a 100 messaggi indipendenti in una sola richiesta, ciascuno con il proprio destinatario e le proprie variabili. Il batch viene validato come un'unità: un solo messaggio errato fa fallire la chiamata con un 422, così non invii mai a metà. Una singola chiave di idempotenza rende l'intera richiesta sicura da ripetere.

digest.ts
202 · batch
import { BirdClient } from "@messagebird/sdk";
import { render } from "@react-email/render";
import { Digest } from "./emails/digest";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const messages = await Promise.all(
  users.map(async (u) => ({
    from:    "Bird <hello@bird.com>",
    to:      [u.email],
    subject: "Your weekly digest",
    html:    await render(<Digest user={u} />),
  })),
);

const { data: batch, error } = await bird.email
  .sendBatch(messages, { idempotencyKey: `digest-${runId}` })
  .safe();

if (error) throw error;
console.log(`queued ${batch.data.length} messages`);

Allega il tuo contesto a ogni invio.

I tag sono una dimensione filtrabile di prima classe: segmenta recapito e coinvolgimento per campagna, template o esperimento nella stats API (fino a 20 per messaggio). I metadata sono JSON arbitrario, fino a 2 KB, che torna intatto a ogni lettura e webhook, così i tuoi ID viaggiano insieme al messaggio.

tagged.ts
await bird.email.send({
  from:     "Bird <hello@bird.com>",
  to:       ["ada@example.com"],
  subject:  "Your invite is ready",
  html:     "<p>Welcome aboard, Ada.</p>",
  tags:     [{ name: "campaign", value: "spring-2026" }],
  metadata: { user_id: "u_2bX91", order_id: "ord_5512" },
});

Segui ogni messaggio per tutto il suo ciclo di vita.

Un invio restituisce subito un 202; l'esito arriva come webhook per ogni destinatario. Verifica una sola firma, distingui in base al type: la stessa struttura che già gestisci per SMS, voce e WhatsApp.

app/api/webhooks/bird/route.ts
signed
import { bird } from "@/lib/bird";

export async function POST(req: Request) {
  const event = bird.webhooks.unwrap(
    await req.text(),
    Object.fromEntries(req.headers),
  );

  switch (event.type) {
    case "email.delivered":
      await markDelivered(event.data.email_id);
      break;
    case "email.bounced":
      await flag(event.data.recipient, event.data.bounce_type);
      break;
  }

  return new Response(null, { status: 204 });
}

Anche gli hard bounce, le segnalazioni di spam e le disiscrizioni aggiornano automaticamente la tua lista di soppressione, così un indirizzo errato non ti costa la reputazione una seconda volta.

  • email.acceptedAccettato dall'API e messo in coda per la consegna.
  • email.processedGenerato e consegnato alla pipeline di invio.
  • email.deliveredIl mail server ricevente ha accettato il messaggio.
  • email.deferredUn errore transitorio che Bird riprova automaticamente.
  • email.bouncedErrore permanente: tipo di bounce e codice SMTP nel payload.
  • email.openedPixel di tracciamento caricato (vengono conteggiate le aperture non prefetchate).
  • email.clickedÈ stato cliccato un link tracciato.
  • email.complainedIl destinatario ha segnalato il messaggio come spam.
  • email.unsubscribedIl destinatario si è disiscritto tramite un link tracciato nel corpo del messaggio.

Testa ogni esito prima di andare in produzione.

Nella sandbox è l'indirizzo a decidere il risultato, non lo stato del tuo account. Invia a delivered@messagebird.dev per un recapito pulito, oppure a bounce@, complaint@ e suppressed@ per attivare ciascun percorso di errore attraverso la pipeline reale e i webhook. Nessun dominio da verificare, nessun rischio per la tua reputazione. L'invio in produzione è regolato come dovrebbe: prima verifichi un dominio, e un nuovo dominio o IP dedicato passa per il warmup della reputazione prima di gestire il volume pieno.

Approfondisci nella documentazione.

Leggi la guida all'invio, configura gli eventi email e i webhook oppure, se arrivi da un altro provider, segui una guida alla migrazione da SendGrid, SES, Mailgun o Resend.

FAQ sull'invio

Posso inviare sia email transazionali che marketing?+
Sì. Entrambe passano per la stessa API di invio; l'unica differenza è il campo category, che determina come vengono applicate soppressioni e disiscrizioni. Scegli transactional per reset password e ricevute, marketing per le campagne.
Supportate i template React Email?+
Renderizza i tuoi template React Email in HTML nella tua applicazione — la funzione render di @react-email/render funziona senza modifiche — e passa il risultato come body html. Niente cambia nella tua toolchain dei template.
Quante email posso inviare in una singola richiesta?+
Fino a 100 messaggi indipendenti per chiamata batch, ciascuno con destinatario, oggetto e variabili propri. Il batch viene validato come un'unica unità, quindi un solo messaggio non valido fa rifiutare l'intera chiamata con un 422 — non invii mai a metà. Un singolo messaggio accetta da 1 a 50 destinatari tra to, cc e bcc.
Cosa succede se una richiesta va in timeout e la riprovo?+
Invia un Idempotency-Key con ogni invio logico. Se la richiesta originale è andata a buon fine ma la risposta è andata persa, ripeterla con la stessa chiave restituisce il risultato originale (contrassegnato con un header Idempotency-Replay) invece di inviare di nuovo.
Quali sono i limiti di frequenza?+
Gli invii singoli e i batch hanno limiti separati — sul piano gratuito, 10 invii singoli e 5 chiamate batch al minuto (5 × 100 = 500 messaggi/min), che salgono a 1.000 invii e 100 chiamate batch al minuto sul piano Growth. I limiti contano le richieste, non i destinatari, quindi il batching è la leva sul volume.
Come faccio a testare senza inviare email reali?+
Invia a un indirizzo sandbox come delivered@messagebird.dev — l'esito è deciso dall'indirizzo, non dallo stato del tuo account — così puoi mettere alla prova invii, webhook e soppressioni prima di verificare un dominio. Indirizzi come bounce@ e complaint@ simulano quegli esiti attraverso la pipeline reale.

Circa il 40% delle email commerciali del mondo gira già su Bird.

Email transazionali e di marketing su un'infrastruttura che gestiamo da un decennio. L'invio è una delle funzionalità della Bird Email API: recapitabilità, IP dedicati, soppressione e analytics sono inclusi.

Inizia con un canale.
Aggiungi gli altri quando sei pronto.

Una chiave API di test è subito tua. La produzione si sblocca quando aggiungi un metodo di pagamento e verifichi un mittente.

Usi Claude Code, Cursor o Codex? Copia un prompt di configurazione e il tuo agente installerà la CLI e le skill di Bird per te. Scegli il tuo: