# Migrar desde Postmark

> Pasa de Postmark a Emailit. Equivalencias de servidores, message streams y tokens, conversión de los campos de la API, cambio de la configuración SMTP y traslado de webhooks, direcciones bloqueadas y plantillas.

Esta guía relaciona los conceptos, las llamadas a la API, los webhooks, las direcciones bloqueadas y las plantillas de Postmark con sus equivalentes en Emailit. Lee primero [Migrar a Emailit](/es/docs/migrate/) para conocer el orden general y cómo usar los dos proveedores en paralelo.

## Conceptos

| Postmark | Emailit |
| --- | --- |
| Cuenta | Cuenta |
| Server | [Espacio de trabajo](/es/docs/workspaces/), o un espacio de trabajo con varios dominios de envío |
| Server API token | [Clave de API](/es/docs/developers/api-keys/) **Sending Only**, limitada opcionalmente a un dominio |
| Account API token | Clave de API con **Full Access** |
| Message stream transaccional | La [API de email](/es/docs/email-api/) y el [SMTP relay](/es/docs/smtp/) |
| Message stream de broadcasts | [Campañas](/es/docs/campaigns/) a [listas de contactos](/es/docs/audiences/), o la API con tu propia cabecera `List-Unsubscribe` |
| Message stream de entrada | [Emails entrantes](/es/docs/inbound/) en un subdominio como `inbound.acme.com` |
| Sender signatures y dominios | [Dominios de envío](/es/docs/domains/). Las sender signatures de una sola dirección no están disponibles. |
| Plantillas y layouts | [Plantillas](/es/docs/templates/) con un alias y versiones. No hay layouts. |
| Webhooks por stream | [Webhooks](/es/docs/webhooks/) por espacio de trabajo |
| Suppressions por stream | Una [lista de direcciones bloqueadas](/es/docs/suppressions/) por espacio de trabajo |
| Activity | **Email API → Emails** y **Email API → Logs** |
| `Tag` y `Metadata` | `meta` |

Para mantener separadas la reputación transaccional y la de marketing, envía cada tipo desde dominios o subdominios distintos, como `mail.acme.com` para los recibos y `news.acme.com` para las newsletters.

## Actualizar las llamadas a la API

`POST /email` de Postmark con un `X-Postmark-Server-Token` pasa a ser `POST /v2/emails` con un token bearer. Los nombres de los campos pasan de PascalCase a snake_case:

```bash title="Antes: Postmark"
curl https://api.postmarkapp.com/email \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Postmark-Server-Token: $POSTMARK_SERVER_TOKEN" \
  -d '{
    "From": "Acme <hello@acme.com>",
    "To": "ada@example.com",
    "Subject": "Your receipt",
    "TextBody": "Thanks for your order.",
    "HtmlBody": "<p>Thanks for your order.</p>",
    "MessageStream": "outbound"
  }'
```

```bash title="Después: Emailit"
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <hello@acme.com>",
    "to": "ada@example.com",
    "subject": "Your receipt",
    "text": "Thanks for your order.",
    "html": "<p>Thanks for your order.</p>"
  }'
```

| Postmark | Emailit |
| --- | --- |
| Cabecera `X-Postmark-Server-Token` | `Authorization: Bearer secret_…` |
| `From` | `from` |
| `To`, `Cc`, `Bcc` (cadenas separadas por comas) | `to`, `cc`, `bcc` como cadena o como array de hasta 50 cada uno |
| `ReplyTo` | `reply_to` |
| `Subject` | `subject` |
| `HtmlBody`, `TextBody` | `html`, `text` |
| `Headers: [{ "Name": "…", "Value": "…" }]` | `headers: { "Name": "Value" }` |
| `Metadata`, `Tag` | `meta`, que se devuelve en los eventos de webhook |
| `TrackOpens`, `TrackLinks` | `tracking: { "loads": true, "clicks": true }` |
| `Attachments[]` con `Name`, `Content`, `ContentType`, `ContentID` | `attachments[]` con `filename`, `content`, `content_type`, `content_id` |
| `MessageStream` | No es necesario |
| `POST /email/withTemplate` con `TemplateAlias` o `TemplateId` y `TemplateModel` | El mismo `POST /v2/emails` con `template` (un alias o ID) y `variables` |
| Respuesta con `MessageID` y `ErrorCode: 0` | `200` con `id` (`em_…`), `status: "accepted"` e `ids` por destinatario. Los errores usan códigos de estado HTTP. |

Emailit no tiene endpoint de envío por lotes. Envía una petición por mensaje, cada una con hasta 50 destinatarios, y añade una cabecera `Idempotency-Key` para que los reintentos sean seguros. Consulta [Enviar un email](/es/docs/email-api/send-email/).

## Cambiar la configuración SMTP

| Ajuste | Postmark | Emailit |
| --- | --- | --- |
| Host | `smtp.postmarkapp.com` | `smtp.emailit.com` |
| Puerto | `587`, `2525` o `25` | `587` (STARTTLS), `465` (TLS), `2525`, `2587` o `25` |
| Usuario | Tu server API token | `emailit` |
| Contraseña | Tu server API token | Tu clave de API de Emailit |

