Migrar do Brevo
Esta página mapeia o payload de envio transacional, as listas de bloqueio e os webhooks do Brevo para Bird. Siga o guia principal de migração na ordem indicada e use esses mapeamentos para os passos 1, 3 e 4.
O Brevo mantém supressões em dois lugares independentes, um para e-mail transacional e outro para marketing. Leia Exportar supressões antes de planejar o passo 3: exportar um e não o outro é o erro que essa migração facilita.
Entregue isto ao seu agente
Cole isto no Claude Code, Cursor ou Codex. O agente percorre esta página no seu repositório, usando a superfície Bird que ele já possui: o servidor MCP se houver um conectado, o CLI se estiver instalado e autenticado.
Exemplo de código
I am moving an email integration from Brevo 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/brevo.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 Brevo usage in this repository before you change anything: calls to /v3/smtp/email and any SDK wrappers around them, whether I send with templateId or with htmlContent, 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 Brevo 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. Brevo holds these in two separate places and I need both: GET /v3/smtp/blockedContacts for transactional blocks and unsubscribes, and the marketing blocklist, which lives on the contact records as emailBlacklisted rather than on a suppression endpoint. Page through both. 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. Brevo's webhook security page documents credentials I configure on the endpoint rather than a payload signature, so check what my endpoint actually relies on today: if it is a username and password in the webhook URL, take them out and tell me to rotate that pair rather than reusing it, because a credential that has lived in a URL should be treated as exposed. Bird signs every delivery instead. 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 Brevo path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Brevo 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 /v3/smtp/email do Brevo e o nosso POST /v1/email/messages têm estrutura parecida. A maior parte do trabalho é desempacotar os objetos de endereço do Brevo em strings simples.
| O que faz | Brevo | Bird |
|---|---|---|
| Autenticação | Header api-key | Authorization: Bearer |
| Remetente | sender ({email, name}) | from |
| Destinatários | to / cc / bcc (arrays de {email, name}) | to / cc / bcc (arrays de endereços) |
| Assunto | subject | subject |
| Corpo | htmlContent / textContent | html / text (pelo menos um) |
| Reply-to | replyTo ({email, name}) | reply_to (array) |
| Headers personalizados | headers (chaves em Title-Case) | headers (objeto string → string) |
| Rótulos filtráveis | tags (array de strings) | pares tags: {name, value} |
| Template armazenado | templateId + params | template + template.parameters |
| Anexos | attachment (url ou base64 content) | attachments (apenas base64, veja abaixo) |
| Agendamento | scheduledAt | scheduled_at |
| Handle de lote | batchId | (sem equivalente, veja abaixo) |
| Cópia por destinatário | messageVersions | um envio por versão, ou um lote |
| Categoria | (nenhum) | category: marketing (padrão) ou transactional |
Os limites e valores padrão dos campos (contagem de destinatários, limites de tags e metadados) estão em Enviando e-mail.
Notas de portabilidade:
- Endereços são objetos lá e strings aqui. {"email": "a@x.com", "name": "A"} se torna "A <a@x.com>" ou apenas "a@x.com". O mesmo desempacotamento se aplica a sender e replyTo.
- tags são strings simples. Nossas tags são pares. Uma tag como "welcome" se torna {"name": "category", "value": "welcome"}. Escolha um name estável para que seus dashboards filtrem da mesma forma que as estatísticas de tags do Brevo.
- params são dados de template, não contexto de ida e volta. Eles se tornam template.parameters. Se você também os usava para transportar seus próprios identificadores até os eventos, mova-os para metadata, que retornamos em todo evento de webhook junto com email_id/recipient_id.
- messageVersions não tem equivalente em uma única chamada. Cada versão é um conjunto distinto de destinatários e payload, então se torna seu próprio envio ou uma entrada em um lote.
- batchId não tem equivalente. O batchId do Brevo agrupa mensagens agendadas para que você possa cancelá-las ou reagendá-las como um conjunto. Envios agendados aqui são endereçados individualmente pelo id da mensagem; não há handle de grupo para passar ou cancelar.
- Anexo por URL não é suportado. O Brevo aceita uma entrada attachment como URL para buscar o arquivo. Busque o arquivo você mesmo e envie-o codificado em base64; veja anexos.
Exportar supressões
O Brevo divide as supressões entre dois sistemas que não compartilham endpoint nem esquema de paginação, e uma migração que extrai apenas o primeiro perde silenciosamente todos os descadastros de marketing:
- Bloqueios e descadastros transacionais: GET /v3/smtp/blockedContacts, paginado (50 por página por padrão, máximo de 100), cada entrada com o motivo do bloqueio.
- Lista de bloqueio de marketing: não é um endpoint de supressão. Fica no registro do contato como emailBlacklisted, então pagine GET /v3/contacts (até 1.000 por página com offset) e mantenha os contatos em que esse flag é verdadeiro.
Execute ambos pelo loop de importação. Os motivos de bloqueio do Brevo mapeiam para os nossos motivos hard_bounce, complaint e manual; Supressões tem a taxonomia completa.
Traduzir eventos de webhook
| Resultado | Brevo | Bird |
|---|---|---|
| Aceito/processado | request | email.accepted → email.processed |
| Entregue | delivered | email.delivered |
| Falha temporária | deferred / soft_bounce | email.deferred |
| Bounce permanente | hard_bounce | email.bounced / email.out_of_band_bounce |
| Reclamação de spam | spam | email.complained |
| Bloqueado/suprimido | blocked / invalid_email | email.rejected |
| Abertura | opened / unique_opened | email.opened |
| Clique | click | email.clicked |
| Descadastro | unsubscribed | email.unsubscribed / email.list_unsubscribed |
Duas diferenças determinam o quanto o seu handler muda.
Verifique no que o seu endpoint depende hoje antes de portá-lo. A página de segurança de webhooks do Brevo documenta credenciais que você configura no endpoint: um nome de usuário e senha anexados à URL como https://username:password@example.com/, um bearer token, headers de requisição personalizados e seus intervalos de IP. Nós assinamos cada entrega conforme o esquema HMAC do Standard Webhooks, então a verificação passa de algo que o chamador carrega para algo que o seu handler calcula. Se o seu endpoint atual contém credenciais na URL, remova-as e faça a rotação desse par em vez de reutilizá-lo: uma credencial que viveu em uma URL já alcançou logs de acesso, exportações de configuração e um console de fornecedor. A receita está em Webhooks e eventos.
O Brevo diferencia aberturas e cliques das suas variantes únicas. Nós não. opened e unique_opened chegam como email.opened, então um handler que contava apenas a variante única precisa deduplicar pelo próprio 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 em vez de um.
Fazer a virada
Siga domínios e DNS e o 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 de verificação e os registros DNS que você está publicando
- Webhooks e eventos: configuração de endpoint e verificação Standard Webhooks
- Sandbox de teste: teste de fumaça da nova integração antes da virada
- Supressões: confirme sua lista importada e como a mantemos daqui em diante
Recursos relacionados
Continue com a documentação, guias e exemplos sobre este tópico. Os recursos estão em inglês.
Assista ao guiaGetting started with emailExplore a funcionalidadeEmailSiga o percurso de aprendizagemBuild your first integrationGuia de implementaçãoSend your first email
Experimente na prática e obtenha um resumo de implementação