Ferramentas

Webhooks

O jeito certo de receber resultados: nós avisamos você, assinado e com retry — em vez de você gastar requisições perguntando.

Eventos

EventoDispara quando
analysis.completedAnálise concluída com sucesso (payload = resultado completo)
analysis.failedMotor não conseguiu processar (payload traz error.code e hint)
units.lowSaldo cruzou o limiar configurado
consent.revokedTitular revogou consentimento via plataforma — pare de usar os dados dele

Entrega e retries

Verifique a assinatura (sempre)

Todo webhook leva X-AOS-Signature: HMAC-SHA256 do corpo bruto com o seu webhook_secret (painel), no formato t=<timestamp>,v1=<hex>. Rejeite assinaturas inválidas ou com timestamp além de 5 minutos:

import crypto from 'node:crypto';

function verify(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(',').map(p => p.split('=')));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = crypto.createHmac('sha256', secret)
    .update(`${t}.${rawBody}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}
import hmac, hashlib, time

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split("=") for p in header.split(","))
    if abs(time.time() - int(parts["t"])) > 300:
        return False
    expected = hmac.new(secret.encode(),
                        f"{parts['t']}.".encode() + raw_body,
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(parts["v1"], expected)

Payload de exemplo

json · analysis.completed
{
  "event_id": "evt_9q1Xw3",
  "type": "analysis.completed",
  "created_at": "2026-10-01T18:22:41Z",
  "data": {
    "analysis_id": "ana_7Kp2mQ",
    "status": "succeeded",
    "overall": { "score": 71, "confidence": 0.92 },
    "dimensions": [ "…resultado completo, idêntico ao GET…" ],
    "metadata": { "pedido": "123" }
  }
}

Testando localmente

No sandbox, dispare entregas de teste sem criar análises reais:

curl
curl -X POST https://api.nutoken.com.br/v1/webhooks/test \
  -H "Authorization: Bearer sk_test_..." \
  -d '{"type":"analysis.completed","url":"https://seu-tunel.ngrok.app/hooks"}'