Aller au contenu

Aperçu des webhooks

Les webhooks envoient des événements vers votre serveur en temps réel, ce qui vous évite de sonder l’API. Lorsqu’un événement se produit dans un restaurant — une réservation est créée, un client est mis à jour, un avis arrive — nous envoyons une requête HTTP POST à une URL que vous contrôlez, accompagnée d’un événement JSON décrivant ce qui s’est passé.

Les points de terminaison de webhook sont en libre-service depuis le back-office. Un propriétaire ou copropriétaire peut les gérer dans Paramètres → Développeurs :

  1. Ajoutez un point de terminaison avec son URL — une adresse HTTPS, accessible publiquement (les adresses internes ou privées sont rejetées).
  2. Choisissez les événements qu’il doit recevoir — des types d’événements individuels ou tous les événements.
  3. Révélez son secret de signature (whsec_…) et stockez-le ; il sert à vérifier les signatures. Vous pouvez le faire tourner par la suite s’il est un jour exposé.

Depuis le même écran, vous pouvez activer, désactiver ou supprimer un point de terminaison, consulter un journal de livraison indiquant le statut et la réponse de chaque tentative, renvoyer une livraison passée et envoyer un événement de test. Un restaurant peut enregistrer jusqu’à 5 points de terminaison.

Chaque point de terminaison est épinglé à une version de l’API à sa création, afin que la forme de la charge utile que vous recevez reste stable.

Un point de terminaison est enregistré par le restaurant et n’est lié à aucune clé d’API : aucune portée ne filtre ce qu’il reçoit. Une livraison de réservation porte les coordonnées de la réservation (contact_email, contact_phone), les notes du client (guest_notes) et la note privée du restaurant (internal_notes), les événements guest.* portent la fiche client, une entrée de file d’attente porte les notes du client, et feedback.received porte le commentaire du client. Sur l’API, ces mêmes champs exigent guests:read : voir Données client d’une réservation. La note privée d’une entrée de file d’attente est la seule chose qu’aucune charge utile ne porte.

Traitez l’URL du point de terminaison comme un identifiant d’accès au fichier clients du restaurant. Quiconque répond à cette URL reçoit les coordonnées de chaque client à mesure qu’elles changent : enregistrez uniquement un hôte que vous contrôlez, et gardez l’URL hors des tickets, des messageries et des configurations partagées.

Chaque livraison est un objet JSON avec cette enveloppe :

{
"id": "evt_1K8xQ2m4Vd0pErJ7sN1aZ9bQ",
"object": "event",
"type": "reservation.updated",
"created": "2026-06-27T17:30:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": { "object": "reservation", "id": "resv_…" },
"previous_attributes": { "party_size": 2 }
}
}

Tous ses champs, et les deux horloges que porte un même contenu, sont sur L’objet événement de webhook.

Renvoyez un code de statut 2xx pour accuser réception, puis effectuez le vrai travail de manière asynchrone. Une livraison expire au bout de 10 secondes, à la connexion comme à la lecture, si bien qu’un point de terminaison qui termine son propre traitement avant de répondre commence à échouer dès que ce traitement ralentit. Toute réponse non 2xx, un délai d’expiration ou une erreur de connexion est une livraison échouée et fait l’objet d’une nouvelle tentative.

Le corps de votre réponse est lu jusqu’à 64 Kio, puis la lecture est abandonnée, ce qui fait échouer la livraison. Les 500 premiers octets sont conservés dans le journal de livraison : une courte chaîne de diagnostic vaut la peine d’être renvoyée, une page HTML entière non.

La livraison est au moins une fois. Le même événement peut être livré plus d’une fois (par exemple, si votre serveur est lent à accuser réception et que nous réessayons, ou après une erreur réseau transitoire). Dédupliquez sur l’id de l’événement (evt_…) : enregistrez les identifiants que vous avez traités et ignorez les répétitions. Rendez votre gestionnaire idempotent.

Les événements ne sont pas garantis d’arriver dans l’ordre où ils se sont produits. Par exemple, vous pourriez recevoir reservation.seated avant reservation.confirmed. Ne présumez pas de l’ordre. Lorsqu’une décision dépend de l’état actuel, traitez l’événement comme un indice et récupérez la dernière version de la ressource depuis l’API, ou réconciliez à l’aide du updated_at de chaque ressource.

Nouvelles tentatives et désactivation automatique

Section intitulée « Nouvelles tentatives et désactivation automatique »

Une livraison échouée est réessayée selon un calendrier fixe : 9 tentatives au total, étalées sur environ 2,7 jours. Les attentes qui les séparent sont de 1 minute, 5 minutes, 30 minutes, 2 heures, 5 heures, 10 heures, 24 heures et 24 heures. Après la neuvième tentative, la livraison est marquée comme échouée et n’est plus jamais reprise.

Une seule livraison réussie remet à zéro le compteur d’échecs du point de terminaison. 15 livraisons consécutives qui épuisent leurs 9 tentatives désactivent le point de terminaison, et une alerte est levée. Corrigez le point de terminaison, réactivez-le depuis le back-office, puis récupérez les événements manqués pendant l’interruption en relisant les données avec updated_since.

Service ne publie aucune liste d’adresses IP d’où partent les livraisons et ne s’engage sur aucune plage fixe. Authentifiez une livraison par sa signature et non par sa provenance apparente.

Les réservations importées n’émettent pas de webhooks

Section intitulée « Les réservations importées n’émettent pas de webhooks »