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 resposta | 15 s Configurável. rt (timeout de leitura) padrão 15000 ms (máx. 15000), ct (conexão) padrão 5000 ms (máx. 10000), tt (total) padrão 15000 ms |
|---|---|
| Novas tentativas | Configurável: rc de 0 a 5, padrão 1. rp define quais falhas geram nova tentativa |
| Desiste | não publicado pelo provedor |
| Fonte | https://www.twilio.com/docs/usage/webhooks/webhooks-connection-overrides |
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.
| Algoritmo | HMAC-SHA1 |
|---|---|
| Payload assinado | full URL + form params sorted by key |
| Codificação | base64 |
| Cabeçalho | x-twilio-signature |
| Tolerância | nenhuma 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");
// base64(HMAC-SHA1(auth token, url + form params sorted by key, concatenated))
const sorted = Object.keys(req.body).sort();
const base = fullUrl + sorted.map((k) => k + req.body[k]).join("");
const expected = crypto
.createHmac("sha1", authToken)
.update(base)
.digest("base64");
const received = Buffer.from(req.headers["x-twilio-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);A assinatura cobre a URL pública inteira, com a query string. Uma terminação TLS ou um proxy que reescreve o caminho na frente do handler muda a URL que a Twilio assinou, e a divergência parece exatamente uma requisição forjada.
Armadilhas
Cinco parâmetros de entrega são configuráveis por URL (timeout de conexão, timeout de leitura, tempo total, número de novas tentativas, política de novas tentativas), e os padrões (15 s no total, 1 nova tentativa) são o que quase todo mundo usa. O ajuste existe; ninguém mexe nele.
Leia também
O AnyHook fica entre Twilio 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.