Guide de migration
Migrer d’Amazon SES vers Mail.Land
Quitter SES, c’est remplacer les identifiants AWS, les ensembles de configuration et les destinations d’événements par une clé API et des webhooks signés. Ce guide fait correspondre chaque champ courant de SendEmail et liste ce qui demande une modification du code.
# 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 enabledLes notions d’Amazon SES dans Mail.Land
| Amazon SES | Mail.Land |
|---|---|
| Utilisateur IAM et signature des requêtes SigV4 | Clé API (identifiant) dans l’en-tête X-API-Key |
| Identifiants SMTP par région AWS | La même clé API, utilisée comme mot de passe SMTP |
| Identité vérifiée (domaine) et MAIL FROM personnalisé | Domaine vérifié (SPF, DKIM, DMARC et chemin de retour) |
| Ensembles de configuration et destinations d’événements (SNS, EventBridge, Firehose) | Webhooks signés en HMAC-SHA256, envoyés directement à votre endpoint |
| Liste de suppression au niveau du compte | Suppressions avec un type et une portée |
| Modèles d’e-mail (Handlebars) | Modèles avec variables {{name}} |
| Listes de contacts et sujets (topics) | Listes de diffusion, campagnes et gestion des désabonnements (Pro et Max) |
| Bac à sable (Sandbox) | Clés de test (ml_set_, ml_sem_) : avec sandboxBehavior sur LogOnly, les requêtes sont acceptées et journalisées mais jamais livrées |
Créer les bonnes clés API
Aucune politique IAM à écrire. Le préfixe d’une clé Mail.Land indique son mode et son flux ; créez une clé par application et par flux, et limitez-la aux domaines et adresses IP qui l’utilisent.
| Préfixe | Usage |
|---|---|
ml_pet_ | Production, transactionnel : reçus, réinitialisations de mot de passe, alertes. Jusqu’à 5 destinataires par requête. |
ml_pem_ | Production, marketing : newsletters et envois en masse avec send-batch, jusqu’à 10 000 destinataires par appel. |
ml_set_ | Test, transactionnel : avec sandboxBehavior sur LogOnly (valeur par défaut), les requêtes sont acceptées et journalisées mais jamais livrées. Utilisez-la pour vos tests d’intégration. |
Chaque clé peut être limitée à l’API, au SMTP ou aux deux, à des domaines choisis et à des adresses IP connues. Une clé n’est affichée qu’une fois, et Mail.Land n’en conserve qu’une empreinte (hash).
Basculer le SMTP : changer l’hôte et les identifiants
Les identifiants SMTP de SES sont créés via IAM et diffèrent dans chaque région AWS. Mail.Land utilise votre clé API comme mot de passe et ignore le nom d’utilisateur.
| Paramètre | Amazon SES | Mail.Land |
|---|---|---|
| Hôte | email-smtp.<region>.amazonaws.com | smtp.mail.land |
| Port | 25, 587 ou 2587 avec STARTTLS, ou 465 et 2465 avec TLS wrapper | 587 avec STARTTLS |
| Nom d’utilisateur | Nom d’utilisateur SMTP de cette région | N’importe quelle valeur, par exemple apikey |
| Mot de passe | Mot de passe SMTP de cette région | Une clé API Mail.Land avec SMTP activé (ml_pet_ pour l’e-mail transactionnel) |
Mail.Land n’accepte l’authentification qu’après STARTTLS, et les ports 465 et 2465 ne sont pas proposés. Si votre application utilise le TLS wrapper, passez au 587 avec STARTTLS. Mail.Land ne tient pas compte des en-têtes X-SES-*, comme X-SES-CONFIGURATION-SET : vous pouvez donc les supprimer. Les messages peuvent atteindre 15 Mio.
Basculer l’appel d’API
Les requêtes SES sont signées avec AWS Signature Version 4, généralement via un SDK AWS. Mail.Land n’a besoin que de l’en-tête X-API-Key et d’un corps JSON plus plat. Voici le même message dans les deux, ainsi qu’un envoi avec modèle.
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)Correspondance des champs de l’appel d’envoi
De SES API v2 SendEmail (POST /v2/email/outbound-emails) à POST /v1/transactional/send.
| Amazon SES | Mail.Land | Remarque |
|---|---|---|
AWS Signature Version 4 | X-API-Key: <key> | Pas de signature des requêtes ; envoyez la clé via HTTPS. |
FromEmailAddress | from.email, from.name | L’adresse doit appartenir à un domaine vérifié. |
Destination.ToAddresses | to[].email, to[].name | Jusqu’à 5 destinataires par requête avec une clé transactionnelle ; chacun reçoit une copie distincte. |
Destination.CcAddresses, BccAddresses | Aucun | Non pris en charge. Envoyez un message distinct à chaque destinataire. |
ReplyToAddresses | replyTo | Une seule chaîne d’adresse au lieu d’une liste. Si vous en utilisiez plusieurs, gardez-en une. |
Content.Simple.Subject.Data | subject | Obligatoire, sauf si vous utilisez un modèle. |
Content.Simple.Body.Html.Data | htmlContent | |
Content.Simple.Body.Text.Data | textContent | |
Content.Simple.Headers [{ Name, Value }] | customHeaders | Un objet de noms et de valeurs d’en-têtes au lieu d’un tableau. |
Content.Simple.Attachments[].FileName, ContentType, RawContent, ContentId, ContentDisposition | attachments[].fileName, contentType, content, contentId, inline | Contenu Base64. Indiquez inline: true pour une image intégrée. Jusqu’à 10 pièces jointes et 10 Mio au total. |
Content.Raw.Data (MIME) | Absent de l’API | Envoyez plutôt les messages MIME déjà prêts via le relais SMTP. |
Content.Template.TemplateName, TemplateArn | templateId | Recréez d’abord le modèle dans Mail.Land. |
Content.Template.TemplateData | variables, to[].variables | Un objet JSON au lieu d’une chaîne JSON. |
EmailTags [{ Name, Value }] | tags | Un tableau de chaînes au lieu de paires nom-valeur. |
ConfigurationSetName | Aucun | Les webhooks et le suivi se règlent dans votre compte Mail.Land et sur chaque domaine. |
ConfigurationOverrides.Tracking | tracking.opens, tracking.clicks | Le choix propre au domaine pour le suivi des ouvertures est prioritaire. |
ListManagementOptions | Absent de l’appel d’envoi | Les désabonnements marketing sont gérés par les listes et les campagnes de Mail.Land. |
Aucun équivalent | scheduledAt | Programmez un message jusqu’à 7 jours à l’avance. |
Aucun équivalent | En-tête X-Idempotency-Key | Pendant la durée de conservation, une nouvelle tentative avec la même clé renvoie la réponse d’origine au lieu d’envoyer à nouveau. |
SES répond 200 avec un MessageId. Mail.Land répond 202 Accepted avec un jobId, un identifiant de message par destinataire accepté, et les listes des destinataires acceptés et refusés.
Ajouter votre domaine et les enregistrements DNS
Ajoutez le domaine dans Mail.Land et publiez les enregistrements affichés par le tableau de bord. SPF, DKIM et DMARC doivent être vérifiés avant de pouvoir envoyer. Vous pouvez le faire pendant que SES envoie encore.
| Enregistrement | Nom | Valeur | Remarque |
|---|---|---|---|
| SPF (TXT) | yourdomain.com | include:spf.mlnd.net | Ajoutez l’include à votre enregistrement SPF existant. Un domaine ne doit avoir qu’un seul enregistrement SPF. |
| DKIM (TXT) | mlnd._domainkey.yourdomain.com | v=DKIM1; k=rsa; p=... | Le sélecteur est mlnd : l’enregistrement coexiste donc avec les enregistrements DKIM utilisés par SES. |
| DMARC (TXT) | _dmarc.yourdomain.com | v=DMARC1; p=... | Obligatoire. Gardez un seul enregistrement DMARC ; un enregistrement existant avec une politique suffit. |
| Chemin de retour (CNAME) | bounce.yourdomain.com | bounce.mlnd.net | Réglez-le en DNS only, sans proxy. Si votre domaine MAIL FROM personnalisé chez SES utilise déjà ce nom, gardez-le jusqu’à ce que SES cesse d’envoyer. |
Gardez les enregistrements DNS de SES jusqu’à la fin de la migration, et supprimez-les seulement après le départ de son dernier message.
Importer d’abord votre liste de suppression
La liste de suppression au niveau du compte SES s’applique par région AWS. Exportez-la de chaque région depuis laquelle vous envoyez avec ListSuppressedDestinations (aws sesv2 list-suppressed-destinations), puis importez-la dans Mail.Land avec le type et la portée correspondants, dans le tableau de bord ou avec POST /v1/transactional/suppressions/import.
| Motif ou source chez SES | Type Mail.Land | Portée |
|---|---|---|
| BOUNCE | HardBounce | Global |
| COMPLAINT | Complaint | Global |
| Désabonnements des sujets de listes de contacts | Unsubscribe | Marketing ; ou List, qui ne s’applique qu’aux campagnes envoyées à la liste de diffusion Mail.Land correspondante |
SES n’ajoute à la liste que les rebonds définitifs, et les signalements de spam de Gmail ne l’atteignent pas : importez donc aussi les suppressions que gèrent vos propres systèmes. Importez avant votre premier envoi via Mail.Land, pour que les personnes désinscrites restent bloquées dès le départ.
Diriger vos webhooks vers Mail.Land
Remplacez l’ensemble de configuration et sa destination d’événements par un webhook Mail.Land : ajoutez votre endpoint HTTPS, choisissez les événements et vérifiez l’en-tête X-MLND-Signature avec le secret de ce webhook. Il n’y a pas d’abonnement SNS à confirmer.
| Événement SES | Événement Mail.Land | Remarque |
|---|---|---|
Send | Aucun pour l’instant | message.sent n’est pas encore disponible ; la réponse 202 confirme l’acceptation. |
Livraison (Delivery) | message.delivered | |
DeliveryDelay | message.deferred | |
Rebond (Bounce) | message.bounced | |
Complaint | message.complained | |
Subscription | message.unsubscribed | Envoyé lorsque le destinataire se désabonne lui-même, pas pour les changements que vous faites via l’API. |
Reject | Aucun | |
RenderingFailure | Aucun | Une valeur de modèle manquante est refusée dès l’appel d’API, avec 422 TEMPLATE_VARIABLE_MISSING. |
Ouverture, clic (Open, Click) | Pas encore disponible | Les événements d’ouverture et de clic figurent au catalogue mais ne sont pas envoyés aujourd’hui. |
Dédupliquez sur event_id, car une livraison relancée porte le même identifiant d’événement. Un statut peut être corrigé plus tard : continuez à traiter les événements après un événement final et comparez status_version.
Recréer vos modèles
Créez chaque modèle dans le tableau de bord Mail.Land ou avec l’API des modèles, puis envoyez-le avec templateId et variables. Chaque variable doit avoir une valeur, sinon l’envoi est refusé avec un code 422 et les noms manquants.
| Amazon SES | Mail.Land |
|---|---|
{{firstName}} | {{firstName}} |
{{contact.firstName}} (imbriqué) | {{firstName}} |
{{#each}}, {{#if}} ... {{else}} | Aucun |
Partials en ligne ({{> name}}) | Aucun |
Les variables Mail.Land sont simples : ni valeurs imbriquées, ni conditions, ni boucles, ni partials. Passez des valeurs plates et déplacez la logique dans votre application, ou gardez un modèle par variante.
Basculer étape par étape
- Ajoutez et vérifiez votre domaine d’envoi dans Mail.Land, en ajoutant include:spf.mlnd.net à votre enregistrement SPF existant.
- Exportez la liste de suppression de chaque région AWS que vous utilisez et importez-la.
- Créez des clés Mail.Land par application et par flux, limitées à vos domaines et adresses IP.
- Recréez vos modèles, et remplacez chaque destination d’événements par un webhook.
- Créez une clé de test avec sandboxBehavior sur LogOnly, et lancez vos tests d’intégration sur Mail.Land sans livrer d’e-mail.
- Envoyez de vrais messages à des adresses que vous contrôlez et vérifiez-les dans le journal des e-mails.
- Déplacez une application ou une petite part du trafic, puis surveillez la livraison, les rebonds et les plaintes.
- Tant que les deux fournisseurs fonctionnent, synchronisez les désinscriptions dans les deux sens : copiez les nouveaux désabonnements, plaintes et rebonds de SES vers Mail.Land et de Mail.Land vers SES, et faites une synchronisation finale avant de déplacer le trafic restant.
- Vérifiez le préchauffage de votre domaine : en Free et Pro, un nouveau domaine a une limite quotidienne qui augmente par paliers, et les envois au-delà sont refusés. Planifiez la migration dans ces limites, ou demandez-nous un calendrier sur mesure. Max n’a pas de préchauffage.
- Déplacez ensuite le reste, et gardez SES actif jusqu’au départ de ses derniers messages.
Sources
Pages publiques d’AWS utilisées pour ce guide.
- [1]Amazon SES API v2 : SendEmailhttps://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.htmlvérifié le 4 novembre 2026
- [2]Amazon SES : se connecter à un endpoint SMTPhttps://docs.aws.amazon.com/ses/latest/dg/smtp-connect.htmlvérifié le 4 novembre 2026
- [3]Amazon SES : obtenir des identifiants SMTPhttps://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.htmlvérifié le 4 novembre 2026
- [4]Amazon SES : personnalisation avancée des e-mailshttps://docs.aws.amazon.com/ses/latest/dg/send-personalized-email-advanced.htmlvérifié le 4 novembre 2026
- [5]Amazon SES : publication d’événementshttps://docs.aws.amazon.com/ses/latest/dg/monitor-using-event-publishing.htmlvérifié le 4 novembre 2026
- [6]Amazon SES : liste de suppression au niveau du comptehttps://docs.aws.amazon.com/ses/latest/dg/sending-email-suppression-list.htmlvérifié le 4 novembre 2026
Questions fréquentes
Puis-je continuer à envoyer via SES pendant mes tests ?
Oui. Vérifier un domaine dans Mail.Land n’empêche pas SES d’envoyer pour lui : vous pouvez faire tourner les deux et déplacer le trafic progressivement.
Ai-je encore besoin d’un SDK AWS ?
Non. N’importe quel client HTTP peut appeler l’API Mail.Land avec l’en-tête X-API-Key, et toute bibliothèque SMTP fonctionne avec le relais.
Comment envoyer l’e-mail en masse que j’envoyais avec SendBulkEmail ?
Utilisez POST /v1/transactional/send-batch avec une clé marketing (ml_pem_). Il accepte jusqu’à 10 000 destinataires, chacun avec ses propres variables.
Où fonctionne Mail.Land ?
Mail.Land n’a pas de région à choisir. La copie principale de vos données est en Allemagne ; les prestataires hors de l’UE sont listés sur notre page RGPD.
Prêt à quitter Amazon SES ?
Créez un compte gratuit et envoyez votre premier test dès aujourd’hui. Si vous souhaitez de l’aide, décrivez-nous votre configuration.