MailLandDocs
Webhooks

Présentation des webhooks

Recevez des notifications en temps réel sur les événements e-mail via des webhooks

Les webhooks envoient des notifications HTTP en temps réel à votre serveur lorsque des événements e-mail se produisent : livraisons, rebonds, plaintes, et plus encore. Au lieu d'interroger périodiquement les changements d'état, MailLand transmet les événements à votre endpoint au moment où ils se produisent.

Fonctionnement des webhooks

Configurer un webhook

Enregistrez l'URL de votre endpoint et sélectionnez les événements que vous souhaitez recevoir.

Mail.Land envoie les événements

Lorsqu'un événement se produit (par exemple, un e-mail est livré), MailLand envoie un HTTP POST signé à votre endpoint avec le payload de l'événement.

Votre serveur répond

Renvoyez un code de statut 2xx pour accuser réception. Les réponses non-2xx déclenchent des nouvelles tentatives automatiques.

Créer un webhook

POST https://api.mail.land/v1/webhooks
Create a webhook
curl -X POST https://api.mail.land/v1/webhooks \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Events",
    "webhookUrl": "https://your-app.com/webhooks/mailland",
    "products": ["transactional", "marketing"],
    "events": ["message.delivered", "message.bounced", "message.deferred", "message.complained"],
    "includeFutureEvents": true,
    "scope": "all_domains"
  }'

Champs de la requête

ChampTypeRequisDescription
namestringNonNom lisible pour ce webhook
webhookUrlstringOuiURL de l'endpoint HTTPS pour recevoir les événements
productsarrayNonFiltre produit : transactional, marketing, inbound, system
eventsarrayNonÉvénements spécifiques auxquels s'abonner (voir Événements)
includeFutureEventsbooleanNonRecevoir les nouveaux événements ajoutés aux produits abonnés (défaut : true)
scopestringNonall_domains (défaut) ou selected_domains
domainIdsarrayNonIDs de domaines pour le filtrage (requis si scope est selected_domains)

Réponse

Statut : 201 Created

Webhook created response
{
  "webhook": {
    "id": "k3m9x2p7qw4rtz",
    "name": "Production Events",
    "webhookUrl": "https://your-app.com/webhooks/mailland",
    "products": ["transactional", "marketing"],
    "events": ["message.delivered", "message.bounced", "message.deferred", "message.complained"],
    "includeFutureEvents": true,
    "scope": "all_domains",
    "domainIds": [],
    "isActive": true,
    "createdAt": "2026-02-17T10:00:00Z",
    "successCount": 0,
    "failureCount": 0,
    "consecutiveFailures": 0,
    "pauseThreshold": 10
  },
  "secret": "whsec_a1b2c3d4e5f6g7h8i9j0..."
}

Le secret n'est affiché qu'une seule fois lors de la création du webhook. Conservez-le en lieu sûr : vous en aurez besoin pour vérifier les signatures des webhooks. Si vous le perdez, vous pouvez le régénérer, ce qui invalide l'ancien secret.

Les URL des webhooks doivent utiliser HTTPS. MailLand valide les URL contre les attaques SSRF : les adresses de réseau privé (127.0.0.1, 10.x, 192.168.x, etc.) sont rejetées. La livraison se fait uniquement en HTTPS sur le port 443 ; une URL sur un autre port, ou pointant vers les serveurs ou noms d'hôte de MailLand, est refusée avec 400 WEBHOOK_DESTINATION_NOT_ALLOWED. Un autre port TLS nécessite une approbation explicite du support MailLand.

Lister les webhooks

GET https://api.mail.land/v1/webhooks
List webhooks
curl -X GET https://api.mail.land/v1/webhooks \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
List response
[
  {
    "id": "k3m9x2p7qw4rtz",
    "name": "Production Events",
    "webhookUrl": "https://your-app.com/webhooks/mailland",
    "products": ["transactional", "marketing"],
    "events": ["message.delivered", "message.bounced"],
    "isActive": true,
    "lastTriggeredAt": "2026-02-17T12:30:00Z",
    "lastSuccessAt": "2026-02-17T12:30:00Z",
    "successCount": 1542,
    "failureCount": 3,
    "consecutiveFailures": 0,
    "createdAt": "2026-02-10T08:00:00Z"
  }
]

Retourne jusqu'à 100 webhooks triés par date de création (le plus récent en premier).

Obtenir les détails d'un webhook

GET https://api.mail.land/v1/webhooks/{id}
Get webhook detail
curl -X GET https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Retourne la configuration complète du webhook ainsi que les 50 journaux de livraison les plus récents. Consultez la Logique de nouvelles tentatives pour les détails des journaux de livraison.

Mettre à jour un webhook

PUT https://api.mail.land/v1/webhooks/{id}
Update webhook
curl -X PUT https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "All Events",
    "events": ["message.delivered", "message.bounced", "message.deferred", "message.complained"],
    "isActive": true
  }'

