Webhooks
Webhooks sao como Veridia entrega resultados de verificacao ao seu backend no momento que estao prontos. Push, nao poll. Assinados, nao anonimos. Retry, nao best-effort.
Este e o modo recomendado de consumir veredictos em producao.
Por que webhooks ganham do polling
| Aspecto | Polling | Webhooks |
|---|---|---|
| Latencia da completion ao seu codigo | 1-3 segundos (intervalo de poll) | <200ms |
| API calls por verificacao | 3-30 | 1 |
| Confiabilidade se seu servico cai | Voce perde | Tentamos 5 vezes |
| Audit trail | Nenhum | Log completo de delivery no dashboard |
| Custo (sua conta serverless) | Cold start em cada poll | Uma invocacao |
O event handler do widget continua funcionando para feedback UX client-side ("Enviado!"), mas o veredicto deve chegar via webhook.
Setup
- Faca login no seu dashboard Veridia
- Abra Webhooks → Endpoints
- Adicione um novo endpoint:
- URL:
https://seuapp.com/webhooks/veridia(HTTPS obrigatorio em producao) - Events: selecione quais eventos receber (ou "All")
- Description: label interno opcional
- URL:
- Copie o webhook secret — voce vai precisar para verificar assinaturas. E mostrado apenas uma vez.
- Salve
E so isso. A proxima verificacao que completar dispara um POST a sua URL.
O que voce recebe
Cada webhook e uma request POST com:
POST /webhooks/veridia HTTP/1.1
Host: seuapp.com
Content-Type: application/json
Veridia-Signature: t=1714604000,v1=4f8a3b9c...
Veridia-Event: verification.approved
User-Agent: Veridia-Webhooks/1.0
{
"event": "verification.approved",
"verificationId": "vf_AG07CDWRRFQV4T05ZXG2",
"tenantId": "tn_default_demo",
"userRef": "customer-12345",
"verdict": "approved",
"confidence": 87.4,
"scores": {
"ocrConfidence": 78.0,
"faceMatch": 96.2,
"liveness": 91.5,
"docQuality": 85.0
},
"flags": [],
"metadata": {},
"submittedAt": "2026-05-01T18:39:05Z",
"completedAt": "2026-05-01T18:39:08Z"
}
O body e JSON compacto com keys ordenadas alfabeticamente — necessario para verificacao reproduzivel da assinatura.
Tipos de eventos
| Event | Verdict | Quando |
|---|---|---|
verification.approved | approved | Alta confianca, todos os sinais passam |
verification.rejected | rejected | Baixa confianca ou flag critico |
verification.review_required | review | Confianca media, revisao manual recomendada |
Schemas completos: Tipos de eventos.
Obrigatorio: responda 2xx rapido
Seu endpoint deve responder com 2xx dentro de 10 segundos. Esse e o timeout que usamos antes de considerar a delivery falhada.
Se seu handler faz trabalho pesado (writes ao DB, enviar emails, chamar outras APIs), faca apos responder:
// Express
app.post('/webhooks/veridia', async (req, res) => {
// 1. Verificar assinatura (rapido)
if (!verifySignature(req)) {
return res.status(401).send('Assinatura invalida');
}
// 2. Acknowledge imediatamente
res.status(200).send('ok');
// 3. Trabalho pesado acontece apos a resposta
await processVerificationAsync(req.body);
});
Este e o padrao standard para qualquer sistema de webhooks (Stripe, GitHub, etc.).
Politica de retry
Se seu endpoint retorna um status nao-2xx, da timeout, ou e inacessivel, Veridia tenta de novo com backoff exponencial:
| Tentativa | Espera antes de tentar de novo |
|---|---|
| 1 | (imediato) |
| 2 | 1 segundo |
| 3 | 5 segundos |
| 4 | 30 segundos |
| 5 | 2 minutos |
| (final) | 10 minutos |
Apos 5 tentativas falhadas, a delivery e marcada failed no dashboard. Voce pode re-enfileirar manualmente de la.
Uma resposta 4xx (exceto 408 Request Timeout e 429 Too Many Requests) e tratada como falha permanente — nao tentamos de novo, porque tentar de novo nao vai ajudar.
Verificando assinaturas
Sempre verifique o header Veridia-Signature antes de confiar no conteudo do webhook. Caso contrario, um atacante que conhece sua URL poderia forjar eventos.
O formato e:
Veridia-Signature: t=1714604000,v1=4f8a3b9c01ee...
Duas partes:
t=<unix_timestamp>— quando enviamos o webhookv1=<hex_hmac>— HMAC-SHA256 de<timestamp>.<raw_body>usando seu webhook secret
Algoritmo completo + code samples: Verificacao de assinatura.
Idempotencia
Entregamos o mesmo evento no maximo uma vez em condicoes normais, mas durante retries e possivel receber um duplicado. Faca seu handler idempotente:
async function handleWebhook(payload) {
// Use verificationId + event como dedup key
const key = `${payload.verificationId}:${payload.event}`;
if (await wasAlreadyProcessed(key)) {
return; // Ja gerenciado
}
await processVerification(payload);
await markAsProcessed(key);
}
Best practices
- Verifique a assinatura antes de confiar no body. Sempre.
- Responda
2xxdentro de 10 segundos mesmo que voce enfileire o trabalho para depois - Valide que o timestamp esta dentro de 5 minutos (protecao replay)
- Faca seu handler idempotente usando
verificationId + eventcomo dedup key - Logue o
verificationIdem cada webhook — mais facil de rastrear depois - Use HTTPS em producao (entregamos a HTTP apenas em test mode para localhost)
- Whitelist IPs Veridia se voce tem regras de egress (contate o suporte pela lista atual)
Test de webhooks localmente
Webhooks nao podem alcancar localhost diretamente. Use um servico de tunneling:
| Ferramenta | Custo | Notas |
|---|---|---|
| ngrok | Tier gratis disponivel | O mais popular |
| localtunnel | Gratis | Open source |
| Cloudflare Tunnel | Gratis | Melhor para dev production-grade |
Exemplo rapido com ngrok:
ngrok http 3000
# Forwarding https://abc123.ngrok.io -> localhost:3000
# Depois use https://abc123.ngrok.io/webhooks/veridia no seu dashboard
Proximos passos
- Verificacao de assinatura — algoritmo exato com code samples
- Tipos de eventos — schemas completos para cada evento
- Exemplos — implementacoes de handler completas em Node.js, Python, PHP