Envoyer des e-mails

Une seule API pour chaque e-mail que vous envoyez.

Démarrez en :

Transactionnel ou marketing, un message ou cent, envoyés via la même Email API, avec idempotence, suppression et webhooks intégrés. Transmettez du HTML brut ou faites le rendu de vos templates 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..."

Envoyez votre premier e-mail en cinq minutes.

Depuis le langage que vous utilisez déjà.

L'envoi est au cœur de l<hub>API Bird Email</hub>. Le premier envoi peut aller vers une adresse de test autorisée (delivered@messagebird.dev), ce qui vous permet dessayer toute la plateforme (envois, webhooks, suppression) avant de vérifier un domaine.

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

Cinq choses que vous ne construisez pas vous-même.

Le même contrat sur chaque canal Bird.

  1. 01

    Transactionnel et marketing.

    Le même endpoint envoie une réinitialisation de mot de passe ou une campagne. Un champ category détermine comment s'appliquent la suppression et les désabonnements.

  2. 02

    Des modèles à votre façon.

    Transmettez du HTML brut, ou faites le rendu de vos templates React Email en HTML dans votre application et envoyez le résultat. Votre chaîne d'outils, inchangée.

  3. 03

    Envoi par lot jusqu'à 100.

    Jusqu'à 100 messages indépendants par appel, chacun avec son propre destinataire et ses variables, validés comme un seul ensemble pour ne jamais envoyer à moitié.

  4. 04

    Idempotent par contrat.

    Chaque envoi accepte une clé d'idempotence : ainsi, une requête relancée après une expiration renvoie le résultat d'origine au lieu de doubler l'envoi.

  5. 05

    Un webhook à chaque changement d'état.

    Accepté, délivré, ouvert, cliqué, rejeté (bounce), signalé comme spam. Chacun signé en HMAC, protégé contre le rejeu, idempotent, la même enveloppe sur tous les canaux.

Vous envoyez déjà ailleurs ? Migrez en une après-midi.

L'appel que vous faites déjà change à peine : remplacez le client, gardez vos templates, pointez vos webhooks vers un seul endpoint. Les guides de migration couvrent SendGrid, Amazon SES, Mailgun et 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 message ou cent, un seul appel.

Regroupez jusqu'à 100 messages indépendants dans une seule requête, chacun avec son propre destinataire et ses variables. Le lot est validé comme un tout : un seul message incorrect rejette l'appel avec un 422, vous n'envoyez donc jamais à moitié. Une seule clé d'idempotence rend toute la requête rejouable en toute sécurité.

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

Attachez votre propre contexte à chaque envoi.

Les tags sont une dimension filtrable de première classe : segmentez la délivrabilité et l'engagement par campagne, template ou expérimentation dans l'API de stats (jusqu'à 20 par message). Les métadonnées sont du JSON arbitraire, jusqu'à 2 Ko, restitué intact à chaque lecture et webhook, pour que vos propres identifiants accompagnent le message.

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

Suivez chaque message tout au long de sa vie.

Un envoi renvoie immédiatement un 202 ; le résultat arrive sous forme de webhook par destinataire. Vérifiez une signature, branchez selon le type : la même enveloppe que vous gérez déjà pour SMS, voix et 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 });
}

Les hard bounces, les plaintes et les désabonnements mettent aussi à jour automatiquement votre liste de suppression, pour qu'une mauvaise adresse ne vous coûte jamais deux fois votre réputation.

  • email.acceptedAccepté par l'API et mis en file d'attente pour la remise.
  • email.processedGénéré et transmis au pipeline d'envoi.
  • email.deliveredLe serveur de messagerie destinataire a accepté le message.
  • email.deferredUn échec transitoire que Bird réessaie automatiquement.
  • email.bouncedÉchec permanent : type de bounce et code SMTP dans le payload.
  • email.openedPixel de suivi chargé (les ouvertures non préchargées sont comptées).
  • email.clickedUn lien suivi a été cliqué.
  • email.complainedLe destinataire a signalé le message comme spam.
  • email.unsubscribedLe destinataire s'est désinscrit via un lien suivi dans le corps du message.

