Guía de migración
Migrar de Amazon SES a Mail.Land
Al dejar SES, una clave de API y unos webhooks firmados sustituyen a las credenciales de AWS, los conjuntos de configuración y los destinos de eventos. Esta guía hace corresponder cada campo habitual de SendEmail e indica lo que requiere cambios en el código.
# Before (Amazon SES)
SMTP_HOST=email-smtp.eu-central-1.amazonaws.com # your Region's endpoint
SMTP_PORT=587 # STARTTLS (465 for TLS wrapper)
SMTP_USER=<SES SMTP user name for that Region>
SMTP_PASS=<SES SMTP password for that Region>
# After (Mail.Land)
SMTP_HOST=smtp.mail.land
SMTP_PORT=587 # STARTTLS; 465 is not offered
SMTP_USER=apikey # any value; Mail.Land ignores it
SMTP_PASS=ml_pet_... # a Mail.Land key with SMTP enabledConceptos de Amazon SES en Mail.Land
| Amazon SES | Mail.Land |
|---|---|
| Usuario de IAM y firma de solicitudes SigV4 | Clave de API (credencial) en la cabecera X-API-Key |
| Credenciales SMTP por región de AWS | La misma clave de API, usada como contraseña SMTP |
| Identidad verificada (dominio) y MAIL FROM personalizado | Dominio verificado (SPF, DKIM, DMARC y return path) |
| Conjuntos de configuración y destinos de eventos (SNS, EventBridge, Firehose) | Webhooks firmados con HMAC-SHA256, enviados directamente a su endpoint |
| Lista de supresión a nivel de cuenta | Supresiones con un tipo y un ámbito |
| Plantillas de correo (Handlebars) | Plantillas con marcadores {{name}} |
| Listas de contactos y temas (topics) | Listas de correo, campañas y gestión de bajas (Pro y Max) |
| Sandbox | Claves de pruebas (ml_set_, ml_sem_): con sandboxBehavior en LogOnly, las solicitudes se aceptan y se registran, pero nunca se entregan |
Cree las claves de API adecuadas
No hay que escribir políticas de IAM. El prefijo de una clave de Mail.Land indica su modo y su flujo; cree una clave por aplicación y por flujo, y limítela a los dominios y direcciones IP que la usan.
| Prefijo | Para qué sirve |
|---|---|
ml_pet_ | Producción, transaccional: recibos, restablecimiento de contraseñas, alertas. Hasta 5 destinatarios por solicitud. |
ml_pem_ | Producción, marketing: boletines y envíos masivos con send-batch, hasta 10.000 destinatarios por llamada. |
ml_set_ | Pruebas, transaccional: con sandboxBehavior en LogOnly (el valor por defecto), las solicitudes se aceptan y se registran, pero nunca se entregan. Úsela para sus pruebas de integración. |
Cada clave puede limitarse a la API, a SMTP o a ambos, a dominios seleccionados y a direcciones IP conocidas. La clave se muestra una sola vez y Mail.Land solo guarda un hash de ella.
Cambie SMTP: modifique el host y las credenciales
Las credenciales SMTP de SES se crean mediante IAM y son distintas en cada región de AWS. Mail.Land usa su clave de API como contraseña e ignora el nombre de usuario.
| Ajuste | Amazon SES | Mail.Land |
|---|---|---|
| Host | email-smtp.<region>.amazonaws.com | smtp.mail.land |
| Puerto | 25, 587 o 2587 con STARTTLS, o 465 y 2465 con TLS wrapper | 587 con STARTTLS |
| Nombre de usuario | Usuario SMTP de esa región | Cualquier valor, por ejemplo apikey |
| Contraseña | Contraseña SMTP de esa región | Una clave de API de Mail.Land con SMTP habilitado (ml_pet_ para correo transaccional) |
Mail.Land solo acepta el inicio de sesión después de STARTTLS y no ofrece los puertos 465 ni 2465. Si su aplicación usa TLS wrapper, cámbiela al 587 con STARTTLS. Mail.Land no tiene en cuenta las cabeceras X-SES-*, como X-SES-CONFIGURATION-SET, así que puede eliminarlas. Los mensajes pueden ocupar hasta 15 MiB.
Cambie la llamada a la API
Las solicitudes a SES se firman con AWS Signature Version 4, normalmente mediante un SDK de AWS. Mail.Land solo necesita la cabecera X-API-Key y un cuerpo JSON más plano. Este es el mismo mensaje en ambas, y un envío con plantilla.
aws sesv2 send-email --region eu-central-1 \
--from-email-address "[email protected]" \
--destination '{"ToAddresses":["[email protected]"]}' \
--reply-to-addresses "[email protected]" \
--email-tags Name=type,Value=order-shipped \
--content '{
"Simple": {
"Subject": { "Data": "Order 12345 has shipped" },
"Body": {
"Text": { "Data": "Your order is on its way." },
"Html": { "Data": "<p>Your order is on its way.</p>" }
}
}
}'curl -X POST https://api.mail.land/v1/transactional/send \
-H "X-API-Key: $MAILLAND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": { "email": "[email protected]", "name": "Your Shop" },
"to": [{
"email": "[email protected]", "name": "Jane",
"variables": { "orderNumber": "12345" }
}],
"replyTo": "[email protected]",
"subject": "Order {{orderNumber}} has shipped",
"textContent": "Your order {{orderNumber}} is on its way.",
"htmlContent": "<p>Your order {{orderNumber}} is on its way.</p>",
"tags": ["order-shipped"]
}'
# MAILLAND_API_KEY=ml_pet_... (production, transactional)Correspondencia de campos de la llamada de envío
De SES API v2 SendEmail (POST /v2/email/outbound-emails) a POST /v1/transactional/send.
| Amazon SES | Mail.Land | Nota |
|---|---|---|
AWS Signature Version 4 | X-API-Key: <key> | Sin firma de solicitudes; envíe la clave por HTTPS. |
FromEmailAddress | from.email, from.name | La dirección debe pertenecer a un dominio verificado. |
Destination.ToAddresses | to[].email, to[].name | Hasta 5 destinatarios por solicitud con una clave transaccional; cada uno recibe una copia separada. |
Destination.CcAddresses, BccAddresses | Ninguno | No se admite. Envíe un mensaje separado a cada destinatario. |
ReplyToAddresses | replyTo | Una sola cadena de dirección en lugar de una lista. Si usaba varias, conserve una. |
Content.Simple.Subject.Data | subject | Obligatorio salvo que use una plantilla. |
Content.Simple.Body.Html.Data | htmlContent | |
Content.Simple.Body.Text.Data | textContent | |
Content.Simple.Headers [{ Name, Value }] | customHeaders | Un objeto con nombres y valores de cabecera en lugar de un array. |
Content.Simple.Attachments[].FileName, ContentType, RawContent, ContentId, ContentDisposition | attachments[].fileName, contentType, content, contentId, inline | Contenido Base64. Indique inline: true para una imagen incrustada. Hasta 10 adjuntos y 10 MiB en total. |
Content.Raw.Data (MIME) | No existe en la API | Envíe los mensajes MIME ya preparados por el relé SMTP. |
Content.Template.TemplateName, TemplateArn | templateId | Vuelva a crear antes la plantilla en Mail.Land. |
Content.Template.TemplateData | variables, to[].variables | Un objeto JSON en lugar de una cadena JSON. |
EmailTags [{ Name, Value }] | tags | Un array de cadenas en lugar de pares de nombre y valor. |
ConfigurationSetName | Ninguno | Los webhooks y el seguimiento se configuran en su cuenta de Mail.Land y en cada dominio. |
ConfigurationOverrides.Tracking | tracking.opens, tracking.clicks | La opción de seguimiento de aperturas del propio dominio tiene prioridad. |
ListManagementOptions | No existe en la llamada de envío | Las bajas de marketing se gestionan con las listas y campañas de Mail.Land. |
Sin equivalente | scheduledAt | Programe un mensaje con hasta 7 días de antelación. |
Sin equivalente | Cabecera X-Idempotency-Key | Dentro del periodo de conservación, un reintento con la misma clave devuelve la respuesta original en lugar de volver a enviar. |
SES responde 200 con un MessageId. Mail.Land responde 202 Accepted con un jobId, un ID de mensaje por cada destinatario aceptado y las listas de destinatarios aceptados y rechazados.
Añada su dominio y los registros DNS
Añada el dominio en Mail.Land y publique los registros que muestra el panel. SPF, DKIM y DMARC deben verificarse antes de poder enviar. Puede hacerlo mientras SES sigue enviando.
| Registro | Nombre | Valor | Nota |
|---|---|---|---|
| SPF (TXT) | yourdomain.com | include:spf.mlnd.net | Añada el include a su registro SPF actual. Un dominio solo debe tener un registro SPF. |
| DKIM (TXT) | mlnd._domainkey.yourdomain.com | v=DKIM1; k=rsa; p=... | El selector es mlnd, así que el registro convive con los registros DKIM que usa SES. |
| DMARC (TXT) | _dmarc.yourdomain.com | v=DMARC1; p=... | Obligatorio. Mantenga un único registro DMARC; basta con uno existente que tenga una política. |
| Return path (CNAME) | bounce.yourdomain.com | bounce.mlnd.net | Configúrelo como DNS only, sin proxy. Si su dominio MAIL FROM personalizado de SES ya usa ese nombre, consérvelo hasta que SES deje de enviar. |
Mantenga los registros DNS de SES hasta terminar el traslado y elimínelos solo cuando haya salido su último mensaje.
Importe primero su lista de supresión
La lista de supresión de SES a nivel de cuenta se aplica por región de AWS. Expórtela de cada región desde la que envía con ListSuppressedDestinations (aws sesv2 list-suppressed-destinations) e impórtela en Mail.Land con el tipo y el ámbito correspondientes, en el panel o con POST /v1/transactional/suppressions/import.
| Motivo u origen en SES | Tipo en Mail.Land | Ámbito |
|---|---|---|
| BOUNCE | HardBounce | Global |
| COMPLAINT | Complaint | Global |
| Bajas de temas de listas de contactos | Unsubscribe | Marketing; o List, que solo se aplica a las campañas enviadas a la lista de correo correspondiente de Mail.Land |
SES solo añade a la lista los rebotes duros, y las denuncias de spam de Gmail no llegan a ella, así que importe también las supresiones que guarden sus propios sistemas. Importe antes de su primer envío a través de Mail.Land, para que quienes se dieron de baja sigan suprimidos desde el principio.
Dirija sus webhooks a Mail.Land
Sustituya el conjunto de configuración y su destino de eventos por un webhook de Mail.Land: añada su endpoint HTTPS, elija los eventos y verifique la cabecera X-MLND-Signature con el secreto de ese webhook. No hay ninguna suscripción de SNS que confirmar.
| Evento de SES | Evento de Mail.Land | Nota |
|---|---|---|
Send | Ninguno por ahora | message.sent aún no está disponible; la respuesta 202 confirma la aceptación. |
Entrega (Delivery) | message.delivered | |
DeliveryDelay | message.deferred | |
Rebote (Bounce) | message.bounced | |
Complaint | message.complained | |
Subscription | message.unsubscribed | Se envía cuando el destinatario se da de baja por sí mismo, no por cambios que usted haga mediante la API. |
Reject | Ninguno | |
RenderingFailure | Ninguno | Si falta un valor de la plantilla, la solicitud se rechaza al llamar a la API, con 422 TEMPLATE_VARIABLE_MISSING. |
Apertura, clic (Open, Click) | Aún no disponible | Los eventos de apertura y clic están catalogados, pero hoy no se envían. |
Elimine duplicados por event_id, ya que una entrega reintentada lleva el mismo ID de evento. Un estado puede corregirse más tarde, así que siga procesando eventos después de uno final y compare status_version.
Vuelva a crear sus plantillas
Cree cada plantilla en el panel de Mail.Land o con la API de plantillas y envíela con templateId y variables. Cada marcador necesita un valor; si falta, el envío se rechaza con 422 y los nombres que faltan.
| Amazon SES | Mail.Land |
|---|---|
{{firstName}} | {{firstName}} |
{{contact.firstName}} (anidado) | {{firstName}} |
{{#each}}, {{#if}} ... {{else}} | Ninguno |
Parciales en línea ({{> name}}) | Ninguno |
Los marcadores de Mail.Land son simples: sin valores anidados, condiciones, bucles ni parciales. Pase valores planos y traslade la lógica a su aplicación, o mantenga una plantilla por variante.
Cambie paso a paso
- Añada y verifique su dominio de envío en Mail.Land, agregando include:spf.mlnd.net a su registro SPF actual.
- Exporte la lista de supresión de cada región de AWS que use e impórtela.
- Cree claves de Mail.Land por aplicación y por flujo, limitadas a sus dominios y direcciones IP.
- Vuelva a crear sus plantillas y sustituya cada destino de eventos por un webhook.
- Cree una clave de pruebas con sandboxBehavior en LogOnly y ejecute sus pruebas de integración contra Mail.Land sin entregar correo.
- Envíe mensajes reales a direcciones que usted controle y revíselos en el registro de correo.
- Traslade una aplicación o una pequeña parte del tráfico y vigile la entrega, los rebotes y las quejas.
- Mientras funcionen ambos proveedores, mantenga sincronizadas las bajas en los dos sentidos: copie las nuevas bajas, quejas y rebotes de SES a Mail.Land y de Mail.Land a SES, y haga una sincronización final antes de trasladar el tráfico restante.
- Revise el calentamiento de su dominio: en Free y Pro, un dominio nuevo tiene un límite diario que sube por etapas, y los envíos que lo superan se rechazan. Planifique el traslado dentro de esos límites o consúltenos un calendario a medida. Max no pasa por calentamiento.
- Después traslade el resto y mantenga SES activo hasta que hayan salido sus últimos mensajes.
Fuentes
Páginas públicas de AWS utilizadas en esta guía.
- [1]Amazon SES API v2: SendEmailhttps://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.htmlcomprobado el 4 de noviembre de 2026
- [2]Amazon SES: conexión a un endpoint SMTPhttps://docs.aws.amazon.com/ses/latest/dg/smtp-connect.htmlcomprobado el 4 de noviembre de 2026
- [3]Amazon SES: obtención de credenciales SMTPhttps://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.htmlcomprobado el 4 de noviembre de 2026
- [4]Amazon SES: personalización avanzada del correohttps://docs.aws.amazon.com/ses/latest/dg/send-personalized-email-advanced.htmlcomprobado el 4 de noviembre de 2026
- [5]Amazon SES: publicación de eventoshttps://docs.aws.amazon.com/ses/latest/dg/monitor-using-event-publishing.htmlcomprobado el 4 de noviembre de 2026
- [6]Amazon SES: lista de supresión a nivel de cuentahttps://docs.aws.amazon.com/ses/latest/dg/sending-email-suppression-list.htmlcomprobado el 4 de noviembre de 2026
Preguntas frecuentes
¿Puedo seguir enviando a través de SES mientras hago pruebas?
Sí. Verificar un dominio en Mail.Land no impide que SES siga enviando en su nombre, así que puede usar ambos y trasladar el tráfico gradualmente.
¿Sigo necesitando un SDK de AWS?
No. Cualquier cliente HTTP puede llamar a la API de Mail.Land con la cabecera X-API-Key, y cualquier biblioteca SMTP funciona con el relé.
¿Cómo envío el correo masivo que enviaba con SendBulkEmail?
Use POST /v1/transactional/send-batch con una clave de marketing (ml_pem_). Admite hasta 10.000 destinatarios, cada uno con sus propias variables.
¿Dónde funciona Mail.Land?
Mail.Land no tiene regiones que elegir. La copia principal de sus datos está en Alemania; los proveedores fuera de la UE figuran en nuestra página sobre el RGPD.
¿Listo para dejar Amazon SES?
Cree una cuenta gratuita y envíe hoy mismo su primera prueba. Si desea ayuda, cuéntenos cómo es su configuración.