Saltar para o conteúdo
Explorar a referência
Voltar à referência da API
Guia

Receber webhooks

Os webhooks enviam-lhe os eventos em tempo real, em vez de andar a sondar a API. Subscreva um URL, escolha os eventos que lhe interessam e verifique cada entrega com a respetiva assinatura HMAC.

Subscrever

Crie uma subscrição através da API de Webhooks, com o URL do seu endpoint e os eventTypes que quer receber. Em troca, recebe um segredo de assinatura. Guarde-o: é ele que verifica todas as entregas.

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

A lista completa e sempre atual dos tipos de evento é servida em /meta/webhook-events. O catálogo de hoje:

  • transaction.created: foi registado um movimento.
  • recurrence.materialised: um movimento periódico gerou o movimento agendado.
  • bank.sync.completed: uma ligação bancária terminou a sincronização.
  • budget.overrun: uma categoria excedeu o orçamento do mês.
  • spending.anomaly: foi detetado um gasto fora do normal.
  • goal.reached: um objetivo de poupança atingiu a meta.
  • insight.generated: está pronta uma nova análise da IA.

Verificar a assinatura

Cada entrega traz um cabeçalho X-Vokse-Signature no formato t=<timestamp>,v1=<signature>. A assinatura é um HMAC-SHA256 calculado com o seu segredo de assinatura sobre o timestamp, um ponto e o corpo do pedido em bruto. Reconstrua essa string a partir dos bytes exatos que recebeu, volte a calcular o HMAC, compare-o com v1 em tempo constante e rejeite timestamps demasiado antigos.

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

Repetições e entrega

Responda 2xx em poucos segundos para confirmar a receção. As respostas 5xx e os timeouts são repetidos com backoff exponencial, até cinco tentativas; um 4xx é considerado definitivo e nunca é repetido. Ao fim de várias falhas seguidas, a subscrição é suspensa automaticamente e o proprietário do agregado é notificado.