Emailit no lee las cabeceras `X-PM-*`, como `X-PM-Message-Stream` o `X-PM-Tag`. Elimínalas y configura el seguimiento en el dominio. Consulta [Configuración SMTP](/es/docs/smtp/settings/).

## Equivalencias de los eventos de webhook

| Webhook de Postmark | Evento de Emailit |
| --- | --- |
| Delivery | `email.delivered` |
| Bounce, tipos de rebote duro | `email.bounced` |
| Bounce, tipos blandos o transitorios | `email.attempted` mientras Emailit reintenta, y después `email.bounced` si fallan todos los reintentos |
| Spam complaint | `email.complained` |
| Open | `email.loaded` |
| Click | `email.clicked` |
| Subscription change | `email.unsubscribed` para los emails de campaña, y `suppression.created` o `suppression.deleted` para los bloqueos que añades o eliminas con la API |
| Inbound | `email.received`; después, obtén el contenido con [`GET /emails/{id}`](/es/docs/api-reference/emails/get/) |

Emailit también envía `email.accepted` cuando la API acepta un email, algo para lo que Postmark no tiene webhook.

El formato de las peticiones cambia:

- Postmark envía un registro por petición y lo identifica en `RecordType`. Emailit envía un array JSON de hasta 100 eventos, con el nombre en `type` y el email en `data.object`.
- Usa `data.object.id`, el ID `em_` de la respuesta de envío, en lugar de `MessageID`. Tus valores de `meta` están en `data.object.meta`.
- Los webhooks de Postmark suelen protegerse con credenciales de autenticación básica en la URL. Emailit, en cambio, firma todas las peticiones: verifica `X-Emailit-Signature` con `X-Emailit-Timestamp` y tu secreto `whsec_`. Consulta [Verificar las firmas de los webhooks](/es/docs/webhooks/request-signature/).

```javascript
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

1. Exporta las suppressions de cada message stream de Postmark desde el que envías, desde la página de suppressions del stream o con la API de volcado de suppressions. Incluye los rebotes duros, las quejas por spam y los bloqueos manuales.

2. Crea un único CSV con las columnas `email,type,reason`:

```csv
email,type,reason
old-address@example.com,recipient,postmark hard bounce
angry@example.com,recipient,postmark spam complaint
```

   Usa el tipo `recipient` para las direcciones que nunca deben recibir emails. Bloquea los envíos por API, por SMTP y de campañas. Para las personas que solo se dieron de baja de tus broadcasts, usa el tipo `unsubscribe`, que detiene las campañas pero sigue dejando pasar los emails transaccionales.

3. En **Email API → Suppressions**, 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.

Consulta [Gestionar las direcciones bloqueadas](/es/docs/suppressions/manage/).

## Trasladar las plantillas

Copia el HTML de cada plantilla de Postmark, incluido su layout, y después impórtalo en **Email Marketing → Templates** o crea la plantilla con la [API de plantillas](/es/docs/api-reference/templates/create/). Emailit no tiene layouts, así que combina el layout y el contenido en una sola plantilla. Usa el mismo alias que usabas en Postmark para que los cambios en tu código sean mínimos.

Las plantillas de Postmark usan Mustachio. Temple cubre los valores simples y las condiciones:

| Postmark (Mustachio) | Emailit (Temple) |
| --- | --- |
| `{{name}}` | `{{name}}` |
| `{{company.name}}` | `{{company.name}}` |
| Secciones `{{#company}}…{{/company}}` | `{{#if company}}…{{/if}}`, con rutas completas como `{{company.name}}` dentro |
| Secciones invertidas `{{^name}}…{{/name}}` | `{{#if name}}{{else}}…{{/if}}` |
| `{{#each items}}…{{/each}}` | No compatible. Genera la lista en tu código y pásala como una sola variable. |
| `TemplateModel` | `variables` |

Temple nunca escapa el HTML, así que escapa los datos que introducen los usuarios antes de pasarlos. Un valor que falta se renderiza como una cadena vacía, salvo que añadas un valor por defecto, como `{{name|"there"}}`. Consulta [Lenguaje de plantillas Temple](/es/docs/templates/temple/).

## Cambiar los DNS

Añade tu dominio en **Email API → Domains** 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 el registro DKIM de Postmark ni con su CNAME de return-path `pm-bounces`. Conserva tu registro DMARC. Después del cambio definitivo, elimina los registros de Postmark. Consulta [Registros DNS de los dominios de envío](/es/docs/domains/dns-records/).

Si procesas correo entrante con Postmark, trasládalo a un subdominio de entrada de Emailit y actualiza las direcciones que facilita tu aplicación. Consulta [Configurar el email entrante](/es/docs/inbound/set-up/).

## Próximos pasos

- [Lista de comprobación para pasar a producción](/es/docs/get-started/go-live/)
- [Configurar un webhook](/es/docs/webhooks/set-up/)
- [Migración prioritaria](/es/docs/programs/priority-migration/): deja que los ingenieros de Emailit hagan la migración contigo

---
Fuente: https://emailit.com/es/docs/migrate/postmark/
