E-mail verzenden

Één API voor elke e-mail die je verstuurt.

Aan de slag in:

Transactioneel of marketing, één bericht of honderd, verstuurd via dezelfde Email API, met idempotency, suppressie en webhooks ingebouwd. Geef ruwe HTML door of render je React Email-templates.

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..."

Verstuur je eerste e-mail in vijf minuten.

Vanuit de taal die je al gebruikt.

Verzenden is de kern van de Bird Email API. De eerste send kan naar een goedgekeurd testadres (delivered@messagebird.dev), zodat je het hele platform (sends, webhooks, suppressie) kunt uitproberen voordat je een domein verifieert.

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();

Vijf dingen die je niet zelf bouwt.

Hetzelfde contract op elk Bird-kanaal.

  1. 01

    Transactioneel + marketing.

    Hetzelfde endpoint verstuurt een wachtwoordherstel of een campagne. Een category-veld bepaalt hoe suppressie en unsubscribes worden toegepast.

  2. 02

    Templates op jouw manier.

    Geef ruwe HTML door, of render React Email-templates naar HTML in je app en verstuur het resultaat. Je toolchain blijft ongewijzigd.

  3. 03

    Batch tot 100.

    Tot 100 onafhankelijke berichten per aanroep, elk met een eigen ontvanger en variabelen, als één geheel gevalideerd zodat je nooit half verstuurt.

  4. 04

    Idempotent per contract.

    Elke send accepteert een idempotency-key, zodat een opnieuw geprobeerd verzoek na een time-out het oorspronkelijke resultaat teruggeeft in plaats van dubbel te versturen.

  5. 05

    Een webhook bij elke statuswijziging.

    Accepted, delivered, opened, clicked, bounced, complained. Elk HMAC-ondertekend, replay-beveiligd, idempotent, dezelfde envelope op elk kanaal.

Verstuur je al ergens anders? Schakel over in een middag.

De call die je al doet verandert nauwelijks: wissel de client, behoud je templates, richt je webhooks op één endpoint. De migratiegidsen behandelen SendGrid, Amazon SES, Mailgun en 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>",
});

Eén bericht of honderd, één call.

Batch tot 100 onafhankelijke berichten in één request, elk met een eigen ontvanger en variabelen. De batch valideert als één geheel: één fout bericht laat de call afketsen met een 422, zodat je nooit half verstuurt. Eén idempotency key maakt het hele request veilig om opnieuw te proberen.

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`);

Voeg je eigen context toe aan elke send.

Tags zijn een eersteklas, filterbare dimensie: splits levering en engagement uit per campagne, template of experiment in de stats-API (tot 20 per bericht). Metadata is willekeurige JSON, tot 2 KB, die ongewijzigd terugkomt bij elke read en webhook, zodat je eigen ID's met het bericht meereizen.

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" },
});

Volg elk bericht gedurende zijn hele levensloop.

Een send geeft direct 202 terug; de uitkomst komt binnen als een webhook per ontvanger. Verifieer één signature, switch op de type: dezelfde envelope die je al verwerkt voor SMS, voice en 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 });
}

Hard bounces, complaints en unsubscribes werken ook automatisch je suppressielijst bij, zodat een slecht adres je reputatie nooit twee keer kost.

  • email.acceptedGeaccepteerd door de API en in de wachtrij gezet voor bezorging.
  • email.processedGegenereerd en overgedragen aan de verzendpipeline.
  • email.deliveredDe ontvangende mailserver heeft het bericht geaccepteerd.
  • email.deferredEen tijdelijke fout die Bird automatisch opnieuw probeert.
  • email.bouncedPermanente fout: bounce-type en SMTP-code in de payload.
  • email.openedTracking-pixel geladen (niet-prefetched opens tellen mee).
  • email.clickedOp een getrackte link is geklikt.
  • email.complainedDe ontvanger heeft het bericht als spam gemeld.
  • email.unsubscribedDe ontvanger heeft zich uitgeschreven via een getrackte link in de berichttekst.

Test elke uitkomst voordat je live gaat.

In de sandbox bepaalt het adres het resultaat, niet de staat van je account. Verstuur naar delivered@messagebird.dev voor een schone delivery, of naar bounce@, complaint@ en suppressed@ om elk faalpad door de echte pipeline en webhooks te sturen. Geen domein om te verifiëren, geen risico voor je reputatie. Productieverkeer is afgeschermd zoals het hoort: je verifieert eerst een domein, en een nieuw domein of dedicated IP wordt via reputatie-warmup opgevoerd voordat het volledig volume draagt.

Verdiep je in de documentatie.

Lees de verzendgids, koppel e-mailevents en webhooks, of, als je van een andere provider komt, volg een migratiegids van SendGrid, SES, Mailgun of Resend.

Verzenden FAQ

Kan ik zowel transactionele als marketing-e-mail versturen?+
Ja. Beide lopen via dezelfde send-API; het enige verschil is het category-veld, dat bepaalt hoe suppressie en uitschrijvingen worden toegepast. Kies transactional voor wachtwoordresets en bonnen, marketing voor campagnes.
Ondersteunen jullie React Email-templates?+
Render je React Email-templates naar HTML in je applicatie — de render-functie uit @react-email/render werkt ongewijzigd — en geef het resultaat door als de html-body. Er verandert niets aan je template-toolchain.
Hoeveel e-mails kan ik in één verzoek versturen?+
Tot 100 onafhankelijke berichten per batch-aanroep, elk met een eigen ontvanger, onderwerp en variabelen. De batch wordt als geheel gevalideerd, dus één ongeldig bericht wijst de hele aanroep af met een 422 — je verstuurt nooit half. Eén bericht heeft 1–50 ontvangers verdeeld over to, cc en bcc.
Wat gebeurt er als een verzoek een time-out krijgt en ik het opnieuw probeer?+
Stuur een Idempotency-Key mee met elke logische send. Als het oorspronkelijke verzoek slaagde maar het antwoord verloren ging, levert opnieuw afspelen met dezelfde key het oorspronkelijke resultaat terug (gemarkeerd met een Idempotency-Replay-header) in plaats van opnieuw te versturen.
Wat zijn de rate limits?+
Losse sends en batches hebben aparte limieten — op het free-tier 10 losse sends en 5 batch-aanroepen per minuut (5 × 100 = 500 berichten/min), oplopend tot 1,000 sends en 100 batch-aanroepen per minuut op Growth. Limieten tellen verzoeken, niet ontvangers, dus batchen is de hefboom voor volume.
Hoe test ik zonder echte e-mail te versturen?+
Verstuur naar een sandbox-adres zoals delivered@messagebird.dev — de uitkomst wordt bepaald door het adres, niet door de staat van je account — zodat je sends, webhooks en suppressie kunt uitproberen voordat je een domein verifieert. Adressen als bounce@ en complaint@ simuleren die uitkomsten via de echte pipeline.

Ongeveer 40% van de commerciële e-mail wereldwijd draait al op Bird.

Transactionele en marketing-e-mail op infrastructuur die we al tien jaar draaien. Verzenden is één van de mogelijkheden van de Bird Email API: deliverability, dedicated IP's, suppressie en analytics horen er standaard bij.

Begin met één kanaal.
Voeg de rest toe wanneer je er klaar voor bent.

Een test-API-key is direct beschikbaar. Productietoegang wordt ontgrendeld zodra je een betaalmethode toevoegt en een afzender verifieert.

Gebruik je Claude Code, Cursor of Codex? Kopieer een setup-prompt en je agent installeert de Bird CLI en skills voor je. Kies de jouwe: