Novedad: campañas, automatizaciones y correos del producto en la misma cuenta. Conoce Postal
Iniciar sesión Crear cuenta

De Amazon SES a Postal, con SES por debajo

Ya envías por SES. En Postal, la entrega sigue siendo de SES, y lo que antes quedaba a tu cargo pasa a venir listo: dominio guiado, eventos en webhooks, lista de supresión y cuidado de la reputación.

Para comprobar el DNS
Hasta 72 h
Funcionan los dos
API o SMTP
Eventos ya en webhooks
Sin SNS
La región de envío
Por dominio

Visión general

Lo que cambia cuando SES queda por debajo

Postal envía por su cuenta de Amazon SES, y no por la tuya. Eso cambia quién se encarga de cada cosa.

Hoy, directo en SES

  1. Tu sistemaEnvías con el SDK de AWS o por el SMTP de SES.
  2. Tú configuras y vigilasIdentidad y DKIM, configuration set, tema de SNS, lista de supresión, cuotas y salida del sandbox.
  3. Amazon SESEn tu cuenta de AWS.

Con Postal

  1. Tu sistemaEnvías por la API o por el SMTP de Postal.
  2. Postal se encargaDominio guiado, eventos en webhooks, supresión por equipo y reputación, con aviso antes de pausar.
  3. Amazon SESEn la cuenta de Postal, en la región que eliges para el dominio.

La documentación de Postal no trata las IPs dedicadas de SES. Si tu cuenta usa IPs dedicadas, habla con nosotros por el formulario de contacto antes de migrar.

1

Haz el inventario en SES

Antes de cambiar nada, enumera lo que tu sistema usa en SES. Cada elemento tiene un lugar en Postal. Las identidades de SES valen para una sola región, así que anota las regiones desde las que envías.

En la consola de SESQué anotarDónde queda en Postal
IdentitiesDominios y direcciones verificados, y la región de cada unoDominios (la región se elige por dominio)
Configuration setsNombres y destinos de eventoWebhooks, y el rastreo de apertura y clic en el dominio
Email templatesNombre de la plantilla y las variablesPlantillas
Temas de SNSQuién se suscribe y qué código recibe los eventosWebhooks
Suppression listDirecciones suprimidas, por regiónSupresiones
SMTP settingsQuién usa las credenciales SMTPClaves de API
2

Verifica el dominio en Postal

Añade el dominio en Dominios (o con POST /domains), elige la región y publica los registros que muestra Postal. Ella comprueba el DNS sola durante hasta 72 horas, muestra el estado de cada registro y explica qué está mal. El dominio puede seguir verificado en SES al mismo tiempo: los nombres de los registros son diferentes.

Registros de SES y de Postal lado a lado
En SESEn Postal
DKIM3 registros CNAME, <token>._domainkey, que apuntan a <token>.dkim.<região>.amazonses.com (Easy DKIM)1 registro TXT, postal._domainkey, con la clave pública de Postal
Return-Path (MAIL FROM)Opcional. Un subdominio tuyo, con MX 10 feedback-smtp.<região>.amazonses.com y TXT "v=spf1 include:amazonses.com ~all"El subdominio postal (cambia con custom_return_path): MX hacia feedback-smtp.<região>.amazonses.com y TXT v=spf1 include:_spf.postal.so ~all
SPF del dominio principalTuyo, si incluiste amazonses.comNo cambia: el SPF de Postal queda en el subdominio del Return-Path
DMARCTuyoSigue vigente. Postal no lo exige, pero los grandes proveedores lo piden a quien envía volumen
RegiónUna identidad por regiónUna región por dominio: São Paulo (predeterminada), Virginia del Norte, Ohio, Irlanda o Tokio
PlazoHasta 72 horas para que el DNS se propagueHasta 72 horas, con diagnóstico en portugués por registro
  • Si tu Return-Path en SES ya se llama postal, elige otro nombre en Postal con custom_return_path, para no mezclar los registros.
  • Para migrar poco a poco, usa un subdominio solo de correo, como mail.exemplo.com.br.
  • Postal avisa por el webhook domain.updated cuando el dominio pasa a verified. Consulta Dominios y DNS.
3

Cambia la llamada del SDK por la API

Crea una clave de API (acceso total, o solo de envío y restringida al dominio) y cambia el SendEmail del SDK de AWS por POST /emails. La respuesta trae el id del correo electrónico, en lugar del MessageId.

