Migrer depuis Mailjet
Cette page fait correspondre le payload Send API v3.1, la liste de blocage et l'Event API de Mailjet à Bird. Suivez le guide de migration principal dans l'ordre et utilisez ces correspondances pour les étapes 1, 3 et 4.
Le changement structurel le plus important concerne l'enveloppe. Mailjet encapsule chaque envoi dans un tableau Messages d'objets PascalCase (POST /v3.1/send). Nous prenons un seul objet JSON plat, en minuscules, par POST /v1/email/messages, et les messages indépendants multiples passent par le endpoint batch au lieu du tableau Messages.
Transmettez ceci à votre agent
Collez ceci dans Claude Code, Cursor ou Codex. L'agent parcourt cette page en regard de votre 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 Mailjet 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/mailjet.md for the payload, suppression and event mapping, and https://bird.com/docs/guides/email/migrate.md for the order the steps go in.
3. Find and list my Mailjet usage in this repository before you change anything: the POST /v3.1/send call sites and any SDK wrappers around them, the event handler and the URL it is registered at, and every domain I send from.
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 my current provider 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 blocklist from Mailjet and import it into Bird before any production traffic goes through Bird, so my first sends do not reach addresses that already bounced or complained. Read it through the contact-management API, or from the contact statistics pages if that is what I have access to. 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 event handler using the mapping tables on the provider page. Mailjet posts a Messages array of PascalCase objects, and each entry becomes either one flat Bird send or one entry in a batch, so tell me which shape my call sites map onto before you rewrite them. EventPayload becomes metadata. Bird signs deliveries per Standard Webhooks rather than Mailjet's scheme, so treat verification as a rewrite rather than a URL change: 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 Mailjet path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Mailjet 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
| Fonction | Mailjet (Send API v3.1) | Bird |
|---|---|---|
| Expéditeur | From : { "Email", "Name" } | from : string ou { "email", "name" } |
| Destinataires | To / Cc / Bcc : [{ "Email", "Name" }] | to / cc / bcc : arrays |
| Objet | Subject | subject |
| Corps | TextPart / HTMLPart | text / html (au moins un) |
| Reply-to | ReplyTo : { "Email", "Name" } | reply_to : array |
| En-têtes personnalisés | Headers | headers : objet string → string |
| Contexte aller-retour | EventPayload (string), renvoyé sur les événements | metadata : JSON arbitraire |
| Votre propre ID d'envoi | CustomID, renvoyé sur les événements | metadata ou tags |
| Template enregistré | TemplateID + Variables | template + template.parameters |
| Pièces jointes | Attachments : { "ContentType", "Filename", "Base64Content" } | attachments : { "content_type", "filename", "content" } |
| Images en ligne | InlinedAttachments, avec ContentID | attachments avec content_id |
| Suivi | paramètre compte/template | track_opens / track_clicks (défaut true) |
| Catégorie | (aucun) | category : marketing (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 des e-mails.
Notes de portage :
- Déballez le tableau Messages. Un envoi Mailjet unique est une entrée dans Messages. Ici, c'est le corps entier de la requête. Un tableau Messages avec plusieurs entrées correspond à notre endpoint batch. Des champs répétés dans une même requête ne peuvent pas représenter le batch.
- La casse passe de PascalCase à minuscules. Chaque champ est renommé : HTMLPart → html, TextPart → text, From.Email → from.email. C'est mécanique, mais cela touche chaque envoi.
- EventPayload devient metadata. Mailjet renvoie une seule chaîne EventPayload sur chaque événement. Nous renvoyons des metadata structurés (JSON) et des tags sur chaque événement webhook, ce qui vous permet de séparer les données de corrélation en champs typés. Voir tags vs métadonnées.
- CustomID est un identifiant de corrélation, et les nouvelles tentatives nécessitent une réponse distincte. Le CustomID de Mailjet est transmis aux événements pour le suivi ; il ne déduplique pas. Leur déduplication repose sur X-Mailjet-DeduplicateCampaign, un booléen utilisé avec X-Mailjet-Campaign qui empêche une campagne d'atteindre le même destinataire deux fois, soit une garantie au niveau de la campagne et non une nouvelle tentative sûre d'une requête. Ici, placez votre ID de corrélation dans metadata ou tags, et utilisez l'en-tête Idempotency-Key pour rendre une requête réessayée sûre.
- Les templates enregistrés se portent directement. Les TemplateID + Variables de Mailjet correspondent à notre champ template (référencé par ID ou slug) avec les valeurs dans template.parameters. Voir envoyer avec un template. La logique de template au-delà de la substitution de variables se porte aussi : les conditionnelles et boucles TemplateLanguage de Mailjet deviennent des {% if %} et {% for %} Liquid dans notre template.
- Les pièces jointes se portent directement. Le Base64Content de Mailjet est notre content en base64, et InlinedAttachments + ContentID deviennent des entrées attachments avec content_id. Voir pièces jointes.
Exporter les suppressions
Mailjet conserve les adresses injoignables et indésirables dans sa liste de blocage (bounces définitifs/temporaires et envois bloqués) et suit séparément les signaux de spam et de désabonnement. Exportez les adresses bloquées et rejetées depuis les pages de statistiques de contacts de Mailjet, ou récupérez-les via l'API de gestion des contacts, puis passez la liste dans la boucle d'import. Si vous envoyez des e-mails marketing, transférez aussi les contacts marqués comme désabonnés pour que ces préférences survivent à la migration.
Traduire les événements webhook
L'Event API de Mailjet envoie un déclencheur par type d'événement. La correspondance avec notre vocabulaire d'événements :
| Résultat | Mailjet | Bird |
|---|---|---|
| Accepté/traité | (aucun) | email.accepted → email.processed |
| Remis | sent | email.delivered |
| Bounce définitif | bounce | email.bounced / email.out_of_band_bounce |
| Bloqué | blocked | email.rejected |
| Plainte spam | spam | email.complained |
| Ouverture | open | email.opened |
| Clic | click | email.clicked |
| Désabonnement | unsub | email.unsubscribed / email.list_unsubscribed |
Deux différences à prendre en compte dans votre code :
- Nous signalons explicitement les étapes pré-remise. Le sent de Mailjet se déclenche une fois que le serveur de messagerie du destinataire a pris le message, ce qui correspond à notre email.delivered. Nous émettons aussi email.accepted et email.processed en amont, pour que vous voyiez la progression de l'envoi avant la confirmation de remise. Ne traitez pas ces événements antérieurs comme une remise.
- Les événements sont par destinataire. Mailjet indexe les événements par MessageID. Nos événements de remise comportent recipient_id en plus de email_id, de sorte qu'un envoi multi-destinataires produit un flux d'événements par destinataire. Nous signons les remises selon la spécification Standard Webhooks. Voir Webhooks et événements pour la vérification.
Basculer
Suivez domaines et DNS et le test de fumée en sandbox dans le guide principal. Les deux sont indépendants du fournisseur.
Étapes suivantes
- Domaines d'envoi : enregistrement, cycle de vie de la vérification et enregistrements DNS que vous redirigez
- 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 ensuite
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.
Regarder le guideGetting started with emailExplorer la fonctionnalitéEmailSuivre le parcours d'apprentissageBuild your first integrationGuide d'implémentationSend your first email
Essayez la pratique et obtenez un guide d'implémentation