Tous les champs sont optionnels : incluez uniquement les champs que vous souhaitez modifier.

Tester un webhook

Envoyez un événement de test pour vérifier que votre endpoint fonctionne :

POST https://api.mail.land/v1/webhooks/{id}/test
Test a webhook
curl -X POST https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz/test \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Test result
{
  "success": true,
  "statusCode": 200,
  "statusText": "OK",
  "durationMs": 145,
  "responseBody": "{\"received\": true}",
  "headersSent": {
    "X-MLND-Signature": "t=1708171200,v1=abc123...",
    "X-MLND-Event-Id": "evt_test_abc123",
    "X-MLND-Event-Version": "1",
    "X-MLND-Event": "webhook.test",
    "X-MLND-Webhook-Id": "k3m9x2p7qw4rtz",
    "X-MLND-Attempt": "1"
  },
  "wouldReceiveRealEvents": true,
  "liveEvents": ["message.delivered", "message.bounced"],
  "dormantEvents": {},
  "subscriptionWarning": null
}

L'envoi de test utilise la même signature et le même transport de livraison qu'un événement réel : un succès ici prouve donc votre URL, votre TLS et votre vérification de signature.

Il ne prouve pas votre abonnement : un test est envoyé à la demande, sans passer par le routage de vos événements sélectionnés. Les quatre derniers champs y répondent séparément :

ChampSignification
wouldReceiveRealEventsIndique si un événement réel peut atteindre ce point de terminaison
liveEventsÉvénements souscrits qui passent le même filtre que le répartiteur applique
dormantEventsÉvénements souscrits qui n'arriveront jamais, chacun avec sa raison
subscriptionWarningRenseigné lorsque le point de terminaison est joignable mais définitivement inactif

Un "success": true accompagné de "wouldReceiveRealEvents": false est le cas important : le point de terminaison fonctionne mais n'est abonné à rien qui puisse être livré.

Si le test échoue, le champ errorType indique la raison : ssrf_blocked (l'URL, ou une redirection depuis celle-ci, pointait vers une destination vers laquelle la plateforme refuse d'envoyer) ou network_error (délai dépassé, échec TLS, connexion refusée ; errorMessage porte le détail).

Régénérer le secret

Si vous perdez ou devez faire tourner votre secret webhook :

POST https://api.mail.land/v1/webhooks/{id}/regenerate-secret
Regenerate webhook secret
curl -X POST https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz/regenerate-secret \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
New secret
{
  "secretKey": "whsec_x9y8z7w6v5u4..."
}

La régénération du secret invalide immédiatement l'ancien secret. Mettez à jour le code de vérification de votre serveur avant la prochaine livraison webhook, sinon vous rejetterez des événements valides.

Périmètre de domaine

Par défaut, les webhooks reçoivent les événements pour tous les domaines de votre espace de travail. Pour limiter un webhook à des domaines spécifiques :

Domain-scoped webhook
{
  "webhookUrl": "https://your-app.com/webhooks/mailland",
  "scope": "selected_domains",
  "domainIds": ["d4n8q1zt5wm3xc", "b7r2mv9k0jy4pw"]
}

Seuls les événements liés à ces domaines déclencheront le webhook.

Mise en pause automatique en cas d'échecs

MailLand met automatiquement en pause les webhooks après 10 échecs de livraison consécutifs (configurable via pauseThreshold). Cela évite de gaspiller des ressources sur des endpoints hors ligne.

Lorsqu'un webhook est mis en pause :

  • L'horodatage pausedAt est défini
  • pausedReason décrit la raison de la mise en pause
  • Un événement account.webhook_paused est envoyé à vos autres webhooks actifs
  • Une notification in-app est créée

Reprendre un webhook mis en pause

Après avoir résolu le problème, reprenez la livraison :

POST https://api.mail.land/v1/webhooks/{id}/resume
Resume a paused webhook
curl -X POST https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz/resume \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Cette action efface l'état de pause, réinitialise le compteur d'échecs consécutifs et réactive le webhook (isActive redevient true), de sorte que les événements futurs lui sont à nouveau livrés normalement.

Supprimer un webhook

DELETE https://api.mail.land/v1/webhooks/{id}
Delete a webhook
curl -X DELETE https://api.mail.land/v1/webhooks/k3m9x2p7qw4rtz \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Retourne 204 No Content. Si le webhook est utilisé par des routes d'e-mail entrant, ces routes seront mises à jour ou désactivées automatiquement.

Réponses d'erreur

StatutCodeDescription
400INVALID_REQUESTURL, événements ou configuration de périmètre invalides
403PLAN_LIMIT_REACHEDNombre maximum de webhooks atteint pour votre abonnement
404(corps vide)L'ID du webhook n'existe pas : renvoyé par get, update, delete, regenerate-secret et resume
404RESOURCE_NOT_FOUNDL'ID du webhook n'existe pas, renvoyé uniquement par /test

Étapes suivantes

Sur cette page