Sign inGet Started

Tester la délivrabilité des e-mails (bac à sable de messagerie)

Le bac à sable de messagerie permet de tester les gestionnaires de webhooks, la logique de suppression et les résultats de livraison sans envoyer vers une boîte de réception réelle. Envoyez via le API habituel à une adresse sur messagebird.dev. La partie locale détermine le résultat : bounce@messagebird.dev génère un rebond et delivered@messagebird.dev est livré.

Un envoi en bac à sable emprunte les circuits habituels d'acceptation, d'événements et de webhooks. Il renvoie la même réponse 202 et produit, pour chaque destinataire, des payloads d'événement de même structure qu'un envoi en production. Le payload ne contient aucun indicateur de test. Le message n'atteint ni l'infrastructure de livraison externe ni une boîte de réception réelle. Les rebonds et plaintes simulés n'affectent pas votre réputation d'expéditeur et n'écrivent rien dans la liste de suppression : vous pouvez donc réutiliser les adresses.

Le bac à sable ne nécessite aucune configuration : ni option à activer, ni mode test, ni clé API spéciale. Il se déclenche uniquement selon l'adresse du destinataire, sur les points de terminaison d'envoi habituels (POST /v1/email/messages et POST /v1/email/batches) ainsi que sur une diffusion. Un contact de l'audience dont l'adresse est une adresse de bac à sable est simulé au lieu de recevoir le message. Vous pouvez ainsi répéter une campagne sans envoyer d'e-mail à personne. Un destinataire simulé est tout de même décompté de votre quota d'envoi, si bien que la répétition sollicite le même quota que l'envoi réel.

Adresses magiques

Toutes les adresses se trouvent sur @messagebird.dev. La partie locale détermine le résultat :

AdresseRésultat simuléSéquence de webhooksRemarques
delivered@Le serveur de messagerie destinataire accepte le messageemail.accepted → email.processed → email.deliveredLe cas nominal
bounce@ / hardbounce@Rebond définitif : SMTP 550, 5.1.1 Unknown User, classe de rebond 10email.accepted → email.processed → email.bounced avec bounce_type: "hard"Aucune écriture dans la liste de suppression, l'adresse reste donc réutilisable
softbounce@Rebond temporaire : SMTP 451, 4.3.0 Temporary failure, please retry, classe 20email.accepted → email.processed → email.bounced avec bounce_type: "soft"Un rebond temporaire, réel ou simulé, n'entraîne jamais de suppression
deferred@ / delay@Report : SMTP 451, 4.2.1 Mailbox temporarily unavailable, will retry, classe 21email.accepted → email.processed → email.deferredLe report simulé est définitif : aucune nouvelle tentative ne suit, le destinataire reste donc deferred
complaint@ / spam@Le destinataire signale le message comme spam (feedback_type: "abuse")email.accepted → email.processed → email.complainedAucune écriture dans la liste de suppression ; réutilisable
suppressed@Le destinataire est traité comme s'il figurait déjà sur votre liste de suppressionemail.accepted → email.rejected avec rejection_reason: "recipient_suppressed"Le traitement s'interrompt exactement comme pour un vrai destinataire sur la liste de suppression : aucun email.processed, aucun événement de livraison
reject@Le message est rejeté avant toute tentative de remiseemail.accepted → email.rejected avec rejection_reason: "transmission_failed"Aucun événement email.processed ni événement de remise ne suit

Les séquences ci-dessus sont les webhooks produits par un envoi unique. Pour une diffusion, retirez le email.accepted initial : un destinataire de diffusion est accepté individuellement, mais nous enregistrons cet événement sans envoyer de webhook. Chaque séquence commence donc par l'événement suivant : email.processed sur les parcours de remise et email.rejected pour suppressed@ et reject@. Tout ce qui suit est identique, et la référence des événements décrit la règle en détail.

Un envoi peut combiner des destinataires sandbox et des destinataires réels. Chaque destinataire suit son propre cycle de vie : les destinataires réels reçoivent le message normalement, les destinataires sandbox sont simulés.

Les mêmes événements apparaissent aussi dans la chronologie du message, dans le journal des e-mails et dans les événements API. Vous pouvez donc utiliser la sandbox sans endpoint de webhook et consulter ensuite les résultats.

Règles d'adressage

  • La détection repose uniquement sur la partie locale, et seulement sur le domaine messagebird.dev. bounce@yourdomain.com est une adresse normale.
  • Seules les parties locales du tableau des adresses magiques sont magiques. Toute autre adresse sur messagebird.dev est un destinataire normal. Si vous envoyez depuis le domaine d'onboarding partagé, cette adresse doit appartenir à un membre vérifié de l'espace de travail.
  • La correspondance ne tient pas compte de la casse : Bounce@messagebird.dev et bounce@messagebird.dev se comportent de la même façon.
  • Le sous-adressage +label est retiré avant la correspondance : bounce+signup-flow@messagebird.dev produit toujours un bounce. Utilisez des libellés pour associer les cas de test ; l'adresse complète, libellé compris, figure dans vos événements et webhooks, ce qui permet à chaque exécution de test de marquer ses propres destinataires.

