Sign inGet started

Migrer depuis Brevo

Cette page fait correspondre le payload d'envoi transactionnel, les listes de blocage et les webhooks de Brevo à Bird. Suivez le guide de migration principal dans l'ordre et utilisez ces correspondances pour les étapes 1, 3 et 4.
Brevo conserve les suppressions dans deux endroits indépendants, l'un pour le courrier transactionnel et l'autre pour le marketing. Lisez Exporter les suppressions avant de planifier l'étape 3 : n'exporter qu'une seule des deux est l'erreur typique de cette migration.

Confiez 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, via 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 Brevo 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/brevo.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 Brevo usage in this repository before you change anything: calls to /v3/smtp/email and any SDK wrappers around them, whether I send with templateId or with htmlContent, 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 Brevo 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. Brevo holds these in two separate places and I need both: GET /v3/smtp/blockedContacts for transactional blocks and unsubscribes, and the marketing blocklist, which lives on the contact records as emailBlacklisted rather than on a suppression endpoint. Page through both. 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. Brevo's webhook security page documents credentials I configure on the endpoint rather than a payload signature, so check what my endpoint actually relies on today: if it is a username and password in the webhook URL, take them out and tell me to rotate that pair rather than reusing it, because a credential that has lived in a URL should be treated as exposed. Bird signs every delivery instead. 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 Brevo path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Brevo 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

POST /v3/smtp/email de Brevo et notre POST /v1/email/messages ont une structure proche. L'essentiel du travail consiste à extraire les objets d'adresse Brevo en chaînes simples.
FonctionBrevoBird
AuthentificationEn-tête api-keyAuthorization: Bearer
Expéditeursender ({email, name})from
Destinatairesto / cc / bcc (tableaux de {email, name})to / cc / bcc (tableaux d'adresses)
Objetsubjectsubject
CorpshtmlContent / textContenthtml / text (au moins un)
Reply-toreplyTo ({email, name})reply_to (tableau)
En-têtes personnalisésheaders (clés en Title-Case)headers (objet string → string)
Libellés filtrablestags (tableau de chaînes)Paires tags : {name, value}
Template enregistrétemplateId + paramstemplate + template.parameters
Pièces jointesattachment (url ou base64 content)attachments (base64 uniquement, voir ci-dessous)
PlanificationscheduledAtscheduled_at
Identifiant de lotbatchId(pas d'équivalent, voir ci-dessous)
Copie par destinatairemessageVersionsun envoi par version, ou un lot
Catégorie(aucune)category : marketing (par défaut) ou transactional
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 un e-mail.
Notes de portage :
  • Les adresses sont des objets chez Brevo et des chaînes chez nous. {"email": "a@x.com", "name": "A"} devient "A <a@x.com>" ou simplement "a@x.com". La même extraction s'applique à sender et replyTo.
  • Les tags sont des chaînes simples. 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 Brevo.
  • params contient des données de template, pas du contexte aller-retour. Il devient template.parameters. Si vous l'utilisiez aussi pour transmettre vos propres identifiants jusqu'aux événements, déplacez-les vers metadata, que nous renvoyons sur chaque événement webhook aux côtés de email_id/recipient_id.
  • messageVersions n'a pas d'équivalent en un seul appel. Chaque version est un ensemble distinct de destinataires et de payload, donc elle devient soit son propre envoi, soit une entrée dans un lot.
  • batchId n'a pas d'équivalent. Le batchId de Brevo regroupe les messages planifiés pour que vous puissiez les annuler ou les replanifier en bloc. Ici, les envois planifiés sont adressés individuellement par leur identifiant de message ; il n'existe pas d'identifiant de groupe à transmettre ou à utiliser pour annuler.
  • L'ajout de pièce jointe par URL n'est pas pris en charge. Brevo accepte une entrée attachment sous forme d'URL qu'il récupère lui-même. Récupérez le fichier vous-même et envoyez-le encodé en base64 ; voir pièces jointes.

Exporter les suppressions

Brevo répartit les suppressions entre deux systèmes qui ne partagent ni endpoint ni schéma de pagination, et une migration qui n'extrait que le premier perd silencieusement tous les désabonnements marketing :
  • Blocages et désabonnements transactionnels : GET /v3/smtp/blockedContacts, paginé (50 par page par défaut, 100 maximum), chaque entrée portant la raison du blocage.
  • Liste de blocage marketing : il ne s'agit pas du tout d'un endpoint de suppressions. Elle réside sur la fiche contact sous emailBlacklisted. Paginez GET /v3/contacts (jusqu'à 1 000 par page avec offset) et conservez les contacts pour lesquels ce flag est vrai.
Passez les deux dans la boucle d'import. Les raisons de blocage de Brevo correspondent à nos raisons hard_bounce, complaint et manual ; Suppressions contient la taxonomie complète.

Traduire les événements webhook

RésultatBrevoBird
Accepté/traitérequestemail.acceptedemail.processed
Distribuédeliveredemail.delivered
Échec temporairedeferred / soft_bounceemail.deferred
Rebond permanenthard_bounceemail.bounced / email.out_of_band_bounce
Plainte pour spamspamemail.complained
Bloqué/suppriméblocked / invalid_emailemail.rejected
Ouvertureopened / unique_openedemail.opened
Clicclickemail.clicked
Désabonnementunsubscribedemail.unsubscribed / email.list_unsubscribed
Deux différences déterminent l'ampleur des modifications à apporter à votre handler.
Vérifiez sur quoi votre endpoint s'appuie aujourd'hui avant de le porter. La page de sécurité des webhooks de Brevo documente les identifiants que vous configurez sur l'endpoint : un nom d'utilisateur et un mot de passe ajoutés à l'URL sous forme de https://username:password@example.com/, un bearer token, des en-têtes de requête personnalisés et ses plages d'adresses IP. Nous signons chaque livraison selon le schéma HMAC de Standard Webhooks, de sorte que la vérification passe de quelque chose que l'appelant transporte à quelque chose que votre handler calcule. Si votre endpoint actuel contient des identifiants dans son URL, retirez-les et renouvelez cette paire au lieu de la réutiliser : un identifiant qui a vécu dans une URL a atteint les journaux d'accès, les exports de configuration et la console du fournisseur. La marche à suivre se trouve dans Webhooks et événements.
Brevo distingue les ouvertures et les clics de leurs variantes uniques. Nous non. opened et unique_opened arrivent tous deux sous la forme 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 limités au destinataire : un envoi à trois destinataires produit trois résultats de livraison, et non un seul.

Basculer

Suivez les étapes domaines et DNS et test de fumée en sandbox du guide principal. Toutes 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 : vérifiez votre liste importée et la façon dont nous la maintenons à partir de maintenant