Sign inGet started

Migrar do Mailgun

Esta página mapeia os parâmetros POST /v3/{domain}/messages, listas de supressão e eventos de webhook do Mailgun para Bird. Siga o guia principal de migração na ordem indicada e use esses mapeamentos para as etapas 1, 3 e 4.

Passe isto para seu agente

Cole isto no Claude Code, Cursor ou Codex. O agente percorre esta página em relação ao seu próprio repositório, usando qualquer superfície Bird que já tenha disponível: o servidor MCP, se estiver conectado, ou o CLI, se estiver instalado e autenticado.
Exemplo 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.

Mapeie a chamada de envio

Os prefixos de parâmetros form-encoded do Mailgun (opções o:, variáveis v:, cabeçalhos h:) se tornam campos JSON de primeira classe em POST /v1/email/messages:
O que fazMailgunBird
Remetentefromfrom
Destinatáriosto / cc / bccto / cc / bcc (arrays)
Assuntosubjectsubject
Corpohtml / texthtml / text (pelo menos um)
Reply-toh:Reply-Toreply_to (array)
Cabeçalhos personalizadosh:X-*headers (objeto string → string)
Rótulos filtráveiso:tagtags: pares {name, value}
Contexto de ida e voltav:* / X-Mailgun-Variablesmetadata: JSON arbitrário
Template armazenadotemplate + t:variablestemplate + template.parameters
Agendamentoo:deliverytimescheduled_at
Rastreamento de abertura/cliqueo:tracking-opens / o:tracking-clickstrack_opens / track_clicks (padrão true)
Categoria(nenhum)category: marketing (padrão) ou transactional
Os limites e padrões dos nossos campos (quantidade de destinatários, limites de tags e metadados) estão em Enviando e-mail.
Notas de portabilidade:
  • A solicitação passa a ser JSON. O Mailgun aceita multipart form data. Nós recebemos um body JSON com Content-Type: application/json. Essa costuma ser a maior mudança mecânica na portabilidade.
  • Variáveis v: eram ecoadas nos eventos. Nosso metadata funciona da mesma forma. Ecoamos seus metadata (e tags) em cada evento de webhook junto com email_id/recipient_id, para que seus handlers os recebam de volta sem uma consulta extra.
  • Variáveis de destinatário não migram diretamente. O recipient-variables do Mailgun personaliza vários destinatários em uma única chamada. Aqui, essa função pertence ao endpoint de lote, uma entrada por destinatário, cada uma com seu próprio conteúdo ou seus próprios valores parameters para substituição {{ token }}.
  • Templates armazenados migram diretamente. O parâmetro template do Mailgun mapeia para nosso campo template com valores em template.parameters. Veja enviando com um template.
  • Anexos migram diretamente. Os arquivos multipart attachment / inline do Mailgun se tornam nosso array attachments com content em base64 (defina content_id para imagens inline). Veja anexos.

Exportar supressões

O Mailgun mantém três listas por domínio. Exporte cada uma e processe-as pelo loop de importação:
  • GET /v3/{domain}/bounces
  • GET /v3/{domain}/complaints
  • GET /v3/{domain}/unsubscribes
Repita por domínio de envio. As listas do Mailgun têm escopo de domínio, enquanto nossas supressões têm escopo de espaço de trabalho; portanto, a união das listas dos seus domínios é o que você importa.

Traduzir eventos de webhook

O Mailgun sinaliza falha temporária vs permanente com um único evento failed e um campo severity. Nós os separamos:
ResultadoMailgunBird
Aceito/processadoacceptedemail.acceptedemail.processed
Entreguedeliveredemail.delivered
Falha temporáriafailed (temporary)email.deferred
Bounce permanentefailed (permanent)email.bounced / email.out_of_band_bounce
Reclamação de spamcomplainedemail.complained
Bloqueado/suprimido(nenhum)email.rejected
Aberturaopenedemail.opened
Cliqueclickedemail.clicked
Descadastrounsubscribedemail.list_unsubscribed
email.rejected não tem equivalente no Mailgun: reportamos destinatários suprimidos de forma visível (status rejected, rejection_reason: recipient_suppressed) em vez de ignorá-los silenciosamente. Adicione um handler para ele em vez de tratá-lo como um bounce.
A verificação também muda: o Mailgun assina com um HMAC sobre timestamp + token dentro do objeto signature do payload, enquanto nós assinamos conforme a especificação Standard Webhooks, com cabeçalhos em vez de campos no payload. Substitua seu código de verificação pela receita em Webhooks & eventos.

Migração final

Siga os passos de domínios e DNS e do teste de sanidade 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 & eventos: configuração de endpoint e verificação Standard Webhooks
  • Sandbox de testes: teste a nova integração antes da migração final
  • Supressões: confirme sua lista importada e como a mantemos daqui em diante