Sign inGet started

Migrer depuis MailerSend

Cette page fait correspondre le payload d'envoi, les listes de suppression et les webhooks de MailerSend avec Bird. Suivez le guide de migration principal dans l'ordre et utilisez ces correspondances pour les étapes 1, 3 et 4.
MailerSend maintient cinq listes de suppression et l'une d'entre elles est temporaire par conception. Lisez Exporter les suppressions avant l'étape 3 : importer celle-ci transforme une suspension de 72 heures en un blocage permanent.

Transmettez ceci à votre agent

Collez ceci dans Claude Code, Cursor ou Codex. L'agent parcourt cette page en s'appuyant sur votre propre dépôt, en utilisant la surface Bird dont il dispose déjà : le serveur MCP s'il est connecté, le CLI s'il est installé et authentifié.
Exemple de code
I am moving an email integration from MailerSend to Bird. Route through it with me.
1. Check what you already have before setting anything up. If Bird's MCP server is connected, use its tools. If the Bird CLI is installed and signed in, use that. Either one is enough, and every step below is an action you take with whichever you have. Only if neither is present, follow https://bird.com/docs/ai/set-up-your-agent.md to set one up and sign me in. Every Bird docs page serves Markdown at its own URL with `.md` appended, so fetch that rather than the HTML.
2. Read https://bird.com/docs/guides/email/migrate/mailersend.md for the payload, suppression and webhook mapping, and https://bird.com/docs/guides/email/migrate.md for the order the steps go in.
3. Find and list my MailerSend usage in this repository before you change anything: calls to /v1/email and any SDK wrappers around them, whether I send with template_id and personalization or with html, the webhook handler and the URL it is registered at, and every domain I send from. Tell me the list before you edit anything.
4. Register each of those sending domains with Bird and give me the DNS records to publish, following https://bird.com/docs/guides/email/sending-domains.md. Leave every DNS record MailerSend uses exactly as it is: Bird's records are published alongside them and both providers authenticate side by side until I switch traffic. Publishing DNS affects mail for the whole domain, so show me the records and let me publish them.
5. Export my suppressions and import them into Bird before any production traffic goes through Bird, so my first sends do not reach addresses that already bounced or complained. MailerSend keeps five lists under /v1/suppressions: hard bounces, spam complaints, unsubscribes and the blocklist are the four to carry over. Do NOT import the On Hold list: it is a temporary 72-hour hold that MailerSend clears by itself, and importing it would suppress those addresses permanently. The Bird import takes one address per request and is idempotent, so a partial re-run is safe. https://bird.com/docs/guides/email/suppressions.md has the reason taxonomy.
6. Port the send call and the webhook handler using the mapping tables on the provider page. Both providers sign with HMAC-SHA256, so this is a re-implementation rather than new code: MailerSend sends one Signature header, Bird follows the Standard Webhooks scheme with webhook-id, webhook-timestamp and webhook-signature, and the signed string is constructed differently. Keep the constant-time comparison. https://bird.com/docs/guides/webhooks.md and https://bird.com/docs/guides/email/events.md.
7. Run my whole integration against Bird's mail sandbox before any production traffic, following https://bird.com/docs/guides/email/testing-sandbox.md. Sandbox sends run the real pipeline without reaching an inbox or touching my sending reputation.
8. Stop and ask me wherever a step needs a decision. Do not point production traffic at Bird until I have seen the sandbox results and replied with the words cut over to Bird. Retiring the MailerSend path is a separate step that comes later: ask me again and wait for me to reply with the words retire the MailerSend path. A reply that agrees without naming what it is authorising is not authorisation. Finish by telling me what is left that only a person can do.

Faire correspondre l'appel d'envoi