envio.js
- import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2'- - const ses = new SESv2Client({ region: 'us-east-1' })- await ses.send(new SendEmailCommand({-   FromEmailAddress: 'Aurora Cosméticos <[email protected]>',-   Destination: { ToAddresses: ['[email protected]'] },-   Content: { Simple: {-     Subject: { Data: 'Tu pedido salió para la entrega' },-     Body: { Html: { Data: '<p>El pedido #10482 está en camino.</p>' } },-   } },-   EmailTags: [{ Name: 'category', Value: 'shipping' }],- }))+ await fetch('https://api.postal.so/emails', {+   method: 'POST',+   headers: {+     Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,+     'Content-Type': 'application/json',+   },+   body: JSON.stringify({+     from: 'Aurora Cosméticos <[email protected]>',+     to: ['[email protected]'],+     subject: 'Tu pedido salió para la entrega',+     html: '<p>El pedido #10482 está en camino.</p>',+     tags: [{ name: 'category', value: 'shipping' }],+   }),+ })
SendEmail de SES y POST /emails
Campo en SES (SendEmail, v2)En PostalQué cambia
FromEmailAddressfromEl dominio debe estar verificado en Postal.
Destination.ToAddressestoTexto o lista, con hasta 50 destinatarios.
CcAddresses, BccAddressescc, bccIguais.
ReplyToAddressesreply_toTexto o lista.
Content.Simple (Subject, Body.Html, Body.Text)subject, html, textSin los objetos Data y Charset: es el texto directo.
Content.Simple.HeadersheadersUn objeto nombre → valor. Algunos nombres no se pueden cambiar (From, To, Subject...).
Content.Simple.Attachmentsattachmentsfilename y content en base64, o path con una URL. Hasta 40 MB en total. El content_id sirve para imágenes incrustadas.
Content.Template (TemplateName, TemplateData)template (id o alias, variables)Las variables pasan de {{nome}} a {{{NOME}}}. Solo texto y números: las listas y los objetos anidados deben resolverse antes de enviar.
Content.RawSin campo en la APIUsa el SMTP de Postal, que entrega el mensaje tal como llegó.
EmailTags (Name, Value)tags (name, value)Letras ASCII, números, _ y -. Hasta 50 por correo electrónico.
ConfigurationSetNameNo hace faltaLos eventos van a los webhooks.
ConfigurationOverrides.Trackingopen_tracking, click_trackingQuedan configurados en el dominio, no en cada mensaje.
FeedbackForwardingEmailAddressNo hace faltaLos rebotes y las quejas se convierten en eventos y pasan a la supresión. El Return-Path es de Postal.
SendBulkEmailPOST /emails/batchUna lista de hasta 100 correos electrónicos (en SES, hasta 50 destinos). Sin adjuntos ni scheduled_at, y depende del plan.
No existescheduled_at, Idempotency-KeyNovedades: programar hasta 30 días (depende del plan) y repetir una llamada sin duplicar el envío, durante 24 horas.
  • Los errores llegan con el estado HTTP y un JSON {statusCode, name, message}. La cuota responde 429 y la pausa por reputación, 403 sending_paused.
  • ¿Prefieres un SDK? Los de Postal (Node.js, PHP y Laravel) y el de Resend, apuntando a Postal, usan la misma API. Consulta SDKs y CLI y la referencia de correos.
4

Si envías por SMTP, cambia solo el servidor

Los sistemas que hablan SMTP, como WordPress, los ERP y las plataformas de tienda, cambian cuatro campos: servidor, puerto, usuario y contraseña. La contraseña deja de ser la contraseña SMTP derivada de una clave de IAM y pasa a ser una clave de API de Postal.