Testez chaque résultat avant de passer en production.

Dans le sandbox, c'est l'adresse qui détermine le résultat, pas l'état de votre compte. Envoyez à delivered@messagebird.dev pour une délivrance propre, ou à bounce@, complaint@ et suppressed@ pour déclencher chaque scénario d'échec à travers le vrai pipeline et les webhooks. Aucun domaine à vérifier, aucun risque pour votre réputation. L'envoi en production est encadré comme il se doit : vous vérifiez d'abord un domaine, et un nouveau domaine ou une IP dédiée monte en charge via un warmup de réputation avant de porter le volume complet.

Allez plus loin dans la documentation.

Lisez le guide d'envoi, branchez les événements e-mail et webhooks, ou, si vous venez d'un autre fournisseur, suivez un guide de migration depuis SendGrid, SES, Mailgun ou Resend.

FAQ sur l'envoi

Puis-je envoyer à la fois des e-mails transactionnels et marketing ?+
Oui. Les deux passent par la même API d'envoi ; la seule différence est le champ category, qui détermine la façon dont la suppression et les désinscriptions s'appliquent. Choisissez transactional pour les réinitialisations de mot de passe et les reçus, marketing pour les campagnes.
Prenez-vous en charge les modèles React Email ?+
Restituez vos modèles React Email en HTML dans votre application — la fonction render de @react-email/render fonctionne sans changement — et transmettez le résultat comme corps html. Rien ne change dans votre chaîne d'outils de modèles.
Combien d'e-mails puis-je envoyer en une seule requête ?+
Jusqu'à 100 messages indépendants par appel de lot, chacun avec son propre destinataire, son objet et ses variables. Le lot est validé comme un tout : un seul message invalide rejette l'appel entier avec une erreur 422 — vous n'envoyez jamais à moitié. Un seul message accepte 1 à 50 destinataires répartis entre to, cc et bcc.
Que se passe-t-il si une requête expire et que je la relance ?+
Envoyez une Idempotency-Key avec chaque envoi logique. Si la requête initiale a réussi mais que la réponse a été perdue, la rejouer avec la même clé renvoie le résultat d'origine (signalé par un en-tête Idempotency-Replay) au lieu de procéder à un nouvel envoi.
Quelles sont les limites de débit ?+
Les envois uniques et les lots ont des limites distinctes — sur l'offre gratuite, 10 envois uniques et 5 appels de lot par minute (5 × 100 = 500 messages/min), montant à 1,000 envois et 100 appels de lot par minute sur Growth. Les limites comptent les requêtes, pas les destinataires : le traitement par lot est donc le levier de volume.
Comment tester sans envoyer de véritables e-mails ?+
Envoyez vers une adresse de sandbox telle que delivered@messagebird.dev — le résultat est déterminé par l'adresse, et non par l'état de votre compte — afin d'exercer les envois, les webhooks et la suppression avant même de vérifier un domaine. Des adresses comme bounce@ et complaint@ simulent ces résultats à travers le pipeline réel.

Environ 40% des e-mails commerciaux dans le monde fonctionnent déjà sur Bird.

E-mail transactionnel et marketing sur une infrastructure que nous exploitons depuis dix ans. L'envoi n'est qu'une des capacités de l'API Bird Email : délivrabilité, IPs dédiées, suppression et analytics sont fournis avec.

Commencez avec un seul canal.
Ajoutez les autres quand vous êtes prêt.

Une clé API de test est disponible immédiatement. L'accès production se débloque dès que vous ajoutez un moyen de paiement et vérifiez un expéditeur.

Vous utilisez Claude Code, Cursor ou Codex ? Copiez un prompt de configuration et votre agent installe la CLI Bird et les compétences pour vous. Choisissez le vôtre :