Guía
Migrar desde Resend
Pasa de Resend a Emailit. Las API se parecen, así que los cambios son pequeños. Equivalencias de campos, configuración SMTP y eventos de webhook, verificación de firmas y traslado de contactos.
Esta guía relaciona los conceptos, las llamadas a la API, los webhooks y las plantillas de Resend con sus equivalentes en Emailit. Las dos API tienen una forma parecida, así que la mayoría de los cambios en el código son pequeños. Lee primero Migrar a Emailit para conocer el orden general y cómo usar los dos proveedores en paralelo.
Conceptos
| Resend | Emailit |
|---|---|
| Team | Espacio de trabajo. Cada espacio de trabajo tiene sus propios dominios, claves, miembros y créditos. |
| Clave de API con acceso total o de envío | Clave de API: Full Access, o Sending Only limitada opcionalmente a un dominio |
| Domains | Dominios de envío |
| Audiences y contactos | Contactos y listas de contactos |
| Broadcasts | Campañas |
| Webhooks | Webhooks |
| Emails y logs | Email APIEmails y Email APILogs |
tags |
meta |
| Componentes de React Email | HTML que renderizas en tu código, o plantillas diseñadas en el panel |
Actualizar las llamadas a la API
POST /emails de Resend pasa a ser POST /v2/emails de Emailit, con casi los mismos campos. En Node.js:
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: 'Acme <hello@acme.com>',
to: ['ada@example.com'],
subject: 'Your receipt',
html: '<p>Thanks for your order.</p>',
});import { Emailit } from '@emailit/node';
const emailit = new Emailit(process.env.EMAILIT_API_KEY);
await emailit.emails.send({
from: 'Acme <hello@acme.com>',
to: ['ada@example.com'],
subject: 'Your receipt',
html: '<p>Thanks for your order.</p>',
});| Resend | Emailit |
|---|---|
Authorization: Bearer re_… |
Authorization: Bearer secret_… |
from, subject, html, text, headers |
Igual |
to, cc, bcc |
Igual, hasta 50 cada uno |
reply_to (replyTo en el SDK de Node.js) |
reply_to |
react (SDK de Node.js) |
No disponible. Renderiza el componente a HTML y pasa html. |
attachments[] con filename y content o path |
attachments[] con filename y content en base64 o una url. content_type es obligatorio con content. |
tags: [{ "name": "…", "value": "…" }] |
meta: { "name": "value" }, que se devuelve en los eventos de webhook |
scheduled_at |
scheduled_at (ISO 8601, tiempo Unix o lenguaje natural en inglés) |
Cabecera Idempotency-Key |
Cabecera Idempotency-Key, que se conserva durante 24 horas |
POST /emails/batch |
No disponible. Envía una petición por mensaje. |
Respuesta { "id": "…" } |
200 con id (em_…), status: "accepted" e ids con un ID por destinatario |
Cada destinatario de una petición a Emailit se convierte en un email independiente con su propio ID. Cuando envías a varios destinatarios, ids en la respuesta asocia cada dirección con su ID. Emailit también hace el seguimiento de aperturas y clics por email con tracking: { "loads": true, "clicks": true }, una vez que el dominio tiene un subdominio de seguimiento verificado. Consulta Enviar un email.
React Email
Si creas los emails con React Email, conserva tus componentes y renderízalos tú antes de enviar:
import { render } from '@react-email/render';
import Receipt from './emails/receipt';
const html = await render(<Receipt order={order} />);
const text = await render(<Receipt order={order} />, { plainText: true });
await emailit.emails.send({ from, to, subject, html, text });Cambiar la configuración SMTP
| Ajuste | Resend | Emailit |
|---|---|---|
| Host | smtp.resend.com |
smtp.emailit.com |
| Puerto | 587, 2587 o 25 (STARTTLS), 465 o 2465 (TLS) |
587, 2587, 2525 o 25 (STARTTLS), 465 (TLS) |
| Usuario | resend |
emailit |
| Contraseña | Tu clave de API de Resend | Tu clave de API de Emailit |
Consulta Configuración SMTP.
Equivalencias de los eventos de webhook
| Evento de Resend | Evento de Emailit |
|---|---|
email.sent |
email.accepted (solo API) |
email.delivered |
email.delivered |
email.delivery_delayed |
email.attempted |
email.bounced |
email.bounced |
email.complained |
email.complained |
email.opened |
email.loaded |
email.clicked |
email.clicked |
contact.created, contact.updated, contact.deleted |
Los mismos nombres |
domain.created, domain.updated, domain.deleted |
Los mismos nombres |
El formato de las peticiones cambia:
- Resend envía un evento por petición. Emailit envía un array JSON de hasta 100 eventos, así que recorre el cuerpo.
- El email está en
data.object. Usadata.object.id, el IDem_de la respuesta de envío, en lugar dedata.email_id. Tus valores demetaestán endata.object.meta. - Las firmas funcionan de otra manera. Resend firma los webhooks a través de Svix, con cabeceras
svix-*. Emailit envíaX-Emailit-Signature, el HMAC-SHA256 en hexadecimal de<timestamp>.<raw body>, con el secreto completo, incluido el prefijowhsec_, como clave. Una biblioteca de verificación de Svix no funcionará, aunque los dos secretos empiecen porwhsec_. Consulta Verificar las firmas de los webhooks.
for (const event of req.body) {
const email = event.data.object;
if (event.type === 'email.bounced') markBounced(email.to, email.id);
if (event.type === 'email.complained') unsubscribe(email.to);
}Trasladar las direcciones bloqueadas y los contactos
-
Reúne todas las direcciones que rebotaron o generaron quejas mientras usabas Resend, desde el panel de Resend o a partir de los eventos que guardaron tus webhooks.
-
Crea un único CSV con las columnas
email,type,reason:email,type,reason old-address@example.com,recipient,resend bounce angry@example.com,recipient,resend complaintUsa el tipo
recipientpara las direcciones que nunca deben recibir emails. Bloquea los envíos por API, por SMTP y de campañas. -
En Email APISuppressions, selecciona Import y sube el archivo. Cada archivo puede tener hasta 10.000 filas y ocupar como máximo 8 MB. Los duplicados se omiten.
Si envías broadcasts, exporta cada audience de Resend como CSV e impórtala en Email MarketingContacts con Import, eligiendo la lista de contactos correspondiente de Emailit. Asigna la columna de baja para que las personas que se dieron de baja sigan dadas de baja. Consulta Importar y exportar contactos.
Trasladar las plantillas
Si renderizas los emails en tu código, con React Email o con cualquier otra herramienta, no cambia nada: envía el HTML. Si guardas plantillas en Resend, vuelve a crearlas en Email MarketingTemplates o con la API de plantillas, asigna un alias a cada una y envíalas con template y variables.
Las plantillas de Emailit usan Temple: {{name}}, valores anidados como {{user.name}}, valores por defecto como {{name|"there"}} y {{#if plan}}…{{else}}…{{/if}}. No hay bucles, así que genera las listas en tu código. Temple nunca escapa el HTML, así que escapa los datos que introducen los usuarios antes de pasarlos.
Cambiar los DNS
Añade tu dominio en Email APIDomains y publica los registros de Emailit. Usan sus propios nombres (emailit._domainkey, emailit.<domain> y, opcionalmente, go e inbound), así que no entran en conflicto con los registros de Resend, que normalmente están en resend._domainkey y en un subdominio send. Conserva tu registro DMARC. Después del cambio definitivo, elimina los registros de Resend. Consulta Registros DNS de los dominios de envío.
Próximos pasos
- Lista de comprobación para pasar a producción
- Configurar un webhook
- Migración prioritaria: deja que los ingenieros de Emailit hagan la migración contigo