Saltar al contenido
Explorar la referencia
Volver a la referencia de la API
Guía

Recibir webhooks

Los webhooks te envían eventos en tiempo real en lugar de tener que hacer polling. Suscribe una URL, elige los eventos que te interesan y verifica cada entrega con su firma HMAC.

Suscribirse

Crea una suscripción a través de la API de Webhooks con la URL de tu endpoint y los eventTypes que quieres recibir. Recibirás a cambio un secreto de firma: guárdalo, porque es lo que verifica cada entrega.

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"]}'

Tipos de evento

La lista completa y siempre actualizada de tipos de evento se sirve desde /meta/webhook-events. El catálogo actual es este:

  • transaction.created: se ha registrado una transacción.
  • recurrence.materialised: una recurrencia ha generado su transacción programada.
  • bank.sync.completed: una conexión bancaria ha terminado de sincronizarse.
  • budget.overrun: una categoría se ha pasado de su presupuesto del mes.
  • spending.anomaly: se ha detectado un gasto inusual.
  • goal.reached: un objetivo de ahorro ha llegado a su importe.
  • insight.generated: hay un nuevo análisis de IA disponible.

Verificar la firma

Cada entrega lleva una cabecera X-Vokse-Signature con la forma t=<timestamp>,v1=<firma>. La firma es un HMAC-SHA256, con tu secreto de firma como clave, sobre el timestamp, un punto y el cuerpo crudo de la petición. Reconstruye esa cadena con los bytes exactos que recibiste, recalcula el HMAC, compáralo con v1 en tiempo constante y rechaza los timestamps demasiado antiguos.

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));}

Reintentos y entrega

Responde 2xx en unos pocos segundos para confirmar la recepción. Las respuestas 5xx y los timeouts se reintentan con retroceso exponencial, hasta cinco intentos; un 4xx se considera definitivo y no se reintenta. Tras varios fallos consecutivos, la suscripción se pausa automáticamente y se avisa al propietario del hogar.