Intercom: como funciona a entrega de webhooks

O Intercom ainda assina com HMAC-SHA1 no x-hub-signature. O formato verificado, o que o provedor não publica e um verificador Node.

Comportamento de entrega

Lido na documentação do próprio provedor, verificado pela última vez em 2026-08-06. Onde o provedor não informa um número, esta tabela também não traz nenhum.

Prazo de respostanão publicado pelo provedor
Novas tentativasnão publicado pelo provedor
Desistenão publicado pelo provedor

Assinatura

Verificada com um verificador funcional, comprovado por uma suíte de testes, e não lida na documentação. Última verificação em 2026-08-20.

AlgoritmoHMAC-SHA1
Payload assinadoraw body
Codificaçãohex
Cabeçalhox-hub-signature = sha1=hex
Tolerâncianenhuma exigida

Verifique a assinatura

O corpo bruto da requisição, byte a byte, antes de qualquer parsing de JSON. Todos os esquemas desta página quebram no momento em que um framework serializa o payload de novo.

const crypto = require("node:crypto");

// x-hub-signature: "sha1=" + hex(HMAC-SHA1(client secret, raw body))
const expected =
  "sha1=" +
  crypto.createHmac("sha1", clientSecret).update(rawBody).digest("hex");
const received = Buffer.from(req.headers["x-hub-signature"] ?? "");
const wanted = Buffer.from(expected);
// timingSafeEqual throws on a length mismatch, so check that first.
const valid =
  received.length === wanted.length && crypto.timingSafeEqual(received, wanted);

Armadilhas

O cabeçalho é x-hub-signature, o original com SHA-1, não o x-hub-signature-256 do GitHub. Um código de detecção automática que compara pelo prefixo precisa conferir o nome inteiro do cabeçalho, ou vai verificar com o algoritmo errado e a codificação errada.

Leia também

O AnyHook fica entre Intercom e seus endpoints: responde em cerca de um segundo, tenta de novo segundo um cronograma próprio quando seu servidor está fora do ar e guarda cada evento disponível para replay. Troque uma URL e mantenha seu código.

Como funciona →