Webhooks
Receba eventos de assinatura em tempo real via HTTP com entregas assinadas por HMAC, novas tentativas automáticas e uma rede de segurança de reprodução do console.
Assinatura de solicitação SHA-256
Per-webhook segredo, enviado como X-Endorsed-Signature
Tempo limite de entrega
Retorne 2xx dentro da janela ou a tentativa falha
Tentativas após a primeira tentativa
60s, 5m, 15m, 1h, depois 6h
No console do desenvolvedor
Inspecione cada tentativa e reproduza eventos individuais
O que você pode fazer com eventos webhook
Cada transição significativa do ciclo de vida emite um evento digitado. Use-os para atualizar seus próprios registros sem fazer pesquisas.
Acionar ações downstream
Quando um envelope estiver totalmente assinado, atualize seu CRM, libere um recurso provisionado ou envie uma confirmação dentro de seu próprio produto — tudo sem consultar o API.
Sincronizar status do documento
Mantenha seu banco de dados sincronizado com o ciclo de vida da assinatura: enviado, aberto, assinado, recusado, expirado, anulado. Um evento por transição, sem necessidade de loop de pesquisa.
Registro de auditoria e conformidade
Alimente eventos webhook em seu próprio armazenamento de auditoria. Os IDs de correlação vinculam cada evento à solicitação API de origem para rastreabilidade total.
Repetir entregas com falha
Eventos que esgotam a escada de novas tentativas chegam a uma fila de mensagens mortas que você pode inspecionar no console do desenvolvedor e reproduzir intencionalmente.
Webhook referência de evento
Registre um webhook, escolha quais eventos você deseja e EndorsedSign entrega uma carga JSON com `event`, `tenantId`, `timestamp` e `data`. Os nomes dos eventos correspondem às strings que você envia na chamada de criação webhook.
| Tipo de evento | Quando dispara | Campos-chave `dados` |
|---|---|---|
| document.created | Você carrega um documento através do API | documentId, customerId, externalDocumentId |
| document.sent | Link de assinatura enviado ao primeiro destinatário | documentId, customerId, canal |
| document.viewed | Signer abre o link de assinatura | documentId, signerEmail, visualizadoAt |
| document.signed | O signatário individual conclui sua etapa | documentId, signerEmail, assinadoAt |
| document.completed | Todas as partes assinaram | documentId, concluídoAt, downloadUrl |
| document.declined | Um signatário recusa explicitamente | documentId, signerEmail, motivo |
| document.expired | Documento atinge a data de validade sem assinatura | documentId, expiradoEm |
| signing.started | O token da sessão de assinatura foi resgatado | documentId, sessionId, signerEmail |
| signing.completed | A sessão de assinatura termina (assinada ou recusada) | documentId, sessionId, resultado |
| customer.created / .updated / .deleted | Você altera um registro de cliente | customerId, externalCustomerId |
| template.created / .updated | Você altera um modelo | modelId, nome |
A lista completa está no backend `WEBHOOK_EVENTS`. Adicione ou restrinja assinaturas por webhook — o pipeline de entrega distribui uma chamada HTTP por endpoint registrado.
Verificando assinaturas webhook (Node.js)
Cada entrega inclui um cabeçalho `X-Endorsed-Signature`: `t={unix_seconds},v1={hex}`. `v1` é HMAC-SHA256 de `{timestamp}.{rawBody}` usando o segredo retornado quando o webhook foi criado. Rejeite carimbos de data/hora fora de ±5 minutos. `X-Webhook-Signature` ainda pode aparecer nas entregas de teste do portal do desenvolvedor como um alias obsoleto apenas para o corpo — verifique `X-Endorsed-Signature`. Pré-requisitos: seu segredo webhook em um env var, uma rota Express que mantém o corpo bruto. Resultado esperado: cargas úteis não reconhecidas ou adulteradas são rejeitadas com 401 antes de qualquer manipulador ser executado.
import crypto from 'node:crypto';
import express from 'express';
const WEBHOOK_SECRET = process.env.ENDORSED_WEBHOOK_SECRET!;
const TOLERANCE_SECONDS = 5 * 60;
export function verifyWebhookSignature(
rawBody: string,
header: string | undefined,
nowSeconds = Math.floor(Date.now() / 1000),
): boolean {
if (!header) return false;
let timestamp: number | null = null;
let v1 = '';
for (const part of header.split(',')) {
const eq = part.indexOf('=');
if (eq === -1) continue;
const key = part.slice(0, eq).trim();
const value = part.slice(eq + 1).trim();
if (key === 't' && /^\d+$/.test(value)) timestamp = Number.parseInt(value, 10);
if (key === 'v1' && /^[a-f0-9]{64}$/i.test(value)) v1 = value.toLowerCase();
}
if (timestamp === null || !v1) return false;
if (Math.abs(nowSeconds - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(timestamp + '.' + rawBody)
.digest('hex');
const a = Buffer.from(expected, 'hex');
const b = Buffer.from(v1, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post(
'/webhooks/endorsed',
express.json({ verify: (req, _res, buf) => { (req as any).rawBody = buf.toString('utf8'); } }),
(req, res) => {
const sig = req.header('X-Endorsed-Signature');
if (!verifyWebhookSignature((req as any).rawBody, sig)) {
return res.status(401).send('Invalid signature');
}
res.sendStatus(200);
},
);Retorne 2xx dentro de 30s ou a entrega será marcada como falha. As tentativas fracassadas tentam novamente com a escada acima e permanecem reproduzíveis no console do desenvolvedor.
Como configurar um endpoint webhook
- 1
Crie o endpoint em seu aplicativo
Adicione uma rota que aceite solicitações POST e retorne HTTP 200 em 10 segundos. Qualquer resposta 2xx conta como entrega bem-sucedida.
- 2
Registre o endpoint nas configurações do seu locatário
Vá para Admin → Configurações → Webhooks. Insira o URL do seu endpoint e selecione os tipos de eventos desejados. Um segredo de assinatura é gerado por endpoint.
- 3
Verifique a assinatura em cada solicitação
Leia `X-Endorsed-Signature`. Recalcular HMAC-SHA256 sobre `{timestamp}.{rawBody}` e comparação de tempo constante com `v1` (veja o exemplo de código acima). Rejeite um cabeçalho ausente, um valor hexadecimal inválido, um carimbo de data/hora fora de ±5 minutos ou uma incompatibilidade de HMAC. `X-Webhook-Signature` é um alias obsoleto em algumas entregas de teste — não o trate como um contrato ativo.
- 4
Retorna 2xx rapidamente, processa assíncrono
Reconhecer a entrega com 200 em 10 segundos e enfileirar o corpo do evento para processamento assíncrono. O console do desenvolvedor mostra todas as tentativas (cabeçalhos, corpo, status, tempo) e permite reproduzir qualquer entrega — não há necessidade de reativar o fluxo de assinatura de origem apenas para testar seu manipulador.
Perguntas comuns
Uma carga útil webhook real — documento concluído
Quando todas as partes tiverem assinado, EndorsedSign POSTs esta carga útil para seu endpoint registrado. Verifique a assinatura HMAC, enfileire e confirme com 200.

Conecte seu primeiro webhook
Solicite um sandbox, registre o endpoint em Admin → Desenvolvedor → Webhooks e inspecione ou reproduza cada entrega no console do desenvolvedor.