Aller au contenu
Retour à la documentation pour les développeurs

Guide des webhooks

Comment recevoir et vérifier les événements que Mailronix envoie à votre adresse : livraison, signature, contenu, nouvelles tentatives et rotation du secret.

Comment arrivent les livraisons

Chaque événement est une requête POST avec un corps JSON vers l'adresse HTTPS que vous avez enregistrée (port 443 ou 8443). Répondez en moins de 10 secondes : tout code 2xx confirme la livraison. Tout le reste est une erreur et déclenche une nouvelle tentative, y compris les redirections, qui ne sont pas suivies. Les adresses non joignables depuis l'Internet public sont refusées.

Mailronix-Signature
La signature de la requête. Voir « Vérifier la signature ».
Mailronix-Event-Id
L'identifiant de l'événement, identique au champ id du corps. Il reste le même à chaque tentative.
Mailronix-Delivery-Id
L'identifiant de la livraison. Indiquez-le lorsque vous contactez le support.
Mailronix-Event-Type
Le type d'événement, identique au champ type du corps.

Vérifier la signature

Vérifiez toujours la signature avant de vous fier au contenu : toute personne qui connaît votre adresse peut lui envoyer une requête. La signature est le HMAC-SHA256, en hexadécimal, de la chaîne « t.corps », avec le corps exactement tel que vous l'avez reçu.

Mailronix-Signature: t=<unix>,v1=<hmac-sha256>
  v1 = hex( HMAC-SHA256( chiave, "<t>." + corpo ) )
  1. Clé : le secret que la console n'affiche qu'une fois a la forme « whsec_… ». La clé HMAC correspond aux octets qui suivent le préfixe, décodés depuis du base64url sans remplissage. Le texte du secret n'est pas la clé.
  2. Corps : calculez le HMAC sur les octets bruts reçus. Si votre framework analyse le JSON avant vous, récupérez le corps brut (dans Express, express.raw) : réécrire le JSON change les octets et la signature ne correspond plus.
  3. Fraîcheur : refusez les requêtes dont t s'écarte de plus de cinq minutes de l'heure actuelle. t est l'instant de chaque tentative, donc une nouvelle tentative plusieurs heures plus tard passe aussi le contrôle.
  4. Plusieurs signatures : dans les 24 heures qui suivent une rotation, l'en-tête contient deux valeurs v1, une pour le nouveau secret et une pour le précédent. Acceptez la requête si l'une d'elles correspond à l'un des secrets que vous connaissez.
  5. Comparaison : utilisez une comparaison à temps constant, comme dans les exemples.

Exemples de vérification

import { createHmac, timingSafeEqual } from 'node:crypto'

// `segreto` è quello mostrato dalla console, «whsec_…». La chiave HMAC sono i
// suoi byte: si toglie il prefisso e si decodifica da base64url.
const chiave = (segreto) => Buffer.from(segreto.replace(/^whsec_/, ''), 'base64url')

// `corpo` è il corpo ESATTO ricevuto (Buffer), non il JSON riscritto.
export function verificaFirma(intestazione, corpo, segreti, toleranza = 300) {
  const parti = intestazione.split(',').map((p) => p.trim().split('='))
  const t = parti.find(([k]) => k === 't')?.[1]
  const firme = parti.filter(([k]) => k === 'v1').map(([, v]) => v)
  if (!t || firme.length === 0) return false
  if (Math.abs(Date.now() / 1000 - Number(t)) > toleranza) return false

  let valida = false
  for (const segreto of segreti) {
    const atteso = createHmac('sha256', chiave(segreto)).update(`${t}.`).update(corpo).digest()
    for (const firma of firme) {
      const ricevuta = Buffer.from(firma, 'hex')
      if (ricevuta.length === atteso.length && timingSafeEqual(ricevuta, atteso)) valida = true
    }
  }
  return valida
}

Exemples exécutés contre la vraie signature de Mailronix. Si la vérification échoue, répondez 401 ; une fois l'événement accepté, répondez 200 tout de suite et traitez-le ensuite.

Événements et contenu

Chaque corps a la même enveloppe ; le contenu de data dépend du type.

