Migrar desde SendGrid
Esta página asocia el payload v3 Mail Send de SendGrid, las listas de supresión y el Event Webhook con Bird. Sigue la guía principal de migración en orden y usa estas correspondencias para los pasos 1, 3 y 4.
Pasa esto a tu agente
Pega esto en Claude Code, Cursor o Codex. El agente recorre esta página contra tu propio repositorio, usando la superficie de Bird que ya tenga: el servidor MCP si hay uno conectado, o CLI si está instalado y con sesión iniciada.
Ejemplo de código
I am moving an email integration from SendGrid 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/sendgrid.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 SendGrid usage in this repository before you change anything: the /v3/mail/send call sites and any SDK wrappers around them, the Event Webhook 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 suppressions from SendGrid 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. SendGrid splits these across GET /v3/suppression/bounces, GET /v3/suppression/spam_reports, GET /v3/suppression/unsubscribes, and GET /v3/asm/groups/{group_id}/suppressions for each unsubscribe group worth carrying over. 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. Bird signs deliveries per Standard Webhooks rather than SendGrid'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 SendGrid path is a separate step that comes later: ask me again and wait for me to reply with the words retire the SendGrid 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.Asociar la llamada de envío
El POST /v3/mail/send de SendGrid envuelve a los destinatarios en un array personalizations. Nuestro POST /v1/email/messages es un payload plano, así que cada personalización se convierte en su propio envío (o en una entrada de lote).
| Qué hace | SendGrid | Bird |
|---|---|---|
| Remitente | from.email | from |
| Destinatarios | personalizations[].to / cc / bcc | to / cc / bcc (arrays) |
| Asunto | subject | subject |
| Cuerpo | content[] (type + value) | html / text (al menos uno) |
| Reply-to | reply_to / reply_to_list | reply_to (array) |
| Cabeceras personalizadas | headers | headers (objeto string → string) |
| Etiquetas filtrables | categories | tags: pares {name, value} |
| Contexto de ida y vuelta | custom_args | metadata: JSON arbitrario |
| Plantilla almacenada | template_id + dynamic_template_data | template + template.parameters |
| Programación | send_at | scheduled_at |
| Seguimiento de aperturas/clics | tracking_settings | track_opens / track_clicks (por defecto true) |
| Pool de IP | ip_pool_name | ip_pool_id (ipp_... o ipp_shared) |
| Categoría | (ninguno) | category: marketing (por defecto) o transactional |
Los límites y valores por defecto de nuestros campos (cantidad de destinatarios, límites de tags y metadatos) están en Envío de correo electrónico.
Notas de migración:
- Los categories son cadenas simples. Nuestros tags son pares. Una categoría como "welcome" se convierte en {"name": "category", "value": "welcome"}. Elige un name estable para que tus dashboards filtren como lo hacían tus estadísticas de SendGrid.
- Los custom_args se incluían en cada evento. Nuestro metadata funciona de la misma manera. Incluimos tu metadata (y tags) en cada evento de webhook junto con email_id/recipient_id, para que tus handlers recuperen tu contexto sin una consulta adicional.
- Las plantillas dinámicas migran a plantillas almacenadas. template_id más dynamic_template_data se convierten en template (referenciada por ID o slug) más template.parameters en la misma llamada de envío. Consulta envío con plantilla. send_at se asocia directamente a scheduled_at.
- Los adjuntos migran directamente. Los attachments de SendGrid (content en base64, type, filename, content_id para inline) se asocian campo por campo con nuestro array de adjuntos.
- Los grupos de cancelación de suscripción (asm) no migran como concepto: gestionamos list-unsubscribe a nivel de categoría, así que el correo marketing obtiene manejo de cancelación de suscripción con reconocimiento de supresión automáticamente.
Exportar supresiones
SendGrid reparte las supresiones en varios endpoints; exporta cada uno y pásalos por el bucle de importación:
- GET /v3/suppression/bounces
- GET /v3/suppression/spam_reports
- GET /v3/suppression/unsubscribes (cancelaciones de suscripción globales)
- GET /v3/asm/groups/{group_id}/suppressions para cada grupo de cancelación de suscripción que quieras conservar
Traducir eventos de webhook
| Resultado | SendGrid Event Webhook | Bird |
|---|---|---|
| Aceptado/procesado | processed | email.accepted → email.processed |
| Entregado | delivered | email.delivered |
| Fallo temporal | deferred | email.deferred |
| Rebote permanente | bounce | email.bounced / email.out_of_band_bounce |
| Queja de spam | spamreport | email.complained |
| Bloqueado/suprimido | dropped | email.rejected |
| Apertura | open | email.opened |
| Clic | click | email.clicked |
| Cancelación de suscripción | unsubscribe / group_unsubscribe | email.unsubscribed / email.list_unsubscribed |
La equivalencia dropped ↔ email.rejected es la que debes probar: al igual que SendGrid, reportamos los destinatarios suprimidos de forma visible (estado rejected, rejection_reason: recipient_suppressed) en lugar de descartarlos silenciosamente, así que tu lógica de auditoría migra sin problemas.
La verificación cambia más que los nombres de los eventos: el Event Webhook de SendGrid firma con una clave pública ECDSA, mientras que nosotros firmamos según el esquema HMAC de Standard Webhooks. Reemplaza tu código de verificación por la receta en Webhooks y eventos. SendGrid también agrupa eventos en arrays JSON. Nosotros entregamos un evento por solicitud.
Migración final
Sigue los pasos de dominios y DNS y la prueba de humo en sandbox en la guía principal. Ambos son independientes del proveedor.
Próximos pasos
- Dominios de envío: registro, ciclo de vida de verificación y los registros DNS que vas a redirigir
- Webhooks y eventos: configuración de endpoints y verificación con Standard Webhooks
- Sandbox de pruebas: prueba de humo de la nueva integración antes de la migración final
- Supresiones: confirma tu lista importada y cómo la mantenemos a partir de ahora
Recursos relacionados
Continúa con la documentación, guías y ejemplos sobre este tema. Los recursos están en inglés.
Ver la guíaGetting started with emailExplorar la funcionalidadEmailSeguir la ruta de aprendizajeBuild your first integrationGuía de implementaciónSend your first email
Prueba el ejercicio y obtén un resumen de implementación