Sign inGet started

Migrar desde Mandrill

Esta página mapea el payload messages/send de Mandrill (Mailchimp Transactional), la rejection blacklist y los webhooks a Bird. Sigue la guía principal de migración en orden y usa estas correspondencias para los pasos 1, 3 y 4.
Dos cambios de estructura dominan la migración. Mandrill anida todo bajo un objeto message y se autentica con un key en el cuerpo de la solicitud. Nosotros usamos un payload plano de primer nivel y un header Authorization: Bearer estándar. Además, el type de destinatario de Mandrill (to/cc/bcc como campo en cada dirección) pasa a ser nuestros arrays separados to/cc/bcc.

Pasa esto a tu agente

Pega esto en Claude Code, Cursor o Codex. El agente recorre esta página contra 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 Mandrill 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/mandrill.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 Mandrill usage in this repository before you change anything: the messages/send and messages/send-template call sites and any SDK wrappers around them, the webhook handler and the URL it is registered at, and every domain I send from. Mandrill authenticates with an API key passed in the request body rather than a header, so tell me every place that key appears in my code: the port changes how I authenticate, not just what I send, and that key is a secret currently sitting in a payload.
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 rejects from Mandrill 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. Read the list through rejects/list, and skip the soft-bounce rows: those are transient failures rather than suppressions, and importing them would suppress addresses that are fine. Show me how many rows you skipped. 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. Move the API key out of the request body and into the Authorization header as a bearer token while you are there. Bird signs deliveries per Standard Webhooks rather than Mandrill'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 Mandrill path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Mandrill 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.

Mapear la llamada de envío

FunciónMandrill (messages/send)Bird
Autenticaciónkey en el cuerpo de la solicitudHeader Authorization: Bearer bk_...
Remitentemessage.from_email / from_namefrom: string o { "email", "name" }
Destinatariosmessage.to: [{ email, name, type }]to / cc / bcc: separados por el campo type
Asuntomessage.subjectsubject
Cuerpomessage.html / message.texthtml / text (al menos uno)
Reply-tomessage.headers["Reply-To"]reply_to: array
Headers personalizadosmessage.headersheaders: objeto string → string
Etiquetas filtrablesmessage.tags: strings simplestags: pares { name, value }
Contexto de ida y vueltamessage.metadatametadata: JSON arbitrario
Plantilla almacenadamessages/send-template + merge_varstemplate + template.parameters
Programaciónsend_atscheduled_at
Seguimiento de aperturas/clicsmessage.track_opens / track_clickstrack_opens / track_clicks (default true)
Adjuntosmessage.attachments: { type, name, content }attachments: { content_type, filename, content }
Imágenes en líneamessage.images: { type, name, content }attachments con content_id
Categoríasubaccount / convención de tagscategory: marketing (default) o transactional
Los límites y valores por defecto de nuestros campos (cantidad de destinatarios, límites de tags y metadata) están en Enviar email.
Notas de migración:
  • Aplana y reautentica. Elimina el wrapper message (sus campos pasan al nivel superior) y mueve la clave API del cuerpo al header Authorization. El campo key no tiene equivalente aquí.
  • Separa los destinatarios por type. Mandrill marca cada destinatario como to, cc o bcc en el objeto de dirección. Nosotros usamos tres arrays separados. Distribuye la lista to por su campo type durante la migración.
  • Los tags pasan a ser pares nombre/valor. Los tags de Mandrill son strings simples ("welcome"). Nuestros tags son pares { name, value }. Elige un name estable, por ejemplo { "name": "category", "value": "welcome" }, para que tus filtros y analíticas agrupen como lo hacían tus estadísticas de Mandrill. metadata se traslada directamente como JSON.
  • Las plantillas almacenadas se trasladan, con una salvedad. El messages/send-template de Mandrill pasa a ser nuestro campo template (referenciado por ID o slug) con valores en template.parameters. Consulta enviar con una plantilla. Nuestras variables de plantilla son por mensaje en lugar de por destinatario, así que las merge_vars por destinatario se convierten en una entrada de batch por destinatario, cada una con su propio parameters.
  • Los adjuntos se trasladan directamente. El content en base64 de Mandrill es nuestro content, y las images en línea (referenciadas como cid: en el HTML) pasan a ser entradas attachments con content_id. Consulta adjuntos.

Exportar supresiones

Mandrill guarda las direcciones no deseadas en su rejection blacklist. Extráela con rejects/list API (o exporta desde la vista Rejection Blacklist). Cada entrada tiene un motivo (hard-bounce, soft-bounce, spam, unsub, custom). Omite las filas soft-bounce porque describen fallos transitorios, no supresiones reales. Pasa el resto por el ciclo de importación.

Traducir eventos de webhook

Mandrill envía arrays de eventos agrupados; mapea el valor event al vocabulario de eventos de Bird:
ResultadoMandrillBird
Enviado / aceptadosendemail.acceptedemail.processed
Entregadodeliveredemail.delivered
Fallo temporaldeferralemail.deferred
Rebote permanentehard_bounceemail.bounced / email.out_of_band_bounce
Rebote suavesoft_bounceemail.deferred (luego email.bounced si desiste)
Queja de spamspamemail.complained
Cancelación de suscripciónunsubemail.unsubscribed / email.list_unsubscribed
Rechazado/bloqueadorejectemail.rejected
Aperturaopenemail.opened
Clicclickemail.clicked
Dos diferencias que debes contemplar en el código:
  • La aceptación se divide en dos eventos aquí. El send de Mandrill significa que el mensaje fue inyectado y delivered significa que el servidor receptor lo aceptó, que es la misma distinción que hacemos nosotros. La diferencia está solo de nuestro lado: separamos la aceptación (email.accepted) del procesamiento (email.processed) antes de email.delivered, así que un handler que dependía solo de send ahora tiene dos eventos entre los que elegir.
  • Los eventos tienen alcance por destinatario y se firman de forma diferente. Nuestros eventos de entrega incluyen recipient_id junto con email_id, con un flujo por destinatario. Enviamos un evento por solicitud y lo firmamos según la especificación Standard Webhooks. Mandrill, en cambio, firma arrays agrupados con un X-Mandrill-Signature HMAC. Consulta Webhooks y eventos para la verificación.

Puesta en producción

Sigue 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 del endpoint y verificación con Standard Webhooks
  • Sandbox de pruebas: prueba de humo de la nueva integración antes de la puesta en producción
  • Supresiones: confirma tu lista importada y cómo la mantenemos de aquí en adelante