.env de Laravel
- MAIL_HOST=email-smtp.us-east-1.amazonaws.com- MAIL_PORT=587- MAIL_USERNAME=<usuario SMTP de SES>- MAIL_PASSWORD=<contraseña SMTP de SES>+ MAIL_HOST=smtp.postal.so+ MAIL_PORT=587+ MAIL_USERNAME=postal+ MAIL_PASSWORD=ps_sua_chave
Configuración de SMTP en ambos lados
SMTP de SESSMTP de Postal
Servidoremail-smtp.<região>.amazonaws.comsmtp.postal.so
Puertos con STARTTLS25, 587 o 2587587 o 2587
Puertos con TLS directo465 o 2465465 (recomendado) o 2465
UsuarioEl usuario SMTP generado en SES, un par por regiónpostal
ContraseñaLa contraseña SMTP, que no es la clave secreta de AWSUna clave de API (ps_…). Basta una clave de solo envío
RemitenteUna identidad verificada en SESUn dominio verificado en Postal
  • TLS es obligatorio en ambos. En Postal, la autenticación (AUTH PLAIN o AUTH LOGIN) viene siempre después de TLS.
  • El SMTP de Postal no tiene etiquetas, programación ni plantillas: para eso, usa la API. Si tu sistema manda los encabezados X-SES-CONFIGURATION-SET o X-SES-MESSAGE-TAGS, quítalos, porque son de SES.
  • Los envíos por SMTP siguen las mismas reglas de la API (dominio verificado, cuotas y supresión) y aparecen en Correos y Registros. Cada mensaje aceptado puede tener hasta 40 MB y 50 destinatarios. Consulta la guía de SMTP.
5

Cambia SNS por los webhooks

En SES, el camino de los eventos es tuyo: configuration set, destino de evento, tema de SNS y una suscripción que tu código debe recibir. En Postal registras una URL HTTPS en Webhooks y eliges los eventos. Cada entrega se firma con el signing_secret del endpoint y se repite si falla.

webhook.js
- const message = JSON.parse(body.Message)- if (message.eventType === 'Bounce') {-   const kind = message.bounce.bounceType-   const id = message.mail.messageId- }+ const event = resend.webhooks.verify({ payload: rawBody, headers, webhookSecret })+ if (event.type === 'email.bounced') {+   const kind = event.data.bounce.type+   const id = event.data.email_id+ }
Eventos de SES y webhooks de Postal
Evento en SES (eventType)Evento en PostalObservación
Sendemail.sentPostal entregó el correo al proveedor de envío.
Deliveryemail.deliveredEl servidor del destinatario aceptó el mensaje.
DeliveryDelayemail.delivery_delayedLos reintentos ocurren solos.
Reboteemail.bounceddata.bounce trae type (Permanent, Transient o Undetermined), subType y diagnosticCode. Un rebote permanente pone la dirección en la supresión.
Complaintemail.complainedLa dirección entra en la lista de supresión.
Open, Clickemail.opened, email.clickedActiva open_tracking y click_tracking en el dominio.
Rendering FailureNo existeUna variable de plantilla sin valor devuelve 422 al momento del envío.
Subscription (listas de contactos de SES)contact.updatedCorresponde a la audiencia y las campañas de Postal.
  • El identificador que guardas pasa a ser el id devuelto por POST /emails (data.email_id en el webhook), y no el MessageId de SES.
  • Las etiquetas vuelven en data.tags como objeto, por ejemplo {"category": "shipping"}.
  • Postal tiene además eventos que SES no tiene, como email.scheduled, email.suppressed, email.received y domain.updated.
  • Cualquier respuesta 2xx confirma la entrega. Quita el tema de SNS solo después de pasar todo el tráfico, porque los correos electrónicos que aún salen por SES siguen generando eventos allí. Consulta Webhooks.
6

Lleva la lista de supresión de SES

Quien ya tuvo un rebote permanente o se quejó en SES no debe recibir de nuevo. Exporta la lista de supresión de tu cuenta e impórtala en Postal antes del primer envío y antes de importar contactos, porque una dirección suprimida nunca se convierte en contacto.

exportar de SES
aws sesv2 list-suppressed-destinations --region us-east-1 > supressoes-ses.json
# se a resposta trouxer "NextToken", repita com --next-token "<valor>"

jq -r '.SuppressedDestinationSummaries[].EmailAddress' supressoes-ses.json \
  | tr 'A-Z' 'a-z' | sort -u > emails.txt
importar en Postal
import { readFileSync } from 'node:fs'

const emails = readFileSync('emails.txt', 'utf8').split('\n').filter(Boolean)
const headers = {
  Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
  'Content-Type': 'application/json',
}

