GET e POST são verificações diferentes
GET: usado pela Meta para confirmar que você controla a URL. O endpoint deve devolver exatamente o valor de hub.challenge quando o verify token for válido.
POST: usado para entregar mensagens, status e eventos. O endpoint deve aceitar JSON e responder rapidamente com HTTP 2xx.
Conexão inicial com webhook próprio: política 3 × 5
Quando o assinante informa uma URL própria durante uma nova conexão, falhas relacionadas ao callback não ficam sendo repetidas por vários minutos.
Tentativas máximas
A validação é encerrada depois da terceira falha relacionada ao callback.
Intervalo mínimo
O job é reagendado com pelo menos cinco segundos entre as tentativas.
Timeout por chamada
A chamada de validação do callback tem timeout de dez segundos nesse fluxo.
Requisitos da URL antes do onboarding
- use uma URL HTTPS completa, pública e sem credenciais embutidas;
- não use
localhost, hostname interno, IP privado ou domínio reservado; - publique a rota antes de abrir o Embedded Signup;
- libere o GET de verificação de login, firewall e Cloudflare Access;
- valide o verify token no código e devolva apenas
hub.challenge; - mantenha DNS público e certificado TLS válidos;
- aceite POSTs e responda rapidamente com HTTP 2xx.
Fluxo completo
- A Meta chama a URL por GET.
- Seu servidor valida
hub.verify_token. - Seu servidor devolve somente
hub.challenge. - O Flow aplica a rota no nível seguro para a conexão.
- O Flow relê a configuração do Phone Number ID.
- A Meta entrega eventos por POST.
- Seu sistema responde 2xx e processa de forma assíncrona.
Entrega direta da Meta ao seu endpoint
Com a rota própria confirmada, a Meta entrega os eventos operacionais compatíveis diretamente ao webhook configurado. A HookCloud aplica e verifica a rota, mas não atua como proxy do conteúdo normal das conversas.
Meta WhatsApp Cloud API
↓
Seu webhook HTTPS
↓
Seu CRM, n8n, Make ou backend
Eventos administrativos que não aceitam override podem continuar no callback do aplicativo HookCloud para observabilidade. Para arquitetura completa, assinatura, retries, Click-to-WhatsApp, BSUID e envio pela Graph API, consulte CRM próprio e integração técnica →
Exemplo Node.js / Express
app.get('/webhook', (req, res) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
if (mode === 'subscribe' && token === process.env.VERIFY_TOKEN) {
return res.status(200).send(String(challenge));
}
return res.sendStatus(403);
});
app.post('/webhook', express.json({ limit: '2mb' }), (req, res) => {
res.sendStatus(200); // confirme primeiro
queueWebhook(req.body); // processe depois
});
Assinatura, corpo bruto e idempotência
- O corpo e os headers operacionais chegam diretamente da Meta, sem transformação da HookCloud.
- Capture o corpo bruto antes do parse caso utilize
X-Hub-Signature-256. - O verify token protege o GET, não substitui a assinatura do POST.
- O App Secret da HookCloud não é compartilhado; portanto, a validação HMAC independente não é oferecida no modo direto.
- Responda HTTP 2xx rapidamente e use
messages[].idpara idempotência.
Usernames, BSUID e telefone opcional
Seu webhook não deve depender somente de from ou wa_id. Em cenários compatíveis com usernames, a Meta pode fornecer um BSUID mesmo quando o telefone não estiver presente.
contacts[].user_id ou messages[].from_user_id, conforme o payload recebido.
from ou wa_id estão ausentes.
user_id_update estiver disponível e assinado, reconcilie o identificador antigo e o novo.
Botões relacionados ao webhook
| Botão | O que faz | Quando usar |
|---|---|---|
| Alterar webhook | Enfileira mudança da conexão exata, aplica no Phone Number ID, faz readback e só então grava o novo endpoint. | Quando o sistema de destino mudou. |
| Validar rota | Consulta a configuração remota sem escrever. | Diagnóstico; não corrige divergência. |
| Reaplicar webhook | Escreve novamente a rota configurada e verifica. | Somente quando a validação indicar divergência. |
| Log da conexão | Mostra fila, processamento, sucesso/falha e código de suporte. | Sempre que uma ação não terminar como esperado. |
Teste de alcance da CláudIA
Quando a dúvida do atendimento privado é sobre callback, a CláudIA pode fazer um teste controlado e somente leitura da URL pública associada à conexão.
hub.challenge, não confere a assinatura do POST e não altera a rota na Meta. Para validação completa, use o fluxo próprio do painel e faça um teste real de evento.Trocar o webhook com segurança
Tempo de operação e cronômetro
Na conexão inicial por webhook próprio, o painel mostra uma estimativa regressiva de aproximadamente 00:45 e informa que serão feitas no máximo três tentativas, com intervalo mínimo de cinco segundos. A duração real pode ganhar alguns segundos conforme a frequência do worker e o tempo de resposta da Meta.
Alteração de webhook, verificação de Chatwoot, transferência e desconexão continuam usando seus próprios fluxos e estimativas.
Limpeza segura da tentativa incompleta
| Situação | Comportamento do Flow | Próximo passo |
|---|---|---|
| Falha determinística antes de qualquer rota confirmada | Encerra na terceira tentativa, remove a conexão provisória e os registros criados apenas para aquele onboarding. | Corrija a URL e inicie uma nova conexão. |
| Reconexão com estado anterior válido | Restaura a conexão, endpoint e credencial anteriores quando aplicável. | Confira o card antes de repetir. |
| Timeout após possível escrita ou readback divergente | Para as tentativas, mas preserva o estado para não apagar uma rota possivelmente aplicada pela Meta. | Atualize o painel, valide a rota e só depois decida se deve tentar novamente. |
Alteração durante transferência/onboarding
Se a conexão estiver sendo transferida ou ainda não tiver WABA acessível, o Flow mantém a operação em espera ou encerra com orientação de reconexão. Não força uma escrita remota incerta. O log deve indicar Aguardando conclusão da conexão com a Meta ou Refaça a conexão.
Erros comuns do callback próprio
| Erro/sintoma | Possível motivo | Como corrigir |
|---|---|---|
| URL ausente ou inválida | Campo vazio, formato incorreto ou uso de HTTP. | Informe a URL HTTPS completa e pública. |
| Domínio privado/reservado |
localhost, rede interna, IP privado ou hostname não público. |
Publique o endpoint em um domínio acessível pela internet. |
| DNS não encontrado | Domínio inexistente, sem A/CNAME público ou propagação incompleta. | Corrija o DNS e aguarde a propagação. |
| HTTP 401/403 | Login, Basic Auth, firewall ou Cloudflare Access bloqueando a Meta. | Libere o GET de verificação e valide o token no próprio código. |
| HTTP 404 | Caminho incorreto ou rota ainda não publicada. | Confira a URL completa e publique o endpoint. |
| HTTP 5xx | Erro interno, função indisponível ou gateway com falha. | Revise logs e disponibilidade do servidor. |
| Erro de TLS | Certificado inválido, expirado ou cadeia incompleta. | Corrija o HTTPS e teste a cadeia do certificado. |
| Timeout | O GET demorou demais ou iniciou processamento pesado. | Responda rapidamente ao challenge e processe o restante depois. |
| Challenge incorreto | O endpoint devolveu JSON, HTML ou texto extra. | Retorne exatamente o valor de hub.challenge. |
| Rota não confirmada no readback | A escrita pode ter sido aceita, mas a Meta não confirmou a configuração lida. | Atualize o painel e valide a rota antes de repetir. |
| Indisponibilidade da Meta | Timeout ou falha de transporte entre HookCloud e Meta. | Atualize o painel e confira o estado antes de nova tentativa. |
Webhook próprio x entrega externa gerenciada
| Modo | Rota esperada | Ações |
|---|---|---|
| Webhook próprio | A URL salva pelo assinante deve corresponder ao readback do Phone Number ID. | Validar e reaplicar podem ser usados. |
| Chatwoot / plataforma externa | O callback da inbox deve ser confirmado na rota efetiva do número. | Verificar Chatwoot apenas lê; Configurar caixa existente aplica URL + verify token quando necessário. |
- A verificação manual faz uma leitura; a automática tenta no máximo três vezes.
- A verificação passiva não bloqueia Configurar caixa existente, Usar webhook próprio ou Desconectar.
- Uma URL própria antiga não é aceita como Chatwoot apenas por ser externa.
- O webhook global da HookCloud é fallback do App, não o webhook personalizado do cliente.
Trocar Chatwoot por webhook próprio
- Pare envios e automações da inbox antiga; preserve a caixa se precisar manter o histórico.
- No card do Flow, clique Usar webhook próprio.
- Informe a URL e aguarde o readback terminal.
- Faça um teste real de POST e confirme que apenas o destino novo recebe as mensagens.
Envie o e-mail do owner, Workspace ID, Connection ID, horário aproximado e o código de suporte exibido no painel para suporte@hookcloud.app. Nunca envie o token completo.