Sign inGet started

Migrar do Amazon SES

Esta página mapeia a chamada SendEmail do SES v2, a lista de supressão no nível da conta e as notificações de eventos do SNS para Bird. Siga o guia principal de migração na ordem indicada e use estes mapeamentos para os passos 1, 3 e 4.

Passe isso para o seu agente

Cole isso 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: 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 Amazon SES 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/ses.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 SES usage in this repository and its infrastructure before you change anything: the SendEmail and SendRawEmail call sites through the AWS SDK or CLI, the configuration sets they name, the SNS topics or EventBridge rules carrying my events, the handler subscribed to them, and every identity I send from. Say which of these live in infrastructure code rather than application code, because those change by a different route.
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 the SES DKIM CNAMEs exactly as they are: Bird's DKIM record uses its own selector, so the two coexist 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 account-level suppression list from SES 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 from GET /v2/email/suppressed-destinations, paginating with NextToken to the end, and keep both the BOUNCE and COMPLAINT reasons. 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 replace the event plumbing. Bird posts signed webhooks straight to an endpoint, so the SNS topic, the subscription-confirmation handshake, and the message-envelope unwrapping all go away rather than being ported: my handler reads the event body directly and verifies it per Standard Webhooks. See https://bird.com/docs/guides/webhooks.md and https://bird.com/docs/guides/email/events.md. Tell me which SNS or EventBridge resources become unused, but do not delete any of them.
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 SES path is a separate step that comes later: ask me again and wait for me to reply with the words retire the SES 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 SES divide um envio entre Destination, Content e o encanamento de configuration sets. Nosso POST /v1/email/messages é um único payload plano:
O que fazSES (SendEmail v2)Bird
RemetenteFromEmailAddressfrom
DestinatáriosDestination.*Addressesto / cc / bcc (arrays)
AssuntoContent.Simple.Subjectsubject
CorpoContent.Simple.Body.Html/Texthtml / text (pelo menos um)
Reply-toReplyToAddressesreply_to (array)
Headers personalizadosContent.Simple.Headersheaders (objeto string → string)
Labels filtráveisEmailTagstags: pares {name, value}
Contexto de ida e volta(nenhum)metadata: JSON arbitrário
Template armazenadoContent.Templatetemplate + template.parameters
Rastreamento de abertura/cliqueconfiguration settrack_opens / track_clicks (padrão true)
Pool de IPsdedicated IP pool (config set)ip_pool_id (ipp_... ou ipp_shared)
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 Envio de e-mail.
Notas de portabilidade:
  • Configuration sets se dissolvem em campos por mensagem. Rastreamento, pool de IPs e roteamento de eventos eram responsabilidades de configuration sets no SES. Aqui, os dois primeiros são campos do payload e o roteamento de eventos é uma assinatura de webhook.
  • A autenticação muda de SigV4 para bearer token. Sem assinatura de requisição; apenas um header Authorization: Bearer bk_... simples. Remova a cadeia de credenciais SDK da AWS deste caminho de código.
  • Templates do SES migram para templates armazenados. Content.Template (nome do template mais TemplateData) mapeia para o nosso campo template com valores em template.parameters. Veja envio com template.
  • Content.Raw (MIME) não tem equivalente. Nós montamos a mensagem a partir de campos estruturados. Se você monta MIME bruto para anexar arquivos, envie-os como nosso array de attachments (base64 content por arquivo, content_id para imagens inline).
  • Sandbox do SES ≠ sandbox Bird. O sandbox do SES restringe para quem você pode enviar. Nosso sandbox de e-mail é um simulador com endereços mágicos: sem allowlisting e nada é entregue.

Exportar supressões

Exporte a lista de supressão no nível da conta e passe-a pelo loop de importação:
  • GET /v2/email/suppressed-destinations (pagine com NextToken; cada entrada tem BOUNCE ou COMPLAINT como motivo)

Traduzir eventos de webhook

O SES publica eventos pelo SNS ou EventBridge. Nós enviamos webhooks assinados via POST diretamente, então o tópico SNS, o handshake de confirmação de assinatura e o desempacotamento do envelope de mensagem deixam de existir. Os nomes dos eventos mapeiam assim:
ResultadoSESBird
Aceito/processadoSendemail.acceptedemail.processed
EntregueDeliveryemail.delivered
Falha temporáriaDeliveryDelayemail.deferred
Bounce permanenteBounceemail.bounced / email.out_of_band_bounce
Reclamação de spamComplaintemail.complained
Bloqueado/suprimido(nenhum)email.rejected
AberturaOpenemail.opened
CliqueClickemail.clicked
DescadastramentoSubscriptionemail.list_unsubscribed
email.rejected é novo em relação ao SES: reportamos destinatários suprimidos de forma visível (status rejected, rejection_reason: recipient_suppressed) em vez de contabilizá-los no ciclo de envio e bounce. Adicione um handler para ele.
No lugar da verificação de mensagens do SNS, assinamos conforme a especificação Standard Webhooks, com headers HMAC na própria entrega. A receita de verificação está em Webhooks & events.

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. Uma nota específica do SES para a etapa de DNS: os CNAMEs DKIM do SES permanecem durante a transição. Nosso registro TXT DKIM usa seu próprio seletor, então os dois coexistem.

Próximos passos

  • Domínios de envio: registro, ciclo de vida de verificação e os registros DNS que você está redirecionando
  • Webhooks & events: 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