Sign inGet started

Migrar do Mandrill

Esta página mapeia o payload messages/send do Mandrill (Mailchimp Transactional), a rejection blacklist e os webhooks para Bird. Siga o guia principal de migração na ordem indicada e use estes mapeamentos para os passos 1, 3 e 4.
Duas mudanças de estrutura dominam a portabilidade. O Mandrill aninha tudo dentro de um objeto message e autentica com uma key no corpo da requisição. Nós usamos um payload plano no nível raiz e um header Authorization: Bearer padrão. E o type de destinatário do Mandrill (to/cc/bcc como campo em cada endereço) se torna nossos arrays separados to/cc/bcc.

Passe isto para o seu agente

Cole isto no Claude Code, Cursor ou Codex. O agente trabalha nesta página contra o seu próprio repositório, usando qualquer superfície Bird que ele já tenha: o servidor MCP se estiver conectado, o CLI se estiver instalado e autenticado.
Exemplo 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 a chamada de envio

O que fazMandrill (messages/send)Bird
Autenticaçãokey no corpo da requisiçãoHeader Authorization: Bearer bk_...
Remetentemessage.from_email / from_namefrom: string ou { "email", "name" }
Destinatáriosmessage.to: [{ email, name, type }]to / cc / bcc: separados pelo campo type
Assuntomessage.subjectsubject
Corpomessage.html / message.texthtml / text (ao menos um)
Reply-tomessage.headers["Reply-To"]reply_to: array
Headers personalizadosmessage.headersheaders: objeto string → string
Labels filtráveismessage.tags: strings simplestags: pares { name, value }
Contexto de ida e voltamessage.metadatametadata: JSON arbitrário
Template armazenadomessages/send-template + merge_varstemplate + template.parameters
Agendamentosend_atscheduled_at
Rastreamento de abertura/cliquemessage.track_opens / track_clickstrack_opens / track_clicks (padrão true)
Anexosmessage.attachments: { type, name, content }attachments: { content_type, filename, content }
Imagens inlinemessage.images: { type, name, content }attachments com content_id
Categoriaconvenção subaccount / tagscategory: marketing (padrão) ou transactional
Os limites e valores padrão dos nossos campos (contagem de destinatários, limites de tags e metadados) estão em Enviando e-mail.
Notas de portabilidade:
  • Achatar e reautenticar. Remova o wrapper message (os campos dele sobem para o nível raiz) e mova a chave API para fora do corpo, colocando-a no header Authorization. O campo key não tem equivalente aqui.
  • Separe os destinatários por type. O Mandrill marca cada destinatário como to, cc ou bcc no objeto de endereço. Nós usamos três arrays separados. Distribua a lista to pelo campo type durante a portabilidade.
  • Tags passam a ser pares nome/valor. As tags do Mandrill são strings simples ("welcome"). As nossas tags são pares { name, value }. Escolha um name estável, por exemplo { "name": "category", "value": "welcome" }, para que seus filtros e analytics agrupem da mesma forma que suas estatísticas do Mandrill. metadata migra diretamente como JSON.
  • Templates armazenados migram, com uma ressalva. O messages/send-template do Mandrill se torna nosso campo template (referenciado por ID ou slug) com valores em template.parameters. Veja enviando com um template. Nossas variáveis de template são por mensagem e não por destinatário, então merge_vars por destinatário se tornam uma entrada de batch por destinatário, cada uma com seu próprio parameters.
  • Anexos migram diretamente. O content em base64 do Mandrill é nosso content, e images inline (referenciados como cid: no HTML) se tornam entradas attachments com content_id. Veja anexos.

Exportar supressões

O Mandrill mantém endereços indesejados na sua rejection blacklist. Extraia-a com rejects/list API (ou exporte pela visualização Rejection Blacklist). Cada entrada tem um motivo (hard-bounce, soft-bounce, spam, unsub, custom). Ignore as linhas soft-bounce porque descrevem falhas transitórias e não supressões reais. Passe o restante pelo loop de importação.

Traduzir eventos de webhook

O Mandrill envia arrays de eventos em lote; mapeie o valor event para o vocabulário de eventos de Bird:
ResultadoMandrillBird
Enviado / aceitosendemail.acceptedemail.processed
Entreguedeliveredemail.delivered
Falha temporáriadeferralemail.deferred
Bounce permanentehard_bounceemail.bounced / email.out_of_band_bounce
Soft bouncesoft_bounceemail.deferred (depois email.bounced se desistir)
Reclamação de spamspamemail.complained
Descadastramentounsubemail.unsubscribed / email.list_unsubscribed
Rejeitado/bloqueadorejectemail.rejected
Aberturaopenemail.opened
Cliqueclickemail.clicked
Duas diferenças para codificar:
  • A aceitação se divide em dois eventos aqui. O send do Mandrill significa que a mensagem foi injetada e delivered significa que o servidor receptor a aceitou, que é a mesma distinção que fazemos. A diferença está apenas do nosso lado: separamos aceitação (email.accepted) de processamento (email.processed) antes de email.delivered, então um handler que dependia apenas de send agora tem dois eventos para escolher.
  • Os eventos são por destinatário e assinados de forma diferente. Nossos eventos de entrega têm recipient_id junto com email_id, com um fluxo por destinatário. Entregamos um evento por requisição e o assinamos conforme a especificação Standard Webhooks. O Mandrill, por sua vez, assina arrays em lote com um X-Mandrill-Signature HMAC. Veja Webhooks e eventos para verificação.

Fazer a virada

Siga os passos de domínios e DNS e do teste de fumaça no sandbox no guia principal. Ambos são independentes de provedor.

Próximos passos

  • Domínios de envio: registro, ciclo de vida da verificação e os registros DNS que você está redirecionando
  • Webhooks e eventos: configuração de endpoint e verificação Standard Webhooks
  • Sandbox de testes: teste de fumaça da nova integração antes da virada
  • Supressões: confirme sua lista importada e como a mantemos daqui em diante