Webhooks
Recevez une requête HTTP à l'instant précis où un rendez-vous est créé, confirmé, déplacé, annulé ou terminé, et connectez BookifyLabs à vos propres systèmes.
Ajouter un point de terminaison (endpoint)
- En tant que propriétaire, ouvrez Paramètres au niveau de l'entreprise et trouvez la carte Webhooks.
- Cliquez sur Ajouter un point de terminaison et saisissez une URL publique https://. Les adresses de réseaux privés et localhost sont refusées.
- Copiez le secret de signature affiché après la création. Il commence par
whsec_et n'est affiché qu'une seule fois. - Envoyez un événement de test en créant un rendez-vous, puis consultez la liste des Envois.
Vous pouvez avoir jusqu'à 5 points de terminaison par entreprise. Chacun peut être mis en pause et repris, voir son URL modifiée, son secret régénéré, ou être supprimé avec son historique d'envois.
Événements
| Événement | Envoyé quand |
|---|---|
appointment.created | Une réservation est effectuée, en ligne, par Booky ou par votre équipe. |
appointment.confirmed | Un rendez-vous en attente est confirmé. |
appointment.rescheduled | L'heure ou le professionnel change. |
appointment.cancelled | Le rendez-vous est annulé par vous ou par le client. |
appointment.completed | Le rendez-vous est marqué comme terminé via l'écran de finalisation. |
Format de la requête
Chaque envoi est un POST avec un corps JSON. L'objet data est une capture du rendez-vous au moment où l'événement s'est produit ; les tentatives de retransmission renvoient le même corps.
POST https://example.com/hooks/bookify
Content-Type: application/json
User-Agent: BookifyLabs-Webhooks/1.0 (+https://bookifylabs.com)
X-Bookify-Event-ID: evt_3f6c…
X-Bookify-Timestamp: 1757145600
X-Bookify-Signature: 4b1d…
{
"id": "evt_3f6c…",
"type": "appointment.created",
"created_at": 1757145600,
"data": {
"appointment": { "id": 1234, "status": "booked", "start_at": "…", "…": "…" }
}
}Vérifier la signature
La signature est un HMAC-SHA256 hexadécimal sur la chaîne <timestamp>.<raw body>, signé avec le secret de votre point de terminaison. Calculez-le à partir du corps brut de la requête, avant tout traitement JSON, et comparez-le avec une fonction à temps constant.
import crypto from "node:crypto";
function verify(rawBody, headers, secret) {
const ts = headers["x-bookify-timestamp"];
const sig = headers["x-bookify-signature"];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // de plus de 5 minutes
const expected = crypto
.createHmac("sha256", secret)
.update(`${ts}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}- Rejetez les horodatages datant de plus de 5 minutes pour empêcher le rejeu.
- Dédupliquez sur X-Bookify-Event-ID : une nouvelle tentative conserve le même identifiant.
- Répondez avec n'importe quel code 2xx dans les 10 secondes. Effectuez les traitements lourds après avoir répondu.
Nouvelles tentatives et historique des envois
Un envoi qui expire, ou qui reçoit une réponse 408, 425, 429 ou n'importe quel code 5xx, est réessayé toutes les 12 heures jusqu'à 30 tentatives. Les redirections ne sont pas suivies et les autres réponses 4xx sont considérées comme définitives. Le tableau Envois affiche le statut de chaque événement (en attente, envoi en cours, nouvelle tentative, livré, échoué), le nombre de tentatives, la réponse enregistrée (jusqu'à 4 Ko) et l'heure de la prochaine tentative. Les envois échoués ou en cours de réessai peuvent être forcés avec Réessayer maintenant. L'historique est conservé pendant 30 jours.