Configuração inicial do webhook
Prepare o endereço do seu sistema que receberá os eventos dos números conectados. Faça esta configuração uma vez para o parceiro, antes de cadastrar clientes, criar instâncias ou gerar sessões de conexão WhatsApp.
Antes do webhook: conclua o cadastro obrigatório
Na contratação, escolha o pacote e informe seu e-mail; cadastre o cartão na Stripe para iniciar o trial de três dias. Ao acessar o Portal, o proprietário deve completar seu cadastro antes de abrir os recursos operacionais, inclusive Endpoints. Pessoa física informa nome completo, celular e CPF. Pessoa jurídica informa razão social, CNPJ, nome completo do responsável e celular.
O sistema valida formato e dígitos verificadores de CPF/CNPJ, inclusive CNPJ alfanumérico. Não consulta a Receita Federal, não confirma titularidade, existência do documento ou situação ativa da empresa e não verifica o celular por SMS. O cadastro é declarado pelo proprietário e poderá ser conferido manualmente pela HookCloud. Um número matematicamente válido não constitui prova de identidade.
Enquanto essa etapa estiver pendente, as rotas operacionais retornam 409 partner_registration_required. Consulte get-partner-onboarding-status; registration_complete=false orienta o proprietário a concluir o cadastro no Portal. Uma Partner API Key não pode enviar ou alterar esse cadastro. Não confunda os dados do contratante com os clientes que ele atenderá: o endpoint upsert-partner-customer não conclui esta etapa.
O trial continua correndo durante o cadastro e a configuração. Após concluir os dados, siga o GET abaixo. Como tratamos os dados cadastrais · Referência oficial do formato CNPJ alfanumérico.
1. Prepare o destino antes de conectar clientes
O cadastro e a validação do endpoint fazem parte da preparação da integração. Antes de cadastrar clientes, criar instâncias ou gerar novas sessões, a HookCloud exige a URL primária habilitada e uma validação GET salva para ela. O acesso ao Portal permite preparar essa etapa após a confirmação da contratação e a conclusão do cadastro obrigatório do proprietário. Testar sem salvar, ter uma URL cadastrada ou apenas um token configurado não libera os novos cadastros.
- URL pública com HTTPS e certificado válido, acessível na porta padrão 443.
- Rota GET para verificar a URL e rota POST para receber eventos, no mesmo caminho.
- Token de verificação idêntico no formulário do Portal ou chamada API e no servidor do seu sistema. Você pode aceitar o valor sugerido ou informar o segredo que já configurou.
- Receptor POST com validação de assinatura, armazenamento durável e tratamento de repetição.
Use um endereço definitivo, sem redirecionamento para login, outra rota ou outro domínio. A verificação não segue redirects e não usa uma sessão do navegador. Não use localhost, IP privado ou credenciais embutidas na URL.
2. Configure o mesmo token no seu backend
No Portal, abra Endpoints → Cadastrar e validar webhook (ou Configurar / revalidar webhook) e copie o Meta Verify Token mostrado. O campo é editável: copie o valor sugerido para seu servidor ou informe o token que seu servidor já aceita. Configure esse token no backend do seu sistema; o exemplo usa META_VERIFY_TOKEN. Depois volte ao Portal para testar e aplicar a URL.
Se fizer o cadastro diretamente pela API, também pode escolher um segredo aleatório e enviar esse mesmo valor em meta_verify_token. Não misture os dois caminhos com tokens diferentes. Maiúsculas, minúsculas e espaços fazem diferença; não deixe o valor vazio.
| Credencial | Para que serve |
|---|---|
meta_verify_token | Comparar o desafio GET e confirmar que você controla a rota. É o mesmo valor aceito pelo seu backend. |
| Partner API Key | Autenticar chamadas do seu backend para a API da HookCloud. Não é o token do desafio GET. |
| Meta Access Token | Autorizar chamadas do seu backend à Graph API para a instância. |
webhook_secret | Validar a assinatura dos eventos POST enviados pela HookCloud. Não substitui o token de verificação GET; é fornecido separadamente no provisionamento. |
Evite registrar hub.verify_token em logs públicos ou colocar credenciais no frontend. O GET de consulta da configuração não revela o token; guarde-o de maneira segura durante o cadastro.
3. Implemente o GET de verificação
O exemplo abaixo cria um servidor Express mínimo, com somente a verificação GET. Se seu projeto já possui app e listen, reutilize o aplicativo existente e adicione apenas a rota, sem iniciar outro servidor. Ajuste o caminho se a URL escolhida for diferente. O exemplo é uma adaptação para a integração HookCloud do mecanismo documentado pela Meta, com validação de configuração e parâmetros; não é uma reprodução literal de todo o aplicativo de exemplo oficial.
Executar o exemplo em um projeto Node.js
- Em um projeto do seu backend, instale a dependência com
npm install express. - Salve o código abaixo em
webhook.mjs. - Crie um arquivo
.envsomente no servidor comMETA_VERIFY_TOKENigual ao valor copiado do Portal. Não publique nem envie esse arquivo ao repositório. - Com uma versão de Node.js que aceite
--env-file, executenode --env-file=.env webhook.mjs. Se seu provedor já injeta as variáveis de ambiente, bastanode webhook.mjs. - Publique a rota por HTTPS no domínio escolhido. Rodar na porta local 3000 não torna a URL pública nem configura o certificado.
META_VERIFY_TOKEN=COLE_O_TOKEN_EXIBIDO_NO_PORTAL
PORT=3000import express from 'express';
const app = express();
const verifyToken = process.env.META_VERIFY_TOKEN;
// Copie o Meta Verify Token exibido em Endpoints no Portal HookCloud.
// Configure esse valor somente no servidor do seu sistema.
if (!verifyToken) {
throw new Error('Configure META_VERIFY_TOKEN antes de iniciar o servidor.');
}
app.get('/webhooks/whatsapp', (req, res) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
if (
mode === 'subscribe' &&
typeof token === 'string' &&
token === verifyToken &&
typeof challenge === 'string' &&
challenge.length > 0
) {
return res.status(200).type('text/plain').send(challenge);
}
return res.sendStatus(403);
});
app.listen(process.env.PORT || 3000);O exemplo só aceita um valor textual por parâmetro, rejeita token ausente ou inválido e devolve o challenge como texto puro. Parâmetros duplicados, arrays ou objetos não devem ser aceitos como se fossem um único token. A configuração ausente no servidor também não deve validar uma solicitação.
| Query parameter | Recebido | O que seu servidor faz |
|---|---|---|
hub.mode | subscribe | Confirma que é um desafio de assinatura. |
hub.verify_token | Valor informado no cadastro | Compara com o segredo configurado no backend. |
hub.challenge | 1234 no teste inicial HookCloud; outros valores nos desafios da Meta | Retorna exatamente esse texto no corpo da resposta HTTP 200, com Content-Type text/plain. Nunca fixe a resposta em 1234 no seu código. |
4. Teste a sua URL
Com a rota publicada, faça uma chamada de teste. Substitua o domínio e o token fictício pelos seus valores. Este teste confirma o comportamento do GET; não registra o endpoint na HookCloud e não testa o processamento dos eventos POST.
curl --get 'https://api.seusistema.com/webhooks/whatsapp' \
--data-urlencode 'hub.mode=subscribe' \
--data-urlencode 'hub.verify_token=TOKEN_DE_VERIFICACAO_FICTICIO' \
--data-urlencode 'hub.challenge=1234'Resultado esperado: HTTP 200, Content-Type: text/plain e corpo 1234. Faça também uma chamada com token incorreto: ela deve ser recusada. Não transforme qualquer requisição em sucesso apenas para passar na validação.
5. Valide e salve o endpoint na HookCloud
No Portal, em Endpoints → Cadastrar e validar webhook (ou Configurar / revalidar webhook), informe a URL HTTPS e um motivo para a configuração (de 3 a 500 caracteres no formulário do Portal). Confirme que seu backend aceita o Meta Verify Token copiado da tela, use Testar GET e depois Validar e salvar. Você pode ajustar o token no formulário; ele precisa corresponder exatamente ao valor aceito pelo seu servidor. Depois confira o destino salvo.
Se preferir configurar pelo backend, use estas rotas da Partner API com sua autenticação e permissão webhook.write; alterações pelo login do Portal exigem perfil owner ou admin.
5.1. Testar sem salvar
validate-partner-webhook-endpoint envia um GET real ao seu endereço. Uma resposta bem-sucedida confirma o desafio, mas não salva a configuração.
{
"route": "validate-partner-webhook-endpoint",
"webhook_url": "https://api.seusistema.com/webhooks/whatsapp",
"meta_verify_token": "TOKEN_DE_VERIFICACAO_FICTICIO"
}Confira verification.challenge_verified=true. Se a API retornar um meta_verify_token, preserve esse valor para salvar. Neste passo a passo, informe o token explicitamente para que ele corresponda ao já configurado no seu servidor.
5.2. Salvar a configuração validada
update-partner-webhook-endpoint valida novamente o GET e salva a configuração. O campo reason registra uma justificativa de 3 a 1000 caracteres.
{
"route": "update-partner-webhook-endpoint",
"webhook_url": "https://api.seusistema.com/webhooks/whatsapp",
"meta_verify_token": "TOKEN_DE_VERIFICACAO_FICTICIO",
"reason": "Configuração inicial do webhook do sistema"
}As duas chamadas usam https://api.hookcloud.app/functions/v1/swift-worker, cabeçalhos apikey: SUA_CHAVE_PUBLICA_DO_AMBIENTE, Authorization: Bearer SUA_PARTNER_API_KEY e Content-Type: application/json. A chave pública do ambiente (Publishable Key) e a Partner API Key são valores diferentes: copie cada um do ambiente correto, sem trocar seus cabeçalhos. O body acima contém o seletor route. Confira os exemplos completos na referência de endpoints.
5.3. Confirmar a liberação dos cadastros
Consulte get-partner-onboarding-status com permissão webhook.read. A resposta informa checkout_confirmed, registration_required, registration_complete, webhook_validated, can_create_customer e can_create_instance. Somente habilite a criação quando a permissão correspondente for true. Em falha de leitura, mantenha a criação bloqueada e permita repetir a consulta. Contas já habilitadas são reconhecidas pelo servidor; não peça outro cartão por suposição.
Uma tentativa prematura retorna 409 partner_webhook_verification_required. Prepare GET e POST, valide e salve o endpoint, e consulte novamente. O código deve ecoar qualquer desafio válido, embora a HookCloud use 1234 neste teste.
5.4. Conferir o destino persistido
Use get-partner-webhook-endpoint, com permissão webhook.read. Confira endpoint.url, enabled, is_primary e o estado da migração. endpoint=null significa que o destino ainda não foi cadastrado. meta_verify_token_configured=true confirma que existe um token salvo; não revela seu valor nem prova o processamento de POSTs.
Se já houver números conectados, mudar URL ou token pode iniciar uma migração dos callbacks. HTTP 202 e migration_status=pending não significam que todos os números já trocaram de destino. Acompanhe get-partner-webhook-migration antes de desligar a URL anterior. Não envie várias trocas em paralelo.
6. Prepare também o POST de eventos
A mesma URL precisa receber os POSTs. O GET valida o endereço; o POST traz mensagens, status e mudanças operacionais. Passar no desafio não garante que seu sistema esteja processando ou armazenando os eventos.
- Capture o corpo bruto antes de transformar o JSON, para validar a assinatura correta da origem.
- Confirme a autenticidade pelo mecanismo adequado à origem. Eventos HookCloud usam o segredo HMAC fornecido separadamente e timestamp. Para eventos diretos da Meta, combine com a HookCloud o mecanismo de autenticação disponível para sua integração antes de aceitar o conteúdo como confiável.
- Persista ou enfileire o evento de forma durável antes de responder HTTP 2xx.
- Processe o conteúdo com deduplicação e retentativas controladas, sem pressupor ordem ou entrega única.
- Associe o evento ao cliente correto. Para mensagens Meta, use o
metadata.phone_number_id; eventos de WABA podem não ter esse campo. Eventos HookCloud usam os identificadores descritos no respectivo contrato.
Itere sobre todos os itens de entry[] e changes[] e sobre as listas de mensagens/status presentes; não processe apenas a primeira posição. Não use BSUID ou o telefone do destinatário como se fosse o ID do número comercial.
Ver contratos de POST, assinaturas e eventos →
Consulte também o catálogo de campos Meta: finalidade, payload, assinatura registrada no app e caminho de entrega de cada campo. A assinatura no app não confirma encaminhamento bruto ao seu endpoint nem habilitação do recurso.
Na configuração dos eventos HookCloud, o endpoint deve estar habilitado e receber os nomes desejados em subscribed_events ou *. Isso é diferente dos campos assinados no app da Meta. Não reconfigure o app Meta da HookCloud para cada cliente final.
7. Inicie as conexões e confirme a operação
Com o endpoint preparado e salvo, siga o Quickstart: cadastre o cliente, crie a instância, abra o link Connect e consulte o estado confirmado. A HookCloud aplica o destino à conexão autorizada; seu sistema usa os IDs retornados para relacionar cada evento ao cliente correto.
- GET válido retorna o challenge e token incorreto é recusado.
- URL/token foram salvos; não apenas testados.
- Endpoint aparece habilitado na consulta e nenhuma migração está pendente de conclusão.
- POST tem assinatura validada e evento persistido antes do 2xx.
- O cliente concluiu a conexão e a saúde da conexão foi conferida.
- Um evento real foi recebido e associado ao número/cliente correto.
Mensagens e status operacionais chegam ao seu receptor. Para alimentar os indicadores da HookCloud, seu backend pode reportar os status normalizados conforme o guia de Saúde de Entregas. A HookCloud não assume o processamento interno do seu sistema.
Quando a validação falhar
| Sintoma | O que conferir |
|---|---|
| 403 no desafio | Mesmo token no backend e no cadastro; hub.mode=subscribe; parâmetros únicos em formato texto. |
| 200, mas validação recusada | O corpo deve ser somente o challenge. Remova JSON, HTML, aspas e conteúdo adicional. |
| 404 ou 405 | O caminho publicado deve corresponder à URL cadastrada e aceitar GET, além de POST. |
| 301, 302 ou página de login | Use a URL HTTPS final, sem redirect e sem autenticação por sessão. Preserve a verificação própria do token. |
| Timeout ou erro de certificado | Certificado válido, DNS público, porta 443 e resposta em até 10 segundos. Revise firewall/proxy sem desabilitar segurança globalmente. |
| Teste passou, mas endpoint ausente | A validação não salva. Execute update-partner-webhook-endpoint ou conclua o salvamento no Portal. |
| GET passou, mas eventos não aparecem | Confira POST, assinatura, persistência, seleção de eventos, conexão e eventual migração pendente. Não use o sucesso do GET como prova de entrega. |
Ao pedir suporte, informe URL sem credenciais, horário, status HTTP, request_id e, se houver, ID da migração. Não compartilhe tokens, segredo HMAC ou conteúdo pessoal das mensagens.
Produção e homologação
A base da API usada nos exemplos desta publicação é https://api.hookcloud.app. Escolha o ambiente correto no Portal e utilize a chave pública e a Partner API Key emitidas para ele. Mantenha URLs e tokens separados para os seus receptores de teste e produção. Stage e produção não compartilham o cadastro do endpoint: configurar um ambiente não configura automaticamente o outro.
Referências oficiais e próximos passos
O mecanismo de verificação segue a documentação da Meta; o cadastro do endpoint global, as permissões e a migração seguem os contratos da HookCloud.
- Meta — Criar um endpoint de webhook (solicitações GET e POST) ↗
- Exemplo oficial Meta em Express — verificação GET, linhas 110–119 ↗
Webhooks e eventos POST · Quickstart · Chamadas para configurar endpoints
