Webhooks et événements
Les résultats de livraison, directement dans votre app
Mail.Land envoie un événement signé à votre point de terminaison lorsqu'un message est livré, différé, renvoyé en rebond ou terminé en échec, lorsqu'un destinataire se plaint et lorsqu'un e-mail entrant arrive, avec un journal de chaque tentative.
import crypto from "node:crypto";
// header: X-MLND-Signature: t=1708171200,v1=<hex>
export function verify(rawBody, header, secret) {
if (typeof header !== "string" || header === "") return false;
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const age = Math.abs(Date.now() / 1000 - Number(parts.t));
if (!parts.t || !parts.v1 || age > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Événements auxquels vous pouvez vous abonner aujourd'hui
Huit types d'événements sont actifs. Abonnez-vous à tous ou seulement à ceux qui vous servent.
| Envoyé lorsque | |
|---|---|
| message.delivered | Le serveur de messagerie du destinataire a accepté le message |
| message.deferred | La livraison est retardée pour l'instant ; Mail.Land continue d'essayer |
| message.bounced | Le serveur du destinataire a refusé le message, avec le type de rebond et sa réponse |
| message.failed | Mail.Land a marqué le message en échec pour une raison interne ou de politique ; cet événement ne place pas le destinataire en liste de suppression |
| message.complained | Le destinataire a signalé le message comme spam via une boucle de rétroaction |
| message.outcome_unknown | Mail.Land ne sait pas encore si le message a atteint sa file de livraison ; un événement final suit si Mail.Land apprend le résultat plus tard |
| message.retried | Vous avez relancé un message en rebond ou en échec et il est de nouveau en file |
| inbound.received | Un e-mail est arrivé sur l'un de vos domaines et correspond à une route webhook |
D'autres types d'événements, comme message.sent, les ouvertures et les clics, figurent au catalogue pour plus tard et ne sont pas encore envoyés. Le point de terminaison du catalogue indique lesquels sont disponibles.
Signé, et envoyé seulement là où il doit aller
Chaque requête peut être vérifiée, et Mail.Land refuse les destinations qui pourraient être détournées.
HMAC-SHA256 avec horodatage
L'en-tête X-MLND-Signature contient un horodatage et la signature de cet horodatage suivi du corps brut. Vérifiez-la en temps constant et refusez les horodatages anciens pour bloquer les rejeux.
HTTPS sur le port 443 uniquement
Les adresses privées et de bouclage sont refusées. Les redirections sont suivies sur trois sauts au plus, et chaque saut est revérifié avant tout envoi.
Un secret par webhook
Le secret de signature s'affiche une seule fois à la création du webhook. S'il fuite, régénérez-le : l'ancien cesse aussitôt de fonctionner.
Quand votre point de terminaison est indisponible
Par défaut, une livraison échouée est retentée selon ce calendrier. Une réponse 2xx en moins de 15 secondes vaut succès.
| Attente avant la tentative | Temps depuis la première tentative | |
|---|---|---|
| Tentative 1 | Aucune | 0 |
| Tentative 2 | Immédiate | Environ 0 |
| Tentative 3 | 1 minute | Environ 1 minute |
| Tentative 4 | 5 minutes | Environ 6 minutes |
| Tentative 5 | 15 minutes | Environ 21 minutes |
| Tentative 6 | 1 heure | Environ 1 heure 21 minutes |
Les délais dépassés, les erreurs réseau et les réponses 408, 429, 500, 502, 503 et 504 sont retentés, et un en-tête Retry-After fixe l'attente suivante. Les autres réponses hors 2xx sont définitives. Vous pouvez relancer toute livraison échouée depuis le journal.
Conçu pour les événements qui arrivent en retard ou en double
La livraison est au moins une fois et pas toujours dans l'ordre. Chaque événement porte ce qu'il faut pour le gérer.
Versions de statut
Chaque événement de message porte une version de statut qui augmente à chaque changement. Si vous vous abonnez à tous les événements de message et n'appliquez un événement que si sa version dépasse celle enregistrée, votre statut reste juste quel que soit l'ordre d'arrivée. Avec moins d'événements, vérifiez le statut actuel via l'API.
Identifiants d'événement stables
L'identifiant d'événement est le même à chaque nouvelle tentative. Conservez les identifiants traités et ignorez les répétitions.
Charges versionnées
Chaque type d'événement a une version de schéma. Mail.Land se contente d'ajouter des champs et des en-têtes à une version existante : un récepteur qui ignore les champs inconnus continue de fonctionner.
Contrôle et visibilité
Gérez les webhooks dans le tableau de bord ou via l'API.
Filtrer par produit et par domaine
Choisissez les événements transactionnels, marketing ou entrants, des types d'événements précis, et tous les domaines ou seulement certains.
Tester avant de s'y fier
Envoyez un événement de test avec la vraie signature et le vrai transport. La réponse indique aussi si de vrais événements peuvent atteindre le point de terminaison avec son abonnement actuel.
Journal des livraisons
Consultez chaque tentative avec son statut, filtrez celles en échec et relancez une livraison à la main.
Pause automatique
Par défaut, après 10 tentatives échouées d'affilée, le webhook est mis en pause et vous recevez une notification dans le tableau de bord. Réactivez-le quand votre point de terminaison est rétabli.
Questions sur les webhooks
Existe-t-il un événement quand un message est accepté ou envoyé ?
Pas encore. message.sent figure au catalogue mais n'est pas envoyé aujourd'hui. La réponse de l'API à votre requête d'envoi contient les identifiants des messages, et le premier événement webhook reçu est le résultat de la livraison.
Puis-je recevoir les événements d'ouverture et de clic ?
Pas par webhook aujourd'hui. Les ouvertures et les clics, là où le suivi est activé, figurent dans vos journaux et votre analytique ; les événements correspondants sont au catalogue pour plus tard.
Et si un message livré rebondit plus tard ?
Cela arrive : un serveur destinataire peut refuser un message après l'avoir accepté. Mail.Land envoie alors un événement de rebond avec une version de statut plus élevée ; continuez donc à traiter les événements après un événement de livraison.
Que se passe-t-il si mon point de terminaison est indisponible une journée ?
Par défaut, chaque événement est tenté jusqu'à six fois sur environ 80 minutes, et le webhook est mis en pause après 10 tentatives échouées d'affilée. Pendant la pause, aucun nouvel événement n'est mis en file pour lui. Après l'avoir réactivé, relancez les livraisons échouées depuis le journal, vérifiez le statut des messages via l'API et renvoyez les messages entrants manqués.
Comment vérifier qu'une requête vient de Mail.Land ?
Calculez un HMAC-SHA256 sur l'horodatage, un point et le corps brut avec le secret du webhook, comparez-le en temps constant à la valeur v1 et refusez les horodatages de plus de 5 minutes. La documentation propose un exemple avec des valeurs exactes.
Un point de terminaison peut-il recevoir les événements de certains domaines seulement ?
Oui. Réglez la portée du webhook sur des domaines sélectionnés et listez-les ; il ne reçoit alors que les événements de ces domaines.
Reliez votre app à chaque résultat de livraison
Créez un compte gratuit, ajoutez un point de terminaison et envoyez-lui un événement de test.