Migrar do Mailjet
Esta página mapeia o payload Send API v3.1, a blocklist e o Event API do Mailjet para Bird. Siga o guia principal de migração na ordem indicada e use esses mapeamentos nos passos 1, 3 e 4.
A maior mudança estrutural é o envelope. O Mailjet envolve cada envio em um array Messages de objetos PascalCase (POST /v3.1/send). Nós recebemos um único objeto JSON flat, em lowercase, por POST /v1/email/messages, e várias mensagens independentes vão para o endpoint de lote em vez do array Messages.
Passe isto para o 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, ou o CLI se estiver instalado e autenticado.
Exemplo de código
I am moving an email integration from Mailjet 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/mailjet.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 Mailjet usage in this repository before you change anything: the POST /v3.1/send call sites and any SDK wrappers around them, the event handler and the URL it is registered at, and every domain I send from.
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 blocklist from Mailjet and import it into Bird before any production traffic goes through Bird, so my first sends do not reach addresses that already bounced or complained. Read it through the contact-management API, or from the contact statistics pages if that is what I have access to. 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 event handler using the mapping tables on the provider page. Mailjet posts a Messages array of PascalCase objects, and each entry becomes either one flat Bird send or one entry in a batch, so tell me which shape my call sites map onto before you rewrite them. EventPayload becomes metadata. Bird signs deliveries per Standard Webhooks rather than Mailjet'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 Mailjet path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Mailjet 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 faz | Mailjet (Send API v3.1) | Bird |
|---|---|---|
| Remetente | From: { "Email", "Name" } | from: string ou { "email", "name" } |
| Destinatários | To / Cc / Bcc: [{ "Email", "Name" }] | to / cc / bcc: arrays |
| Assunto | Subject | subject |
| Corpo | TextPart / HTMLPart | text / html (pelo menos um) |
| Reply-to | ReplyTo: { "Email", "Name" } | reply_to: array |
| Headers personalizados | Headers | headers: objeto string → string |
| Contexto de ida e volta | EventPayload (string), ecoado nos eventos | metadata: JSON arbitrário |
| Seu próprio ID de envio | CustomID, ecoado nos eventos | metadata ou tags |
| Template armazenado | TemplateID + Variables | template + template.parameters |
| Anexos | Attachments: { "ContentType", "Filename", "Base64Content" } | attachments: { "content_type", "filename", "content" } |
| Imagens inline | InlinedAttachments, com ContentID | attachments com content_id |
| Rastreamento | configuração de conta/template | track_opens / track_clicks (padrão true) |
| Categoria | (nenhum) | category: marketing (padrão) ou transactional |
Nossos limites e padrões de campos (contagens de destinatários, limites de tags e metadados) estão em Enviando e-mail.
Notas de portabilidade:
- Desempacote o array Messages. Um único envio do Mailjet é uma entrada em Messages. Aqui, isso é o corpo inteiro da requisição. Um array Messages com várias entradas mapeia para nosso endpoint de lote. Campos repetidos em uma requisição não representam o lote.
- A caixa muda de PascalCase para lowercase. Todo campo é renomeado: HTMLPart → html, TextPart → text, From.Email → from.email. É mecânico, mas afeta todo envio.
- EventPayload vira metadata. O Mailjet ecoa uma única string EventPayload em cada evento. Nós ecoamos metadata (JSON) estruturado e tags em cada evento de webhook, para que você possa separar dados de correlação em campos tipados. Veja tags vs metadados.
- CustomID é um identificador de correlação, e retentativas precisam de uma resposta separada. O CustomID do Mailjet acompanha os eventos para rastreamento; ele não deduplica. A deduplicação deles é X-Mailjet-DeduplicateCampaign, um booleano usado com X-Mailjet-Campaign que impede uma campanha de alcançar o mesmo destinatário duas vezes, o que é uma garantia no escopo da campanha e não uma retentativa segura de uma requisição. Aqui, coloque seu ID de correlação em metadata ou tags, e use o header Idempotency-Key para tornar uma requisição retentada segura.
- Templates armazenados portam diretamente. TemplateID + Variables do Mailjet mapeiam para nosso campo template (referenciado por ID ou slug) com valores em template.parameters. Veja enviando com um template. Lógica de template além de substituição de variáveis também porta: condicionais e loops TemplateLanguage do Mailjet viram {% if %} e {% for %} Liquid no nosso template.
- Anexos portam diretamente. O Base64Content do Mailjet é nosso content em base64, e InlinedAttachments + ContentID viram entradas attachments com content_id. Veja anexos.
Exportar supressões
O Mailjet mantém endereços inalcançáveis e indesejados na sua blocklist (bounces hard/soft e envios bloqueados) e rastreia sinais de spam e cancelamento de inscrição separadamente. Exporte os endereços bloqueados e com bounce das páginas de estatísticas de contato do Mailjet, ou extraia-os pela API de gerenciamento de contatos, e passe a lista pelo loop de importação. Se você envia e-mail de marketing, transfira também os contatos marcados como cancelados para que essas preferências sobrevivam à mudança.
Traduzir eventos de webhook
O Event API do Mailjet envia um gatilho por tipo de evento. O mapeamento para nosso vocabulário de eventos:
| Resultado | Mailjet | Bird |
|---|---|---|
| Aceito/processado | (nenhum) | email.accepted → email.processed |
| Entregue | sent | email.delivered |
| Bounce permanente | bounce | email.bounced / email.out_of_band_bounce |
| Bloqueado | blocked | email.rejected |
| Reclamação de spam | spam | email.complained |
| Abertura | open | email.opened |
| Clique | click | email.clicked |
| Cancelamento de inscrição | unsub | email.unsubscribed / email.list_unsubscribed |
Duas diferenças que vale a pena tratar no código:
- Nós reportamos os estágios pré-entrega explicitamente. O sent do Mailjet dispara quando o servidor de e-mail do destinatário aceita a mensagem, o que corresponde ao nosso email.delivered. Nós também emitimos email.accepted e email.processed antes dele, para que você veja o envio progredindo antes da confirmação de entrega. Não trate esses eventos anteriores como entrega.
- Eventos têm escopo por destinatário. O Mailjet identifica eventos por MessageID. Nossos eventos de entrega têm recipient_id junto com email_id, então um envio com vários destinatários produz um fluxo de eventos por destinatário. Nós assinamos entregas conforme a especificação Standard Webhooks. Veja Webhooks e eventos para verificação.
Migração final
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 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 migração final
- 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