for (let i = 0; i < emails.length; i += 100) {
  const res = await fetch('https://api.postal.so/suppressions/batch/add', {
    method: 'POST',
    headers,
    body: JSON.stringify({ emails: emails.slice(i, i + 100) }),
  })
  if (!res.ok) throw new Error(await res.text())
  await new Promise((resolve) => setTimeout(resolve, 250)) // respeita o limite do plano
}
201Cada lote acepta hasta 100 direcciones
  • La lista de SES vale para la cuenta y para la región. Expórtala una vez por cada región en la que enviabas. En la consola, está en Configuration > Suppression list.
  • SES guarda la dirección exactamente como entró, con mayúsculas y minúsculas. Postal compara sin distinguir, así que el comando de arriba pasa todo a minúsculas y quita los repetidos.
  • En Postal, las direcciones entran con el origen manual: la diferencia entre BOUNCE y COMPLAINT de SES no se guarda.
  • Necesita una clave de acceso total. Para pocas direcciones, el panel acepta una por vez en Supresiones. Consulta la referencia de supresiones.
7

Revisa las cuotas y pasa el tráfico

Pasa un flujo a la vez. Empieza por las direcciones de prueba y por ti mismo, sigue en Correos y Registros y solo entonces pasa el resto. Mantén SES activo hasta que lleguen los eventos de los últimos correos electrónicos antiguos.

Dominio verificadoPrueba en [email protected]Un flujo por PostalTodo el tráficoApagar SES
Cuotas y límites
En SESEn Postal
Tasa de envíoEl límite de envío de tu cuenta, por regiónSolicitudes por segundo, por equipo: Gratis 5, Profesional 10, Escala 20, Empresarial 50. En el lote, 100 correos electrónicos cuentan como una solicitud
Cuota de envíoLa de tu cuenta, por regiónPor plan. Gratis: 100 por día y 3.000 por mes. Profesional: 50.000 por mes. Escala: 100.000 por mes. Empresarial: a medida. El límite por día también sigue la reputación de la cuenta: las cuentas nuevas empiezan con 500
SandboxHasta pedir acceso de producción: 200 mensajes por 24 horas, 1 por segundo, solo a direcciones verificadasEn AWS pides salir del sandbox; aquí no. El límite es la cuota del plan
ReputaciónDe tu cuentaDel equipo, de 0 a 100 puntos, empezando en 0. El envío se pausa cuando los rebotes permanentes superan el límite del nivel (del 3% al 5%) o las quejas el 0,3%. Antes, propietarios y administradores reciben un aviso
  • Las direcciones de prueba (delivered@, bounced@, complained@, suppressed@ y [email protected]) no usan la cuota ni pesan en la reputación. Dependen del plan.
  • Consulta los valores actuales en Precios y en Límites.

Antes de cambiar la clave

  • El dominio está verified en Postal y DMARC está en orden.
  • La clave de API está creada (solo envío y restringida al dominio, en los sistemas que solo envían).
  • Un correo electrónico de prueba llegó y los encabezados muestran DKIM y SPF de tu dominio.
  • El webhook está registrado y tu código verifica la firma.
  • La lista de supresión de SES, de todas las regiones, ya se importó.
  • Los encabezados X-SES-* y los temas de SNS que ya no sirven fueron identificados.
  • La cuota del plan y el límite de solicitudes cubren tu volumen diario.
  • Los propietarios y administradores del equipo saben qué hacer si el envío se pausa por reputación.

Preguntas frecuentes

¿Necesito mantener mi cuenta de AWS?

Para enviar por Postal, no: usa su propia cuenta en SES. Mantén la tuya mientras algún sistema aún envíe por allí y hasta que lleguen los eventos de los últimos correos electrónicos. Después, si quieres, borra las identidades y los registros de DNS de SES que ya no uses.

Mi dominio ya está verificado en SES. ¿Puedo verificarlo también en Postal?

Sí. El DKIM de Postal usa el selector postal y el Return-Path queda en un subdominio propio, así que los registros no chocan con los de SES, y el SPF del dominio principal no cambia. La excepción es un Return-Path tuyo que ya se llame postal: usa otro nombre con custom_return_path.

¿Qué pasa con la reputación de envío?

Pasa a medirse por equipo, con la reputación de la cuenta: una puntuación que empieza en 0 y sube con cada día de envíos sin problemas. Las cuentas nuevas empiezan con un tope de 500 correos por día, que crece con el nivel. Postal pausa el envío si los rebotes permanentes superan el límite del nivel (del 3% al 5%) o las quejas el 0,3%. Importar la lista de supresión de SES ayuda a no repetir rebotes ya conocidos.

¿Puedo usar IP dedicadas?

La documentación de Postal no trata este tema. Si tu cuenta de SES usa IP dedicadas, habla con nosotros por el formulario de contacto antes de migrar.

¿Quieres probar Postal?

Crea tu cuenta y empieza con el plan Gratis.