Webhooks
Webhooks permitem que sua aplicação receba notificações em tempo real quando eventos ocorrem na plataforma Topo Contábil, como aprovação de conciliações ou conclusão de importações.
Como funciona
Quando um evento ocorre, a Topo Contábil envia uma requisição HTTP POST para a URL configurada no webhook, contendo os dados do evento no corpo da requisição. Sua aplicação deve responder com status 200 OK em até 10 segundos.
Eventos disponíveis
| Evento | Descrição |
|---|---|
reconciliation.created | Conciliação foi criada |
reconciliation.approved | Conciliação foi aprovada |
reconciliation.rejected | Conciliação foi rejeitada |
import.completed | Importação foi concluída com sucesso |
import.failed | Importação falhou durante o processamento |
webhook.delivered | Webhook foi entregue com sucesso |
webhook.failed | Entrega do webhook falhou após todas as tentativas |
Registrar um webhook
Para registrar um webhook, envie uma requisição POST para /v1/webhooks informando a URL de destino e os eventos que deseja receber.
curl -X POST https://api.topocontabil.com.br/v1/webhooks \
-H "Authorization: Bearer SUA_CHAVE_API" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"url": "https://sua-app.com/webhooks/topo",
"events": [
"reconciliation.approved",
"reconciliation.rejected",
"import.completed",
"import.failed"
]
}'Formato do payload
Cada entrega de webhook inclui os seguintes headers e corpo:
{
"Content-Type": "application/json",
"X-Topo-Signature": "sha256=a1b2c3d4...",
"X-Topo-Event": "reconciliation.approved",
"X-Topo-Delivery-Id": "550e8400-e29b-41d4-a716-446655440000"
}{
"id": "evt_a1b2c3d4",
"type": "reconciliation.approved",
"createdAt": "2026-01-20T14:30:00Z",
"data": {
"reconciliationId": "550e8400-e29b-41d4-a716-446655440000",
"accountCode": "1.1.01.001",
"accountName": "Caixa e Equivalentes",
"period": "2026-01",
"status": "approved",
"approvedBy": "Maria Silva",
"approvedAt": "2026-01-20T14:30:00Z"
}
}Validar assinatura
Cada requisição de webhook inclui o header X-Topo-Signature com uma assinatura HMAC-SHA256 do corpo da requisição, usando o secret do webhook como chave. Sempre valide a assinatura antes de processar o payload.
import crypto from "crypto";
function validateSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
const sig = signature.replace("sha256=", "");
return crypto.timingSafeEqual(
Buffer.from(sig, "hex"),
Buffer.from(expected, "hex")
);
}
// No handler do webhook:
app.post("/webhooks/topo", (req, res) => {
const signature = req.headers["x-topo-signature"];
const isValid = validateSignature(
JSON.stringify(req.body),
signature,
process.env.TOPO_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send("Assinatura invalida");
}
// Processar evento...
const { type, data } = req.body;
console.log("Evento recebido:", type, data);
res.status(200).send("OK");
});Use timingSafeEqual
crypto.timingSafeEqual ao comparar assinaturas para prevenir ataques de timing. Nunca compare strings diretamente com ===.Política de retentativas
Se o endpoint não responder com status 2xx em até 10 segundos, a Topo Contábil retentar a entrega com backoff exponencial:
- 1a tentativa: imediata
- 2a tentativa: após 1 minuto
- 3a tentativa: após 5 minutos
- 4a tentativa: após 30 minutos
- 5a tentativa: após 2 horas
Após 5 tentativas sem sucesso, o evento e marcado como failed e um evento webhook.failed e emitido. O webhook e desativado automaticamente após 3 falhas consecutivas.
Monitoramento
GET /v1/events para verificar o status de entregas de webhooks e diagnosticar problemas de integração.