Aller au contenu
Parcourir la référence
Retour à la référence de l'API
Guide

Recevoir des webhooks

Les webhooks vous poussent les événements en temps réel, au lieu de vous obliger à interroger l'API. Déclarez une URL, choisissez les événements qui vous intéressent et vérifiez chaque livraison grâce à sa signature HMAC.

S'abonner

Créez un abonnement via l'API Webhooks en indiquant l'URL de votre endpoint et les eventTypes à recevoir. Vous recevrez en retour un secret de signature : conservez-le ; il sert à vérifier chaque livraison.

bash
curl -H "Authorization: Bearer vokse_sk_…" \     -H "Content-Type: application/json" \     -H "Idempotency-Key: $(uuidgen)" \     -X POST https://api.vokse.ai/households/current/webhooks/subscriptions \     -d '{"url":"https://example.com/hooks/vokse","eventTypes":["transaction.created","budget.overrun"]}'

Types d'événements

La liste complète et à jour des types d'événements est servie depuis /meta/webhook-events. Voici le catalogue actuel :

  • transaction.created : une transaction a été enregistrée.
  • recurrence.materialised : une récurrence a généré sa transaction planifiée.
  • bank.sync.completed : une connexion bancaire a terminé sa synchronisation.
  • budget.overrun : une catégorie a dépassé son budget du mois.
  • spending.anomaly : une dépense inhabituelle a été détectée.
  • goal.reached : un objectif d'épargne a été atteint.
  • insight.generated : une nouvelle analyse IA est disponible.

Vérifier la signature

Chaque livraison transporte un en-tête X-Vokse-Signature de la forme t=<timestamp>,v1=<signature>. La signature est un HMAC-SHA256, calculé avec votre secret de signature, sur le timestamp, un point, puis le corps brut de la requête. Reconstituez cette chaîne à partir des octets exacts reçus, recalculez le HMAC, comparez-le à v1 en temps constant et rejetez les timestamps trop anciens.

js
import crypto from 'node:crypto';// X-Vokse-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256>function verify(rawBody, signatureHeader, signingSecret) {  const parts = new Map(    signatureHeader.split(',').map((kv) => kv.split('=')),  );  const t = parts.get('t');  const v1 = parts.get('v1');  const expected = crypto    .createHmac('sha256', signingSecret)    .update(`${t}.${rawBody}`) // timestamp, a dot, the exact bytes received    .digest('hex');  if (!t || !v1 || v1.length !== expected.length) return false;  // freshness: reject stale timestamps to block replays  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));}

Nouvelles tentatives et livraison

Répondez en 2xx en quelques secondes pour accuser réception. Les réponses 5xx et les timeouts sont réessayés avec un backoff exponentiel, jusqu'à cinq tentatives ; une réponse 4xx est considérée comme définitive et n'est jamais réessayée. Après plusieurs échecs consécutifs, l'abonnement est automatiquement mis en pause et le propriétaire du foyer en est notifié.