MailLandDocs
Webhooks

Versionnage et compatibilité

Comment les payloads de webhook sont versionnés, ce que signifie chaque identifiant et chaque horodatage, et comment les changements et dépréciations sont annoncés

MailLand ne modifie les payloads de webhook que d’une manière qu’un récepteur existant peut ignorer. Cette page énonce cet engagement, les identifiants et horodatages sur lesquels un récepteur peut s’appuyer, et ce qui se passerait avant toute introduction d’un changement incompatible.

Version de schéma

Chaque type d’événement possède une version de schéma de son payload, un entier positif. Tous les événements sont aujourd’hui en version 1.

  • Le corps la porte dans schema_version.
  • L’en-tête X-MLND-Event-Version porte la même valeur.
  • Un corps sans schema_version (envoyé avant l’existence du champ) est en version 1.

La version est fixée à la création de l’événement : chaque nouvelle tentative du même événement porte donc la même version. Le v1 de X-MLND-Signature est la version du procédé de signature, indépendante.

Identifiants

IdentifiantOùIdentique entre tentativesÀ utiliser pour
event_idcorps, X-MLND-Event-IdOuiDéduplication : traiter chaque event_id une seule fois
eventcorps, X-MLND-EventOuiLe type d’événement, p. ex. message.delivered
id de pièce jointe (inbound.received)corps, data.email.attachments[]OuiReconnaître une pièce jointe déjà téléchargée ; sa download_url est nouvelle à chaque tentative
Identifiant de livraisonX-MLND-Delivery-IdNon, nouveau à chaque tentativeSupport et diagnostic ; c’est le publicId que l’historique des livraisons affiche pour la tentative
X-MLND-Attempten-têteNonNuméro de tentative, à partir de 1

Dédupliquez sur event_id, jamais sur l’identifiant de livraison. Les événements peuvent arriver plusieurs fois et dans le désordre ; pour les événements de message, ordonnez selon data.status_version, qui ne fait qu’augmenter pour un message donné.

Horodatages

ChampSignification
occurred_at (corps)Quand l’événement lui-même s’est produit. Pour les événements de message, l’heure de l’événement sur le serveur de messagerie, le même instant que data.timestamp.
timestamp (corps)Quand MailLand a créé l’événement de webhook. Inchangé par rapport aux versions précédentes.
t dans X-MLND-Signature, et X-MLND-Delivery-TimestampQuand cette tentative a été envoyée, en secondes Unix. Les deux ont toujours la même valeur.

Toutes les heures du corps sont en UTC au format ISO 8601 terminé par Z. Le corps est identique à chaque tentative ; seuls les en-têtes d’une tentative changent. La signature couvre t et le corps brut, pas les autres en-têtes : traitez-les comme des métadonnées de routage et fiez-vous au corps.

Engagement de compatibilité

Les récepteurs doivent ignorer les champs JSON et en-têtes HTTP qu’ils ne connaissent pas. Avec cette règle, chacun des changements suivants est sûr et se fait sans nouvelle version de schéma :

  • l’ajout d’un champ au corps ou à data, ou d’un nouvel en-tête ;
  • l’ajout d’un type d’événement, reçu seulement après abonnement ;
  • l’ajout d’une valeur à un champ que cette documentation décrit comme ouvert.

Chacun des changements suivants est incompatible et n’est jamais appliqué à une version existante :

  • supprimer ou renommer un champ, un en-tête ou un type d’événement ;
  • changer le type, le format, l’unité ou la signification d’un champ ;
  • rendre obligatoire un champ facultatif, ou nullable un champ non nul ;
  • ajouter une valeur à un champ documenté comme liste fermée.

Un changement incompatible ne serait livré que sous une nouvelle version de schéma que vous choisissez explicitement. Les abonnements existants ne passent jamais automatiquement à une nouvelle version.

Politique de dépréciation

  • Une dépréciation est annoncée au moins 180 jours avant toute migration demandée : dans le journal des modifications, dans le tableau de bord et par e-mail aux propriétaires du compte.
  • L’annonce précise l’événement, la version ou le champ concerné, son remplaçant et la marche à suivre.
  • Un champ déprécié reste dans le payload et un événement déprécié reste disponible pour les abonnés existants. Une dépréciation seule ne supprime jamais rien. Supprimer une version exige une annonce distincte, au plus tôt 180 jours après l’avis de dépréciation.

Exceptions

inbound.received utilise aussi cette enveloppe. Une différence : la download_url de chaque pièce jointe est signée à chaque tentative et diffère donc d’une tentative à l’autre ; l’id de la pièce jointe, lui, ne change pas.

Les étapes Webhook des automatisations envoient un corps plat avec les champs de l’abonné, pas cette enveloppe. Depuis cette version, elles ajoutent event_id, occurred_at et schema_version, et elles sont signées. Voir ci-dessous.

Étapes Webhook des automatisations

Les étapes Webhook d’une automatisation sont signées exactement comme les webhooks clients : vérifiez X-MLND-Signature avec le secret de signature du récepteur de cette étape, selon les mêmes étapes.

  • Chaque récepteur (une URL d’étape distincte) a son propre secret : aucun récepteur ne peut produire de signatures qu’un autre accepte. Les étapes qui envoient vers la même URL forment un seul récepteur et partagent son secret.
  • Lisez les secrets avec GET /v1/marketing/automations/{id}/webhook-signing-secrets : une liste secrets de { webhookUrl, secret }, dans l’ordre des étapes. Ils sont créés quand une automatisation comportant une étape Webhook est créée ou enregistrée. Une modification conserve le secret de chaque URL inchangée ; une URL nouvelle ou modifiée reçoit un nouveau secret.
  • Remplacez-les avec POST /v1/marketing/automations/{id}/webhook-signing-secrets/regenerate, qui donne un nouveau secret à chaque récepteur et les renvoie. Les anciens secrets cessent de fonctionner immédiatement : faites d’abord accepter les deux à chaque récepteur. Une copie d’automatisation reçoit ses propres secrets, et une automatisation dont toutes les étapes Webhook sont supprimées perd les siens.
  • Pour ne faire tourner qu’un seul récepteur, envoyez { "webhookUrl": "<URL de l’étape>" } comme corps de la requête regenerate ; tous les autres récepteurs gardent leur secret. Une URL qui n’est pas une URL d’étape Webhook de l’automatisation donne 400.
  • Une automatisation dont les récepteurs partagent encore un même secret est scindée en secrets par récepteur lors de son activation ou de sa reprise, ou avant l’envoi de sa prochaine étape Webhook. Une requête n’est jamais signée avec un secret détenu par un autre récepteur : si la scission est impossible, l’étape n’est pas envoyée.
  • X-MLND-Event-Id est stable pour une exécution d’une étape pour un abonné. Utilisez-le avec la fenêtre de 5 minutes sur t pour rejeter les rejeux.
  • Une automatisation enregistrée avant l’existence de la signature envoie des requêtes non signées jusqu’à ce qu’elle soit enregistrée de nouveau ou que son secret soit régénéré.
  • Ces requêtes sont au mieux : une seule tentative, sans calendrier de nouvelles tentatives. L’automatisation continue quelle que soit la réponse du récepteur.

Sur cette page