Fonctionnement de la livraison
Le contenu standard, le délai de 5 secondes, les raisons de l’absence de nouvelles tentatives et la signification de chaque statut de livraison.
L'envoi des webhooks est volontairement simple, et cette simplicité a des conséquences pour votre récepteur : une seule tentative HTTP, cinq secondes, aucune nouvelle tentative. Lisez cette page avant de décider de la quantité de traitement que votre gestionnaire effectuera de manière synchrone.
La structure standard des données
Tous les événements sauf listing.submission arrivent avec la même structure de premier niveau, les champs propres à chaque événement étant imbriqués sous data.
{ "event": "connection.location_connected", "timestamp": "2026-08-25T14:32:10Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc" }}Les champs facultatifs de data sont omis lorsqu'ils sont vides, au lieu d'être envoyés avec la valeur null. Prévoyez ces cas dans votre code : traitez de la même manière une clé absente et une valeur null explicite, et ne supposez jamais qu'une clé documentée comme facultative sera présente.
Deux exceptions
Le délai de 5 secondes
Chaque envoi consiste en un seul POST avec un délai de connexion de 5 secondes et un délai de lecture de 5 secondes. Si votre point de terminaison n'a pas répondu à temps, la tentative est abandonnée et enregistrée comme timeout.
Ce délai couvre l'ensemble du traitement effectué par votre gestionnaire. La seule conception sûre consiste à :
- Vérifier la signature.
- Enregistrer les données dans un stockage durable : une file d'attente, une table, un journal.
- Renvoyer
200.
Tous les autres traitements (enrichissement, distribution à plusieurs destinataires, appels à l'API REST, toute interaction avec un service tiers) doivent être effectués après la mise en file d'attente.
Aucune nouvelle tentative n'est effectuée
Chaque envoi fait l'objet d'une seule et unique tentative. Il n'y a ni temporisation progressive, ni file d'attente pour les nouvelles tentatives, ni file d'attente de lettres mortes. Si votre point de terminaison est indisponible pendant deux minutes, les événements déclenchés durant ces deux minutes sont perdus. Ils n'arriveront pas plus tard.
Deux conséquences doivent être explicitées :
- Les redirections ne sont pas suivies. Les redirections sont entièrement désactivées : si votre point de terminaison renvoie
301ou302, l'envoi est enregistré comme un échec et aucune seconde URL n'est appelée. Configurez l'URL de vos webhooks avec l'URL finale. Faites attention aux redirections du domaine nu verswwwet à celles qui ajoutent une barre oblique finale, que de nombreux serveurs web appliquent par défaut. - Seul un
2xxest considéré comme un envoi réussi.3xx,4xxet5xxsont tous enregistrés comme des échecs.
Doublons et ordre
- Vous pouvez recevoir deux fois le même événement, et le même id pour deux modifications différentes. Les identifiants dans
data(un id d’interaction, un id d’élément de publication, un id de compte connecté) désignent la ressource, pas la modification.interaction.reviewse déclenche à nouveau avec le même id d’interaction chaque fois que l’avis change, et aucune charge utile ne contient de version ni de champ updated-at : un gestionnaire qui ignore définitivement les événements sur la base de l’id +eventécarte donc silencieusement de véritables modifications. Détectez plutôt les doublons exacts : calculez le hachage des octets bruts du corps et ignorez toute répétition du même hachage dans une courte fenêtre de durée limitée (quelques minutes, pas indéfiniment). Un corps différent pour le même id correspond à une nouvelle modification, pas à un doublon. Relisez ensuite la ressource via l’API REST et considérez le résultat de cette lecture comme la référence ; utilisez l’id de la ressource comme clé pour l’écriture au lieu d’omettre celle-ci. - L’ordre n’est pas garanti, et
timestampn’y changera rien. Les événements proviennent de plusieurs flux indépendants et sont transmis à mesure qu’ils arrivent ; unlocal_post.publishedpeut donc arriver avant lelocal_post.createdque vous attendiez en premier. N’ordonnez pas deux modifications de la même ressource selontimestamp: cet horodatage est défini lors de la préparation de l’envoi, pas au moment de la modification, et la charge utile ne contient aucune version ni aucun numéro de séquence. Lorsque l’ordre compte, relisez la ressource et utilisez ce que l’API renvoie. profile.updatedest limité à un envoi par établissement toutes les 60 secondes, au début de la fenêtre. Il s’agit bien d’une suppression des événements suivants, pas d’un délai : la première modification ouvre la fenêtre et est transmise, toutes les modifications effectuées dans cette fenêtre sont écartées et n’arrivent jamais, etchanged_fieldsdécrit uniquement la modification qui a ouvert la fenêtre. L’événement vous parvient donc au début de la fenêtre ; une relecture déclenchée par son arrivée ne peut donc voir que cette première modification. Planifiez une seconde relecture après la fermeture de la fenêtre, au moins 60 secondes après l’événement, et synchronisez également les données des établissements à intervalles réguliers, car la notification elle-même peut se perdre : une seule tentative, sans nouvelle tentative. Aucun autre événement n’est soumis à ce mécanisme de limitation.
Récupérer les données après un événement manqué
Il n’y a ni nouvelle tentative ni retransmission ; chaque famille nécessite donc une lecture de référence à laquelle vous pouvez recourir. Synchronisez les données à intervalles réguliers, pas seulement lorsqu’un problème semble se produire.
Résultats des livraisons
Chaque tentative, même lorsqu’aucune requête n’est envoyée, est enregistrée avec un statut. Voici les chaînes exactes.
Liste de vérification pour le récepteur
- Vérifiez la signature de chaque requête ; renvoyez
401et n’effectuez aucun traitement si elle ne correspond pas. - Calculez le hachage des octets bruts du corps, jamais celui d’un objet sérialisé à nouveau.
- Renvoyez
2xxbien avant l’expiration du délai de 5 secondes ; mettez le traitement en file d’attente. - Utilisez les identifiants présents dans
datacomme clés pour chaque écriture effectuée par le gestionnaire afin qu’une répétition produise le même résultat, mais ne considérez jamais qu’un identifiant déjà reçu signifie qu’il n’y a rien à faire. - Ne déduisez pas l’ordre des événements de leur ordre d’arrivée et ne les triez pas selon
timestamp. - Normalisez
location_iden chaîne de caractères dès sa réception. - Ignorez les valeurs de
eventque vous ne reconnaissez pas et renvoyez tout de même200. - Servez directement l’URL des webhooks, sans redirection.
- Vérifiez et corrigez périodiquement la cohérence des données avec l’API REST ; aucune nouvelle tentative n’est prévue pour rattraper les échecs.