Sign inGet started

Migrar desde Mailgun

Esta página asocia los parámetros POST /v3/{domain}/messages de Mailgun, las listas de supresión y los eventos de webhook con Bird. Sigue la guía principal de migración en orden y usa estas correspondencias para los pasos 1, 3 y 4.

Pasa esto a tu agente

Pega esto en Claude Code, Cursor o Codex. El agente trabaja con esta página sobre tu propio repositorio, usando la superficie Bird que ya tenga disponible: el servidor MCP si hay uno conectado, o CLI si está instalado y con sesión iniciada.
Ejemplo de código
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.

Asociar la llamada de envío

Los prefijos de parámetros codificados en formulario de Mailgun (opciones o:, variables v:, encabezados h:) se convierten en campos JSON de primer nivel en POST /v1/email/messages:
FunciónMailgunBird
Remitentefromfrom
Destinatariosto / cc / bccto / cc / bcc (arrays)
Asuntosubjectsubject
Cuerpohtml / texthtml / text (al menos uno)
Reply-toh:Reply-Toreply_to (array)
Encabezados personalizadosh:X-*headers (objeto string → string)
Etiquetas filtrableso:tagtags: pares {name, value}
Contexto de ida y vueltav:* / X-Mailgun-Variablesmetadata: JSON arbitrario
Plantilla almacenadatemplate + t:variablestemplate + template.parameters
Programacióno:deliverytimescheduled_at
Seguimiento de aperturas/clicso:tracking-opens / o:tracking-clickstrack_opens / track_clicks (por defecto true)
Categoría(ninguno)category: marketing (por defecto) o transactional
Los límites y valores por defecto de nuestros campos (cantidad de destinatarios, límites de etiquetas y metadatos) están en Envío de correo electrónico.
Notas de portabilidad:
  • La solicitud pasa a ser JSON. Mailgun acepta datos multipart de formulario. Nosotros recibimos un cuerpo JSON con Content-Type: application/json. Este suele ser el cambio mecánico más grande en la migración.
  • Las variables v: se devolvían en los eventos. Nuestro metadata funciona igual. Devolvemos tus metadata (y tags) en cada evento de webhook junto con email_id/recipient_id, para que tus handlers los reciban sin una consulta adicional.
  • Las variables de destinatario no se portan directamente. Las recipient-variables de Mailgun personalizan muchos destinatarios en una sola llamada. Aquí, esa tarea corresponde al endpoint de lotes, una entrada por destinatario, cada una con su propio contenido o sus propios valores parameters para sustitución en {{ token }}.
  • Las plantillas almacenadas se portan directamente. El parámetro template de Mailgun se asocia con nuestro campo template con valores en template.parameters. Consulta envío con plantilla.
  • Los adjuntos se portan directamente. Los archivos multipart attachment / inline de Mailgun se convierten en nuestro array attachments con content en base64 (establece content_id para imágenes en línea). Consulta adjuntos.

Exportar supresiones

Mailgun mantiene tres listas por dominio. Exporta cada una y pásalas por el bucle de importación:
  • GET /v3/{domain}/bounces
  • GET /v3/{domain}/complaints
  • GET /v3/{domain}/unsubscribes
Repite por cada dominio de envío. Las listas de Mailgun tienen alcance de dominio, mientras que nuestras supresiones tienen alcance de espacio de trabajo, así que lo que importas es la unión de las listas de todos tus dominios.

Traducir eventos de webhook

Mailgun señala fallos temporales y permanentes con un solo evento failed más un campo severity. Nosotros los separamos:
ResultadoMailgunBird
Aceptado/procesadoacceptedemail.acceptedemail.processed
Entregadodeliveredemail.delivered
Fallo temporalfailed (temporal)email.deferred
Rebote permanentefailed (permanente)email.bounced / email.out_of_band_bounce
Queja de spamcomplainedemail.complained
Bloqueado/suprimido(ninguno)email.rejected
Aperturaopenedemail.opened
Clicclickedemail.clicked
Cancelación de suscripciónunsubscribedemail.list_unsubscribed
email.rejected no tiene equivalente en Mailgun: nosotros reportamos los destinatarios suprimidos de forma visible (estado rejected, rejection_reason: recipient_suppressed) en lugar de omitirlos silenciosamente. Añade un handler para este evento en vez de tratarlo como un rebote.
La verificación también cambia: Mailgun firma con un HMAC sobre timestamp + token dentro del objeto signature del payload, mientras que nosotros firmamos según la especificación Standard Webhooks, con encabezados en lugar de campos del payload. Reemplaza tu código de verificación por la receta en Webhooks y eventos.

Transición

Completa dominios y DNS y la prueba de humo en sandbox en la guía principal. Ambos son independientes del proveedor.

Próximos pasos

  • Dominios de envío: registro, ciclo de vida de verificación y los registros DNS que vas a redirigir
  • Webhooks y eventos: configuración de endpoints y verificación con Standard Webhooks
  • Sandbox de pruebas: prueba de humo de la nueva integración antes de la transición
  • Supresiones: confirma tu lista importada y cómo la mantenemos a partir de aquí