Le POST /v1/email de MailerSend et notre POST /v1/email/messages partagent une structure similaire. Les différences qui nécessitent du code sont la limite de tags et la façon dont les données par destinataire sont transmises.
FonctionMailerSendBird
Expéditeurfrom ({email, name})from
Destinatairesto (max 50), cc / bcc (max 10 chacun)to / cc / bcc (tableaux)
Objetsubject (max 998 caractères)subject
Corpshtml / texthtml / text (au moins un)
Reply-toreply_to ({email, name})reply_to (tableau)
En-têtes personnalisésheaders ({name, value}, plans supérieurs)headers (objet string → string)
Libellés filtrablestags (tableau de chaînes, max 5)paires tags : {name, value}
Template enregistrétemplate_id + personalizationtemplate + template.parameters (voir ci-dessous)
Pièces jointesattachments (content, filename, disposition, id)attachments
Planificationsend_at (jusqu'à 72 heures à l'avance)scheduled_at
Précédence bulkprecedence_bulk(pas d'équivalent, voir ci-dessous)
Catégorie(aucune)category : marketing (par défaut) ou transactional
Threadingin_reply_toheaders
Les limites et valeurs par défaut de nos champs (nombre de destinataires, limites de tags et de métadonnées) se trouvent dans Envoyer des e-mails.
Notes de portage :
  • Les adresses sont des objets chez MailerSend et des chaînes chez nous. {"email": "a@x.com", "name": "A"} devient "A <a@x.com>" ou simplement "a@x.com", pour from, to, cc, bcc et reply_to de la même façon.
  • Les tags sont des chaînes simples limitées à cinq. Nos tags sont des paires. Un tag comme "welcome" devient {"name": "category", "value": "welcome"}. Choisissez un name stable pour que vos tableaux de bord filtrent comme le faisaient vos statistiques de tags MailerSend.
  • personalization contient les données de template par destinataire. C'est un tableau indexé par e-mail de destinataire. Notre template.parameters s'applique à l'envoi entier, donc un message dont le contenu diffère réellement par destinataire devient un envoi par destinataire ou une entrée batch chacun. Si votre tableau personalization contient les mêmes valeurs pour chaque destinataire, il se réduit à un seul objet template.parameters.
  • Le contexte aller-retour n'a pas d'équivalent chez MailerSend à copier. Si vous reconstituiez le contexte à partir de tags, utilisez metadata à la place : nous le renvoyons sur chaque événement webhook aux côtés de email_id/recipient_id, et il n'est pas limité à cinq entrées.
  • precedence_bulk n'a pas d'équivalent, et category n'en est pas un. precedence_bulk définit un en-tête Precedence: bulk, qui demande aux répondeurs automatiques et aux agents d'absence de rester silencieux. Notre category détermine quels enregistrements de suppression et préférences de désinscription peuvent bloquer un message, et rien d'autre. Définir category à sa place modifie le comportement de suppression et ne fait rien concernant les répondeurs automatiques. Si vous avez besoin de cet en-tête, notez que headers rejette les noms d'adressage et de plateforme, mais pas celui-ci.
  • Les en-têtes personnalisés et list_unsubscribe sont limités au plan chez MailerSend. Si votre plan ne les incluait pas, ils sont disponibles ici ; consultez envoyer des e-mails et catégories pour savoir comment nous gérons list-unsubscribe sur les e-mails marketing.

Exporter les suppressions

MailerSend maintient cinq listes sous /v1/suppressions, un endpoint par liste. Quatre sont permanentes et doivent être reprises ; la cinquième ne doit pas l'être.
Exportez et passez-les dans la boucle d'import :
  • Hard bounces, par exemple GET https://api.mailersend.com/v1/suppressions/hard-bounces
  • Plaintes pour spam
  • Désinscriptions
  • Blocklist, les adresses et motifs que vous avez ajoutés manuellement
N'importez pas la liste On Hold. La propre description de MailerSend indique qu'elle contient des adresses qui "have soft bounced 5 times within 30 days", qui "these emails will be blocked for 72 hours", et qu'elles sont ensuite "automatically removed from the list". C'est une période de refroidissement que le fournisseur efface de lui-même, donc l'importer convertit une suspension temporaire en une suppression permanente et cesse silencieusement d'envoyer à des adresses qui étaient sur le point d'être libérées. Notre équivalent de ce comportement est le report (deferral), que nous gérons à partir des résultats de livraison en temps réel plutôt que d'une liste importée.
Les types de listes de MailerSend correspondent à nos raisons hard_bounce, complaint et manual ; Suppressions contient la taxonomie complète.

Traduire les événements webhook

RésultatMailerSendBird
Accepté/traitéactivity.sentemail.acceptedemail.processed
Distribuéactivity.deliveredemail.delivered
Échec temporaireactivity.soft_bounced / activity.deferredemail.deferred
Bounce permanentactivity.hard_bouncedemail.bounced / email.out_of_band_bounce
Plainte pour spamactivity.spam_complaintemail.complained
Ouvertureactivity.opened / activity.opened_uniqueemail.opened
Clicactivity.clicked / activity.clicked_uniqueemail.clicked
Désinscriptionactivity.unsubscribedemail.unsubscribed / email.list_unsubscribed
Suspension temporairerecipient.on_hold_added / ..._removed(pas d'équivalent ; voir ci-dessus)
Deux différences déterminent l'ampleur des modifications de votre handler.
Les deux côtés signent avec HMAC-SHA256, c'est donc une ré-implémentation plutôt que du nouveau code. MailerSend envoie un seul en-tête Signature contenant un hash du payload calculé avec le secret de signature de ce webhook. Nous suivons le schéma Standard Webhooks, qui utilise webhook-id, webhook-timestamp et webhook-signature et signe une chaîne construite à partir de l'id, du timestamp et du body, de sorte que le timestamp vous offre aussi une protection contre le rejeu. Conservez la comparaison en temps constant que vous avez déjà et remplacez la construction ; la procédure se trouve dans Webhooks et événements.
MailerSend distingue les ouvertures et les clics de leurs variantes uniques. Nous ne le faisons pas. activity.opened et activity.opened_unique arrivent tous deux en tant que email.opened, donc un handler qui ne comptait que la variante unique doit dédupliquer sur recipient_id lui-même. Nos événements de livraison sont par destinataire, donc un envoi à trois destinataires produit trois résultats de livraison et non un seul.

Basculer

Suivez les étapes domaines et DNS et le test de validation en sandbox dans le guide principal. Les deux sont indépendantes du fournisseur.

Étapes suivantes

  • Domaines d'envoi : enregistrement, cycle de vie de la vérification et enregistrements DNS que vous publiez
  • Webhooks et événements : configuration de l'endpoint et vérification Standard Webhooks
  • Sandbox de test : testez la nouvelle intégration avant la bascule
  • Suppressions : confirmez votre liste importée et comment nous la maintenons à partir de maintenant