Skip to Content
Webhooks

Webhooks

Plutôt que de faire du polling, abonnez-vous aux événements sortants : Kinmu envoie un POST à votre endpoint HTTPS quand un événement pertinent se produit. Chaque livraison est signée selon la convention Standard Webhooks vérifiez toujours la signature avant de traiter l’événement.

La gestion des endpoints requiert le scope webhooks:manage et s’effectue depuis le dashboard ou via les endpoints /v1/webhook-endpoints.

Abonnement

Créez un endpoint en indiquant votre URL (HTTPS) et les événements qui vous intéressent :

curl -s -X POST "https://api.kinmu.app/v1/webhook-endpoints" \ -H "Authorization: Bearer kinmu_sk_live_…" \ -H "Content-Type: application/json" \ -d '{ "url": "https://tu-app.example.com/webhooks/kinmu", "events": ["absence.approved", "checkin.created"], "description": "Sync con nuestro ERP" }'

La réponse inclut le secret de signature (whsec_…), visible une seule fois. Conservez-le : il vous servira à vérifier les signatures.

Gestion disponible : GET (liste), GET /{id}, PATCH /{id} (événements/état), DELETE /{id}, POST /{id}/test (envoie un ping), GET /{id}/deliveries (dernières livraisons) et POST /{id}/deliveries/{deliveryId}/retry (remet en file une livraison précise). 5 endpoints actifs maximum par entreprise.

Événements

employee.created, employee.updated, employee.terminated, checkin.created, absence.requested, absence.approved, absence.denied, absence.cancelled, vacation_balance.updated, report.completed, ping.

Payload de l’événement

{ "id": "evt_…", "type": "absence.approved", "created_at": "…", "company_id": "…", "data": { } }

data contient les ids publics + un état minimal ; réhydratez la ressource complète via GET quand vous avez besoin de tous les champs.

Vérification de la signature

Chaque livraison arrive avec trois headers :

HeaderContenu
webhook-idId unique de l’événement (idempotence côté récepteur).
webhook-timestampTimestamp Unix de l’envoi.
webhook-signaturev1,<signature> (plusieurs signatures possibles, séparées par des espaces).

Algorithme : signature = base64( HMAC_SHA256( key, "{webhook-id}.{webhook-timestamp}.{corps_brut}" ) ), préfixée par v1,. La key est la partie après whsec_ du secret (affiché une seule fois à la création du webhook), décodée de base64 en bytes. Signez le corps brut (les bytes exacts reçus), pas le JSON re-sérialisé.

Vérification (rejetez si la signature ne correspond pas ou si webhook-timestamp s’écarte de plus de 5 min de votre horloge) :

const crypto = require('crypto'); function verify(secret, headers, rawBody) { const id = headers['webhook-id']; const ts = headers['webhook-timestamp']; if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // ±5 min const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64'); const expected = 'v1,' + crypto .createHmac('sha256', key) .update(`${id}.${ts}.${rawBody}`) .digest('base64'); return headers['webhook-signature'] .split(' ') .some(sig => crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))); }

Vérifiez et signez sur le corps brut (les bytes exacts reçus), pas sur le JSON re-sérialisé — tout reformatage invalide la signature. Utilisez le webhook-id comme clé d’idempotence côté récepteur pour écarter les renvois.

Nouvelles tentatives

En cas d’échec (ou de réponse ≠ 2xx), Kinmu réessaie avec un backoff : 1 min, 5 min, 30 min, 2 h, 12 h, 24 h. Répondez 2xx rapidement ; traitez en asynchrone si le traitement est long. Un endpoint en échec pendant 7 jours consécutifs est désactivé automatiquement.

Vous pouvez remettre en file manuellement une livraison échouée avec POST /v1/webhook-endpoints/{id}/deliveries/{deliveryId}/retry (utilisez l’id de la livraison visible dans GET /{id}/deliveries).

Bonnes pratiques

Répondez vite, traitez en arrière-plan

Vérifiez la signature, mettez le travail en file d’attente et répondez 2xx immédiatement.

Vérifiez toujours la signature

Ne traitez aucun payload sans vérifier webhook-signature. Traitez le secret comme un identifiant sensible.

Soyez idempotent

Dédupliquez par webhook-id. Les renvois sont normaux.

Testez avec ping

Utilisez POST /v1/webhook-endpoints/{id}/test pour recevoir un événement ping et valider votre intégration de bout en bout.

Last updated on