Migrer depuis Mailgun
Cette page fait correspondre les paramètres POST /v3/{domain}/messages, les listes de suppression et les événements webhook de Mailgun à Bird. Suivez le guide principal de migration dans l'ordre et utilisez ces correspondances pour les étapes 1, 3 et 4.
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 Mailgun 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/mailgun.md for the parameter, 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 Mailgun usage in this repository before you change anything: the /v3/{domain}/messages call sites and any SDK wrappers around them, every o:, v: and h: prefixed parameter I pass, my webhook handler and the URL it is registered at, and every Mailgun domain I send from. Mailgun scopes almost everything per domain, so keep that list of domains: the next two steps both work through it.
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 Mailgun 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 from Mailgun 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. Mailgun keeps three lists per domain, so pull GET /v3/{domain}/bounces, GET /v3/{domain}/complaints and GET /v3/{domain}/unsubscribes for every domain you found. 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. Two things need attention rather than translation: Mailgun reports one failed event with a severity field where Bird has separate deferred and bounced events, and Bird signs deliveries per Standard Webhooks rather than Mailgun's scheme, so treat verification as a rewrite. See 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 Mailgun path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Mailgun 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
Les préfixes de paramètres encodés en formulaire de Mailgun (options o:, variables v:, en-têtes h:) deviennent tous des champs JSON de premier ordre sur POST /v1/email/messages :
| Fonction | Mailgun | Bird |
|---|---|---|
| Expéditeur | from | from |
| Destinataires | to / cc / bcc | to / cc / bcc (tableaux) |
| Objet | subject | subject |
| Corps | html / text | html / text (au moins un) |
| Reply-to | h:Reply-To | reply_to (tableau) |
| En-têtes personnalisés | h:X-* | headers (objet string → string) |
| Libellés filtrables | o:tag | tags : paires {name, value} |
| Contexte aller-retour | v:* / X-Mailgun-Variables | metadata : JSON arbitraire |
| Template stocké | template + t:variables | template + template.parameters |
| Planification | o:deliverytime | scheduled_at |
| Suivi ouvertures/clics | o:tracking-opens / o:tracking-clicks | track_opens / track_clicks (par défaut true) |
| Catégorie | (aucun) | 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 Envoi d'e-mails.
Notes de portage :
- La requête devient JSON. Mailgun accepte des données multipart form. Nous prenons un corps JSON avec Content-Type: application/json. C'est généralement le changement mécanique le plus important du portage.
- Les variables v: étaient renvoyées dans les événements. Notre metadata fonctionne de la même manière. Nous renvoyons vos metadata (et tags) dans chaque événement webhook aux côtés de email_id/recipient_id, pour que vos handlers les récupèrent sans requête supplémentaire.
- Les variables de destinataire ne se portent pas à l'identique. Les recipient-variables de Mailgun personnalisent plusieurs destinataires en un seul appel. Chez nous, cette tâche revient au batch endpoint, une entrée par destinataire, chacune avec son propre contenu ou ses propres valeurs parameters pour la substitution {{ token }}.
- Les templates stockés se portent directement. Le paramètre template de Mailgun correspond à notre champ template avec les valeurs dans template.parameters. Voir envoi avec un template.
- Les pièces jointes se portent directement. Les fichiers multipart attachment / inline de Mailgun deviennent notre tableau attachments avec un content en base64 (définissez content_id pour les images inline). Voir pièces jointes.
Exporter les suppressions
Mailgun conserve trois listes par domaine. Exportez chacune et passez-les dans la boucle d'import :
- GET /v3/{domain}/bounces
- GET /v3/{domain}/complaints
- GET /v3/{domain}/unsubscribes
Répétez pour chaque domaine d'envoi. Les listes de Mailgun sont limitées au domaine, tandis que nos suppressions sont limitées à l'espace de travail : c'est donc l'union des listes de vos domaines que vous importez.
Traduire les événements webhook
Mailgun signale les échecs temporaires et permanents avec un seul événement failed et un champ severity. Nous les séparons :
| Résultat | Mailgun | Bird |
|---|---|---|
| Accepté/traité | accepted | email.accepted → email.processed |
| Distribué | delivered | email.delivered |
| Échec temporaire | failed (temporary) | email.deferred |
| Rebond permanent | failed (permanent) | email.bounced / email.out_of_band_bounce |
| Plainte spam | complained | email.complained |
| Bloqué/supprimé | (aucun) | email.rejected |
| Ouverture | opened | email.opened |
| Clic | clicked | email.clicked |
| Désabonnement | unsubscribed | email.list_unsubscribed |
email.rejected n'a pas d'équivalent Mailgun : nous signalons les destinataires supprimés de manière visible (statut rejected, rejection_reason: recipient_suppressed) au lieu de les ignorer silencieusement. Ajoutez un handler dédié plutôt que de le traiter comme un rebond.
La vérification change aussi : Mailgun signe avec un HMAC sur timestamp + token à l'intérieur de l'objet signature du payload, tandis que nous signons selon la spécification Standard Webhooks, avec des en-têtes plutôt que des champs du payload. Remplacez votre code de vérification par la recette dans Webhooks & events.
Basculement
Suivez domaines & DNS et le test de fumée 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 & events : configuration de l'endpoint et vérification Standard Webhooks
- Sandbox de test : testez la nouvelle intégration avant le basculement
- Suppressions : vérifiez 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