Pular para o conteúdo principal
Webhooks são a forma da Cativa te avisar quando algo acontece — em vez de você ficar perguntando à API a cada minuto. Esta página é a visão de alto nível. Para o passo a passo de cadastro, verificação de assinatura e retries, veja Cadastrando e verificando webhooks.

Como funciona

Quando algo relevante acontece num tenant (usuário recebe badge, post é criado, pagamento é confirmado), a Cativa monta o payload do evento e faz POST no seu endpoint público com Content-Type: application/json.
Ação no tenant


Cativa monta o payload


POST https://seu-app.com/webhooks/cativa
Você cadastra a URL e os tipos de evento que quer escutar no painel da Cativa, em Console > Webhooks. Cada listener recebe um secret próprio (formato whsec_ + 64 hex), usado para assinar todo disparo daquele listener.

Garantias de entrega

At-least-once

Cada evento é entregue pelo menos uma vez. Sempre use o X-Cativa-Execution-Id para idempotência no seu lado, evitando processar duas vezes em caso de duplicata.

Ordem NÃO garantida

Eventos podem chegar fora da ordem em que aconteceram. Não escreva código que depende de receber user_created antes de user_received_badge — eles podem inverter.

Por que sem ordem?

A Cativa entrega eventos em paralelo para chegar rápido ao seu endpoint. Forçar ordem reduziria o throughput em ordem de magnitude. Em vez disso, o payload de cada evento contém todos os dados que você precisa para processá-lo isoladamente.

Assinatura HMAC (X-Cativa-Signature)

Todo disparo é assinado com HMAC-SHA256 usando o secret do listener. Você confere a assinatura antes de processar o evento, garantindo que o request veio mesmo da Cativa e que o body não foi adulterado em trânsito. A assinatura chega no header:
X-Cativa-Signature: t=1715177521,v1=8c1d4e2a3b5f4d8a9c6e7f0b1a2d3e4f8a9c6e7f0b1a2d3e4f8a9c6e7f0b1a2d
  • t — timestamp Unix (em segundos) do momento do disparo.
  • v1 — assinatura HMAC-SHA256 (hex) sobre a string "<t>.<rawBody>", usando o secret do listener como chave.
O exemplo de verificação completo (Node, Python, Go, C#) está em Cadastrando e verificando webhooks.
Compute o HMAC sobre o body bruto (a string exata recebida), não sobre o JSON re-serializado. Re-serializar muda espaços em branco e ordem de chaves, o que invalida a assinatura.

Retries com backoff

Se seu endpoint não responder com 2xx, a Cativa re-tenta de acordo com a curva:
30s  →  5min  →  30min  →  2h  →  6h  →  24h
São 6 retries após a tentativa inicial — 7 entregas no total, cobrindo cerca de 33 horas. A Cativa respeita o header Retry-After que você retornar (até o limite máximo da próxima janela do backoff).

Quando re-tenta vs falha permanente

StatusComportamento
2xxSucesso — sem retry
408 Request TimeoutRetry
429 Too Many RequestsRetry (respeita Retry-After)
5xx (500, 502, 503, 504, …)Retry
Erros de rede / timeouts TCPRetry
400 Bad RequestFalha permanente — sem retry
401 UnauthorizedFalha permanente — sem retry
403 ForbiddenFalha permanente — sem retry
404 Not FoundFalha permanente — sem retry
410 GoneFalha permanente — sem retry
Se todas as tentativas falharem, o disparo é registrado internamente como falho. A v1 ainda não tem painel no Console para inspecionar entregas falhas — entre em contato com o suporte da Cativa para investigar.

Formato do payload

Diferente de muitas APIs, o payload não usa um envelope genérico ({id, type, data}). Cada evento tem um shape próprio em PascalCase, com CustomerId no nível raiz para roteamento multi-tenant.
Exemplo (payload de user_received_badge):
{
  "CustomerId": "01HQ0...",
  "BadgeId": "01HQ4...",
  "BadgeName": "Premium",
  "User": {
    "Id": "01HQ7Z3X4Y5Z6A7B8C9D0E1F2G",
    "Email": "maria@exemplo.com",
    "DisplayName": "Maria Silva"
  },
  "ReceivedAt": "2026-05-08T14:32:01Z"
}
Os campos comuns ao envelope de qualquer evento:
CampoDescrição
CustomerIdID do tenant que originou o evento. Use para rotear quando seu endpoint recebe webhooks de múltiplos tenants.
Campos específicosCada evento adiciona seus próprios campos (ex: BadgeId, BadgeName, User, ReceivedAt para user_received_badge). Veja a página de cada evento para o shape exato.

Catálogo de eventos

A Cativa expõe eventos para as ações principais da plataforma. Comece pelo evento canônico:

user_received_badge

Disparado quando um badge é atribuído a um usuário. Página de referência completa com payload e exemplo de receiver.

user_created

Novo usuário cadastrado.

user_joined_group

Usuário entrou num grupo (manual ou via badge).

post_created

Novo post publicado num grupo.

paywall_payment_completed

Pagamento do paywall concluído com sucesso.
A lista completa de eventos disponíveis (incluindo comment_created, course_completed, lesson_completed e user_received_private_message) está em Cadastrando e verificando webhooks.

Antipattern: processar eventos síncronamente no endpoint

Não faça operações lentas (chamadas HTTP, queries pesadas, geração de relatórios) dentro do handler do webhook. Volte um 2xx o mais rápido possível e processe em background.O padrão correto: o endpoint enfileira o evento na sua própria fila e responde 200. Um worker do seu lado processa depois, com calma.
app.post('/webhooks/cativa', express.json(), async (req, res) => {
  // Enfileira para processar depois — não processa aqui
  await myQueue.enqueue(req.body);
  res.status(200).send('ok');
});

Idempotência no seu lado

Como entrega é at-least-once, você precisa detectar duplicatas. Use o header X-Cativa-Execution-Id (sempre enviado e estável entre retries do mesmo evento) como chave de deduplicação:
async function processEvent(executionId, payload) {
  const alreadyProcessed = await db.events.exists(executionId);
  if (alreadyProcessed) return;

  await db.transaction(async (tx) => {
    await applyBusinessLogic(tx, payload);
    await tx.events.insert({ id: executionId, processedAt: new Date() });
  });
}
Salvar o identificador de execução na mesma transação da lógica de negócio garante que ou tudo aconteceu, ou nada aconteceu — sem chance de processar duas vezes.

Próximos passos

Cadastrando e verificando webhooks

Como cadastrar listener, verificar HMAC, lidar com retries.

user_received_badge

Página de referência completa de um evento — exemplo concreto de payload e receiver.