Exemple complet : simuler un rebond de bout en bout

Vous n'avez pas besoin d'un domaine d'envoi vérifié. Envoyez depuis onboarding@messagebird.dev, comme décrit dans Envoyer votre premier e-mail. Les adresses sandbox reconnues sont exemptées de la restriction du domaine d'onboarding aux membres vérifiés, mais elles sont tout de même décomptées de son quota quotidien.

Vérifiez qu'un endpoint de webhook est abonné aux événements e-mail (voir Webhooks), puis envoyez :

const msg = await bird.email.send({
  from: { email: "onboarding@messagebird.dev", name: "Bird" },
  to: ["bounce+signup-flow@messagebird.dev"],
  subject: "Sandbox bounce test",
  html: "<p>This message will hard-bounce.</p>",
  tags: [{ name: "flow", value: "signup" }],
  metadata: { test_run: "docs-capture-1" },
});
console.log(msg.id, msg.status); // "em_…", "accepted"

Si votre clé commence par bk_eu1_, appelez plutôt https://eu1.platform.bird.com.

API répond 202 Accepted avec un identifiant de message em_*, impossible à distinguer d'un envoi en production. Ainsi, le chemin de code que vous testez est votre vrai chemin. Votre endpoint de webhook reçoit ensuite email.accepted, email.processed, puis email.bounced. Chaque événement reprend les valeurs tags et metadata de l'envoi (null si l'envoi n'en avait pas), et la charge utile email.bounced contient la classification complète du rebond :

Exemple de code
{
  "type": "email.bounced",
  "timestamp": "2026-07-23T14:51:00.362Z",
  "data": {
    "email_id": "em_01ky7qanhrejer0bn34v38hrxh",
    "recipient_id": "er_01ky7qanhrejds4decpk83q5qq",
    "workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf",
    "recipient": "bounce+signup-flow@messagebird.dev",
    "recipient_role": "to",
    "bounce_type": "hard",
    "bounce_class": 10,
    "bounce_code": "550",
    "bounce_description": "5.1.1 Unknown User",
    "sending_ip": null,
    "tags": [{ "name": "flow", "value": "signup" }],
    "metadata": { "test_run": "docs-capture-1" },
    "broadcast_id": null
  }
}

La signification des champs figure dans la référence des événements. Aucun indicateur de simulation n'apparaît dans la charge utile : le type et la structure de l'événement sont exactement ceux d'un vrai rebond permanent. Seule l'adresse du destinataire indique qu'il s'agit d'une simulation. Si votre gestionnaire doit traiter le trafic de test à part, basez-vous sur le domaine de destinataire messagebird.dev.

Pour vérifier qu'aucun envoi n'est fait à un destinataire déjà sur la liste de suppression, répétez l'envoi avec suppressed@messagebird.dev. Vérifiez que vous recevez email.accepted, puis email.rejected avec rejection_reason: "recipient_suppressed". Vous ne devez recevoir ni email.processed ni événement de remise. Ce comportement reproduit exactement celui d'un vrai destinataire sur la liste de suppression : le message est accepté, puis interrompu pendant le traitement, avant tout envoi.

Ce que fait la sandbox, et ce qu'elle ne fait pas

  • Aucune écriture dans la liste de suppression. Les rebonds permanents et les plaintes simulés n'ajoutent pas le destinataire à votre liste de suppression ; c'est pourquoi les adresses restent réutilisables. Votre webhook se déclenche quand même (email.bounced, email.complained), ce qui permet de tester entièrement votre propre logique de suppression. Pour tester le rejet d'un destinataire déjà sur la liste de suppression, utilisez l'adresse dédiée suppressed@.
  • Aucune remise réelle, jamais. Les destinataires sandbox sont interceptés avant que le message n'atteigne l'infrastructure de remise. Rien n'est transmis, aucune boîte de réception n'intervient et votre réputation d'expéditeur reste intacte.
  • La validation des requêtes s'applique toujours. Un envoi sandbox utilise les endpoints habituels : les contrôles de schéma, les limites de taille et les règles d'en-têtes rejettent donc une requête invalide comme d'habitude. La sandbox ignore tout ce qui suit la transmission : le rendu et la remise au-delà de ce point ne sont pas testés.
  • Les ouvertures et les clics ne sont pas simulés. Une adresse magique simule le résultat de la transmission, et personne n'ouvre le message : email.opened et email.clicked proviennent donc uniquement d'e-mails réels.
  • Les statistiques incluent le trafic du sandbox. Les envois vers le sandbox comptent dans les statistiques globales de votre espace de travail ainsi que dans vos taux de rebond et de plainte. Un grand nombre de rebonds simulés fausse vos tableaux de bord, sans modifier votre réputation.

Étapes suivantes

Poursuivez avec la documentation, les guides et les exemples sur ce sujet.