POST que a Cativa envia para uma URL sua toda vez que um evento acontece no tenant (um usuário se cadastra, um pagamento é confirmado, um post é publicado). Em vez de você ficar consultando a API de tempos em tempos, a Cativa avisa você no instante do evento.
Aqui você encontra: como cadastrar o listener, a lista de eventos, como verificar a assinatura, e como lidar com retries e duplicatas.
Um evento por listener. Cada cadastro escuta um nome de evento (ex:
user_created). Para escutar vários eventos, crie vários listeners, apontando todos para a mesma URL se quiser. Cada listener tem o seu próprio secret.Duas formas de cadastrar
Pelo Console
Interface visual, sem código. Ideal para configurar rápido e revelar o secret na tela.
Pela API de gestão
Programático e versionável. Ideal para provisionar listeners em escala ou via infraestrutura como código.
Cadastrar pelo Console
No painel Cativa, abra Console > Webhooks e clique em Adicionar listener. O fluxo pede 3 informações:- URL, o endpoint público do seu app que vai receber o
POST(ex:https://meuapp.com/webhooks/cativa). - Evento, o nome do evento que você quer escutar (snake_case, ex:
user_received_badge). - Secret, gerado automaticamente. Após criar o listener, abra-o e clique em Reveal secret para copiar o valor (formato
whsec_+ 64 caracteres hex). O secret só pode ser visualizado pelo admin do tenant. Guarde com segurança no seu cofre de credenciais.
Cadastrar pela API de gestão
Os endpoints de gestão de webhook ficam sob o recursoadmin/integration/{customerId}/webhooks. O {customerId} é o ID do seu tenant.
- Base URL:
https://apis.cativalab.digital/tenant/api/v2 - Autenticação: header
Authorization: Bearer YOUR_API_KEY(a API key começa comcativa_).
1
Crie a assinatura (e guarde o secret)
Faça um Resposta:
POST informando o EventName e a Url. A resposta traz o Secret uma única vez. Copie e guarde antes de fechar a conexão, porque depois disso ele não é retornável pela API (só revelável pelo Console).Se você omitir
GroupId, o listener dispara para o evento no tenant inteiro. Informe um GroupId para escutar apenas um grupo específico.2
Receba o POST no seu endpoint
Todo disparo chega como
POST com Content-Type: application/json e os headers X-Cativa-Signature, X-Cativa-Execution-Id, X-Cativa-Automation-Id e X-Cativa-Idempotency-Key (detalhados em Headers de cada entrega).3
Verifique a assinatura HMAC
Antes de confiar no payload, recompute o HMAC-SHA256 com o seu
Secret e compare em tempo constante com o header X-Cativa-Signature. Rejeite disparos com timestamp fora da janela de 5 minutos. Código pronto em Node e Python na seção Verificando a assinatura HMAC.4
Responda 2xx rápido
Responda
200 (qualquer 2xx serve) assim que validar a assinatura. Não faça o trabalho pesado dentro do request. Enfileire o processamento e responda rápido, senão o disparo estoura timeout e entra em retry desnecessário.5
Deduplique reentregas
A entrega é at-least-once. Use o header
X-Cativa-Idempotency-Key (ou X-Cativa-Execution-Id) para descartar duplicatas. Detalhes e código em Idempotência.6
Deixe a Cativa re-tentar as falhas
Se você responder erro
5xx/408/429 ou cair a conexão, a Cativa re-tenta sozinha na curva de backoff. Você não precisa fazer nada além de voltar a responder 2xx. Detalhes em Retries e falhas permanentes.Endpoints de gestão
Todos exigemAuthorization: Bearer YOUR_API_KEY e usam a base https://apis.cativalab.digital/tenant/api/v2.
Listar assinaturas
Listar assinaturas
Atualizar uma assinatura
Atualizar uma assinatura
Desative temporariamente ou troque a URL sem recriar o listener (o secret é preservado):
Remover uma assinatura
Remover uma assinatura
Inspecionar entregas (logs e execuções)
Inspecionar entregas (logs e execuções)
Logs de uma assinatura específica:Todas as execuções do tenant, filtrando por falhas de um evento nas últimas 24h:
Eventos disponíveis
Use exatamente esses nomes em snake_case no campo
EventName ao cadastrar, é como a Cativa faz o match.
Verificando a assinatura HMAC
A assinatura é o que prova que o disparo veio mesmo da Cativa (e não de alguém que descobriu sua URL). Sempre verifique antes de processar. Cada disparo chega com o header:t, timestamp Unix (em segundos) do momento do disparo.v1, HMAC-SHA256 (hex, minúsculo) sobre a string"<t>.<rawBody>", usando osecretdo listener como chave.
- Parse do header em
tev1. - Anti-replay, rejeite o request se
|now - t| > 300segundos (5 minutos é o padrão de mercado). Isso barra o replay de um request antigo capturado. - Recomputar o HMAC e comparar em tempo constante (
timingSafeEqual/hmac.compare_digest), nunca com==.
Headers de cada entrega
Retries e falhas permanentes
Se seu endpoint não responder com2xx, a Cativa re-tenta de acordo com a curva:
X-Cativa-Idempotency-Key e X-Cativa-Execution-Id.
A Cativa respeita o header Retry-After que você retornar (limitado ao máximo da próxima janela do backoff).
Tabela de comportamento por status
A lógica: status na faixa
4xx (exceto 408 e 429) significa “o request está errado e re-tentar não vai ajudar”, tipicamente bug do cliente, URL desativada ou auth incorreta. Status 5xx, 408, 429 e erros de transporte significam “tente de novo mais tarde”.
Quando todas as tentativas falham
Se a 7ª tentativa também falhar, a entrega vira dead-letter e fica registrada nos logs (consultáveis porGET .../webhooks/{webhookId}/logs e GET .../executions). Monitore o uptime do seu endpoint pelo seu lado e, se desconfiar de eventos perdidos, cheque os logs ou abra ticket em dev@cativa.digital.
Idempotência
A entrega é at-least-once. O mesmo evento pode chegar mais de uma vez (retries após timeout, perda de conexão na hora de responder). Você precisa detectar duplicatas no seu lado. A chave canônica é o headerX-Cativa-Idempotency-Key: é determinístico por entrega e se mantém igual em todos os retries (o X-Cativa-Execution-Id também serve). Salve esse ID na mesma transação da lógica de negócio:
Boas práticas
Responda rápido, processe depois
Responda rápido, processe depois
Valide a assinatura, enfileire o payload (fila, tabela de outbox, tópico) e responda
2xx na hora. Processamento pesado dentro do request estoura timeout e gera retries desnecessários.Sempre verifique a assinatura
Sempre verifique a assinatura
Nunca aja sobre um payload não verificado. Sua URL pode vazar (logs, proxies) e qualquer um pode enviar
POST para ela. O HMAC é o que separa o disparo legítimo do forjado.Seja idempotente
Seja idempotente
Grave o
X-Cativa-Idempotency-Key e descarte reentregas. Assuma que todo evento pode chegar duas vezes.Configure timeouts do seu lado
Configure timeouts do seu lado
Chamadas externas dentro do handler (CRM, email) devem ter timeout curto. Se um provedor terceiro travar, você trava a resposta e vira retry.
Um secret por listener
Um secret por listener
Não reuse um secret entre ambientes. Um listener de staging e um de produção têm secrets distintos por design. Trate-os como credenciais separadas.
Eventos relacionados
Webhooks (visão geral)
Por que webhooks, garantias de entrega e o formato dos payloads.
user_received_badge
Página de referência completa de um evento, payload, headers e receiver de exemplo.
