# Migrar do MailerSend

Esta página mapeia o payload de envio, as listas de supressão e os webhooks do MailerSend para Bird. Siga o [guia principal de migração](/docs/guides/email/migrate) na ordem indicada e use estes mapeamentos para os passos 1, 3 e 4.

O MailerSend mantém cinco listas de supressão, e uma delas é temporária por design. Leia [Exportar supressões](#exportar-supressões) antes do passo 3: importar essa lista transforma uma retenção de 72 horas em um bloqueio permanente.

## Entregue isto ao seu agente

Cole isto no Claude Code, Cursor ou Codex. O agente percorre esta página no seu próprio repositório, usando qualquer superfície Bird que ele já tenha: o servidor MCP se houver um conectado, o CLI se estiver instalado e autenticado.

```text
I am moving an email integration from MailerSend 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/mailersend.md for the payload, suppression and webhook mapping, and https://bird.com/docs/guides/email/migrate.md for the order the steps go in.
3. Find and list my MailerSend usage in this repository before you change anything: calls to /v1/email and any SDK wrappers around them, whether I send with template_id and personalization or with html, the webhook handler and the URL it is registered at, and every domain I send from. Tell me the list before you edit anything.
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 MailerSend 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 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. MailerSend keeps five lists under /v1/suppressions: hard bounces, spam complaints, unsubscribes and the blocklist are the four to carry over. Do NOT import the On Hold list: it is a temporary 72-hour hold that MailerSend clears by itself, and importing it would suppress those addresses permanently. 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. Both providers sign with HMAC-SHA256, so this is a re-implementation rather than new code: MailerSend sends one Signature header, Bird follows the Standard Webhooks scheme with webhook-id, webhook-timestamp and webhook-signature, and the signed string is constructed differently. Keep the constant-time comparison. 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 MailerSend path is a separate step that comes later: ask me again and wait for me to reply with the words retire the MailerSend 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 `POST /v1/email` do MailerSend e o nosso [`POST /v1/email/messages`](/docs/api/reference/create-email-message) compartilham uma estrutura. As diferenças que exigem código são o limite de tags e como os dados por destinatário são transportados.

| O que faz                     | MailerSend                                                 | Bird                                                |
| ----------------------------- | ---------------------------------------------------------- | --------------------------------------------------- |
| Remetente                     | `from` (`{email, name}`)                                   | `from`                                              |
| Destinatários                 | `to` (máx. 50), `cc` / `bcc` (máx. 10 cada)                | `to` / `cc` / `bcc` (arrays)                        |
| Assunto                       | `subject` (máx. 998 caracteres)                            | `subject`                                           |
| Corpo                         | `html` / `text`                                            | `html` / `text` (pelo menos um)                     |
| Reply-to                      | `reply_to` (`{email, name}`)                               | `reply_to` (array)                                  |
| Headers personalizados        | `headers` (`{name, value}`, planos superiores)             | `headers` (objeto string → string)                  |
| Labels filtráveis             | `tags` (array de strings, máx. 5)                          | pares `tags`: `{name, value}`                       |
| Template armazenado           | `template_id` + `personalization`                          | `template` + `template.parameters` (veja abaixo)    |
| Anexos                        | `attachments` (`content`, `filename`, `disposition`, `id`) | `attachments`                                       |
| Agendamento                   | `send_at` (até 72 horas à frente)                          | `scheduled_at`                                      |
| Precedência de envio em massa | `precedence_bulk`                                          | (sem equivalente, veja abaixo)                      |
| Categoria                     | (nenhum)                                                   | `category`: `marketing` (padrão) ou `transactional` |
| Threading                     | `in_reply_to`                                              | `headers`                                           |

Os limites e padrões dos nossos campos (quantidade de destinatários, limites de tags e metadados) estão em [Enviando e-mail](/docs/guides/email/sending-email).

Notas de portabilidade:

- **Endereços são objetos lá e strings aqui.** `{"email": "a@x.com", "name": "A"}` vira `"A <a@x.com>"` ou apenas `"a@x.com"`, para `from`, `to`, `cc`, `bcc` e `reply_to` igualmente.
- **`tags` são strings simples limitadas a cinco. Nossas tags são pares.** Uma tag como `"welcome"` vira `{"name": "category", "value": "welcome"}`. Escolha um `name` estável para que seus dashboards filtrem da mesma forma que as estatísticas de tags do MailerSend faziam.
- **`personalization` são dados de template por destinatário.** É um array indexado pelo e-mail do destinatário. Nosso `template.parameters` se aplica ao envio, então uma mensagem cujo conteúdo realmente difere por destinatário se torna um envio por destinatário ou uma entrada de [batch](/docs/guides/email/sending-bulk) cada. Se o seu array `personalization` contém os mesmos valores para todos os destinatários, ele se reduz a um único objeto `template.parameters`.
- **Contexto de ida e volta não tem equivalente no MailerSend para copiar.** Se você reconstruía contexto a partir de `tags`, use [`metadata`](/docs/guides/email/sending-email): nós o incluímos em cada evento de webhook junto com `email_id`/`recipient_id`, e ele não é limitado a cinco entradas.
- **`precedence_bulk` não tem equivalente, e `category` não é um.** `precedence_bulk` define um header `Precedence: bulk`, que pede a autoresponders e agentes de ausência que fiquem em silêncio. Nosso `category` decide quais registros de supressão e preferências de cancelamento de inscrição podem bloquear uma mensagem, e nada mais. Definir `category` no lugar dele altera o comportamento de supressão e não faz nada em relação a autoresponders. Se você precisa do header, note que `headers` rejeita endereçamento e nomes de plataforma, mas não este.
- **Headers personalizados e `list_unsubscribe` são restritos por plano no MailerSend.** Se o seu plano não os incluía, eles estão disponíveis aqui; veja [enviando e-mail](/docs/guides/email/sending-email) e [categorias](/docs/guides/email/categories) para saber como tratamos list-unsubscribe em e-mails de marketing.

## Exportar supressões

O MailerSend mantém cinco listas em `/v1/suppressions`, um endpoint por lista. Quatro são permanentes e devem ser migradas; a quinta não.

Exporte e processe pelo [loop de importação](/docs/guides/email/migrate#3-import-suppressions):

- **Hard bounces**, por exemplo `GET https://api.mailersend.com/v1/suppressions/hard-bounces`
- **Reclamações de spam**
- **Cancelamentos de inscrição**
- **Blocklist**, os endereços e padrões que você adicionou manualmente

**Não importe a lista On Hold.** A própria descrição do MailerSend é que ela retém endereços que "have soft bounced 5 times within 30 days", que "these emails will be blocked for 72 hours", e que eles são então "automatically removed from the list". É um período de espera que o provedor limpa sozinho, então importá-la converte uma retenção temporária em uma supressão permanente e para silenciosamente de enviar para endereços que estavam prestes a ser liberados. Nosso equivalente desse comportamento é o [deferral](/docs/guides/email/events), que tratamos a partir de resultados de entrega em tempo real, não de uma lista importada.

Os tipos de lista do MailerSend mapeiam para os nossos motivos `hard_bounce`, `complaint` e `manual`; [Supressões](/docs/guides/email/suppressions) tem a taxonomia completa.

## Traduzir eventos de webhook

| Resultado                 | MailerSend                                     | Bird                                             |
| ------------------------- | ---------------------------------------------- | ------------------------------------------------ |
| Aceito/processado         | `activity.sent`                                | `email.accepted` → `email.processed`             |
| Entregue                  | `activity.delivered`                           | `email.delivered`                                |
| Falha temporária          | `activity.soft_bounced` / `activity.deferred`  | `email.deferred`                                 |
| Bounce permanente         | `activity.hard_bounced`                        | `email.bounced` / `email.out_of_band_bounce`     |
| Reclamação de spam        | `activity.spam_complaint`                      | `email.complained`                               |
| Abertura                  | `activity.opened` / `activity.opened_unique`   | `email.opened`                                   |
| Clique                    | `activity.clicked` / `activity.clicked_unique` | `email.clicked`                                  |
| Cancelamento de inscrição | `activity.unsubscribed`                        | `email.unsubscribed` / `email.list_unsubscribed` |
| Retido temporariamente    | `recipient.on_hold_added` / `..._removed`      | (sem equivalente; veja acima)                    |

Duas diferenças determinam o quanto do seu handler muda.

**Ambos os lados assinam com HMAC-SHA256, então é uma reimplementação, não código novo.** O MailerSend envia um único header `Signature` contendo um hash do payload calculado com o segredo de assinatura daquele webhook. Nós seguimos o esquema [Standard Webhooks](https://www.standardwebhooks.com), que usa `webhook-id`, `webhook-timestamp` e `webhook-signature` e assina uma string construída a partir do id, do timestamp e do body, de modo que o timestamp também oferece proteção contra replay. Mantenha a comparação em tempo constante que você já tem e troque a construção; a receita está em [Webhooks e eventos](/docs/guides/webhooks).

**O MailerSend distingue aberturas e cliques das suas variantes únicas. Nós não.** `activity.opened` e `activity.opened_unique` chegam ambos como `email.opened`, então um handler que contava apenas a variante única precisa deduplicar por `recipient_id`. Nossos eventos de entrega têm escopo por destinatário, então um envio para três destinatários produz três resultados de entrega, não um.

## Virada

Siga os passos de [domínios e DNS](/docs/guides/email/migrate#2-re-point-domains-and-dns) e do [teste de fumaça no sandbox](/docs/guides/email/migrate#5-verify-in-the-sandbox-before-cutover) no guia principal. Ambos são independentes de provedor.

## Próximos passos

- [Domínios de envio](/docs/guides/email/sending-domains): registro, ciclo de vida de verificação e os registros DNS que você está publicando
- [Webhooks e eventos](/docs/guides/webhooks): configuração de endpoint e verificação Standard Webhooks
- [Sandbox de teste](/docs/guides/email/testing-sandbox): teste de fumaça da nova integração antes da virada
- [Supressões](/docs/guides/email/suppressions): confirme sua lista importada e como a mantemos daqui em diante

## Related resources

- [Getting started with email](/learn/email/getting-started-with-email) (video)
- [Email](/products/email) (product)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=email)
