Desenvolvedores

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.

HMAC

Assinatura de solicitação SHA-256

Per-webhook segredo, enviado como X-Endorsed-Signature

10s

Tempo limite de entrega

Retorne 2xx dentro da janela ou a tentativa falha

5×

Tentativas após a primeira tentativa

60s, 5m, 15m, 1h, depois 6h

Replay

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 eventoQuando disparaCampos-chave `dados`
document.createdVocê carrega um documento através do APIdocumentId, customerId, externalDocumentId
document.sentLink de assinatura enviado ao primeiro destinatáriodocumentId, customerId, canal
document.viewedSigner abre o link de assinaturadocumentId, signerEmail, visualizadoAt
document.signedO signatário individual conclui sua etapadocumentId, signerEmail, assinadoAt
document.completedTodas as partes assinaramdocumentId, concluídoAt, downloadUrl
document.declinedUm signatário recusa explicitamentedocumentId, signerEmail, motivo
document.expiredDocumento atinge a data de validade sem assinaturadocumentId, expiradoEm
signing.startedO token da sessão de assinatura foi resgatadodocumentId, sessionId, signerEmail
signing.completedA sessão de assinatura termina (assinada ou recusada)documentId, sessionId, resultado
customer.created / .updated / .deletedVocê altera um registro de clientecustomerId, externalCustomerId
template.created / .updatedVocê altera um modelomodelId, 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.

typescript
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. 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. 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. 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. 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.

Histórico de eventos de entrega com entradas do ciclo de vida do documento
Histórico de eventos de entrega — eventos de ciclo de vida assinados com carimbos de data/hora e resultados de status para validação operacional.

Conecte seu primeiro webhook

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