{
  "id": "evt_01j9x4k2m7q8r5t3v6w1y0z2ab",
  "type": "email.bounced",
  "api_version": "2026-10-22",
  "created_at": "2026-10-22T14:03:11Z",
  "brand_id": "6f1c7d0e-5a3b-4e8f-9c21-0b7d4a1e3f52",
  "data": {
    "email_log_id": "b2d4f6a8-1c3e-4a5b-8d7f-9e0a1b2c3d4e",
    "recipient": "[email protected]",
    "category": "transactional",
    "bounce_type": "permanent"
  }
}
  • id : l'identifiant de l'événement. Utilisez-le pour repérer les doublons.
  • type : l'un des types listés ci-dessous, ou webhook.test pour la livraison de test.
  • api_version : la version du format.
  • created_at : quand l'événement s'est produit, en UTC.
  • brand_id : la marque à laquelle appartient l'événement (null seulement dans webhook.test).
  • Les événements email.* portent dans data email_log_id, recipient et category. email.bounced ajoute bounce_type (permanent, transient ou undetermined) : un rebond annoncé comme transient puis reclassé permanent produit un second email.bounced.
  • Les événements contact.* portent dans data contact_id et email. contact_id peut être null dans contact.unsubscribed, par exemple quand la désinscription vient d'une révocation : prévoyez ce cas.

Types d'événement

email.sent
webhookGuide.eventTypes.email.sent
email.delivered
webhookGuide.eventTypes.email.delivered
email.bounced
webhookGuide.eventTypes.email.bounced
email.complained
webhookGuide.eventTypes.email.complained
email.failed
webhookGuide.eventTypes.email.failed
email.suppressed
webhookGuide.eventTypes.email.suppressed
contact.confirmed
webhookGuide.eventTypes.contact.confirmed
contact.unsubscribed
webhookGuide.eventTypes.contact.unsubscribed

Il n'y a pas d'événements d'ouverture : Mailronix ne les enregistre pas, par choix de confidentialité. Les événements email.clicked n'arrivent que pour les marques qui ont activé le suivi des clics et uniquement pour les destinataires qui ont accepté ; ils décrivent un clic détecté (des scanners et des aperçus peuvent en générer) et portent l'hôte de destination, pas l'URL. Le retrait du consentement bloque les nouvelles détections et ne rend pas rétroactivement illicite l’événement déjà collecté : les événements antérieurs déjà en file d’attente peuvent arriver ultérieurement, pendant les 30 jours de conservation de la file. L’effacement du contact entraîne l’effacement des événements et des livraisons en file d’attente selon la procédure prévue. Le client destinataire du webhook reste responsable de ses propres copies et de la gestion des droits des personnes concernées à leur égard.

Nouvelles tentatives, doublons et ordre

  • Une livraison échouée est retentée jusqu'à dix fois en près de quatre jours : tout de suite, puis après 10 secondes, 1 minute, 5 minutes, 30 minutes, 2 heures, 6 heures, 12 heures, 24 heures et 48 heures.
  • Chaque événement arrive au moins une fois, pas exactement une : il peut arriver deux fois, par exemple si vous répondez après la limite de 10 secondes. Conservez les id déjà traités et ignorez les doublons.
  • L'ordre d'arrivée n'est pas garanti : un email.delivered peut arriver après un email.bounced. Pour ordonner les événements, utilisez created_at, pas l'heure de réception.
  • Si un événement épuise ses tentatives et qu'aucune livraison vers ce point de terminaison n'a réussi au cours des trois derniers jours, le point de terminaison est désactivé et le propriétaire reçoit un e-mail. Depuis la page Webhooks, vous pouvez le réactiver (le mot de passe est demandé) et renvoyer des événements un par un. Les livraisons sont conservées 30 jours.

Faire tourner le secret

Depuis la page Webhooks, vous pouvez faire tourner le secret d'un point de terminaison (le mot de passe est demandé) ; le nouveau secret n'est affiché qu'une fois. Pendant 24 heures, chaque livraison porte deux signatures, celle du nouveau secret et celle du précédent : acceptez les deux secrets pendant ce temps et mettez à jour votre récepteur sans perdre de livraisons. Si l'ancien secret a fuité, choisissez de le révoquer immédiatement : à partir de là, seul le nouveau compte.

Tester le récepteur

À la création d'un point de terminaison et avec l'action « Envoyer un test », Mailronix envoie un événement webhook.test avec la même enveloppe et la même signature que les vrais événements, sans données de destinataires. Si le test échoue, le point de terminaison est enregistré mais reste désactivé.

Limites

Les points de terminaison actifs par compte sont 1 avec l'offre Free, 5 avec Starter et 10 avec Growth. Les points de terminaison se configurent uniquement depuis la console, avec la session et jamais avec une clé API.

Créer un compte gratuit