Como funciona
Quando algo relevante acontece num tenant (usuário recebe badge, post é criado, pagamento é confirmado), a Cativa monta o payload do evento e fazPOST no seu endpoint público com Content-Type: application/json.
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 osecret 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:
t— timestamp Unix (em segundos) do momento do disparo.v1— assinatura HMAC-SHA256 (hex) sobre a string"<t>.<rawBody>", usando osecretdo listener como chave.
Retries com backoff
Se seu endpoint não responder com2xx, a Cativa re-tenta de acordo com a curva:
Retry-After que você retornar (até o limite máximo da próxima janela do backoff).
Quando re-tenta vs falha permanente
| Status | Comportamento |
|---|---|
2xx | Sucesso — sem retry |
408 Request Timeout | Retry |
429 Too Many Requests | Retry (respeita Retry-After) |
5xx (500, 502, 503, 504, …) | Retry |
| Erros de rede / timeouts TCP | Retry |
400 Bad Request | Falha permanente — sem retry |
401 Unauthorized | Falha permanente — sem retry |
403 Forbidden | Falha permanente — sem retry |
404 Not Found | Falha permanente — sem retry |
410 Gone | Falha permanente — sem retry |
Formato do payload
Exemplo (payload deuser_received_badge):
| Campo | Descrição |
|---|---|
CustomerId | ID do tenant que originou o evento. Use para rotear quando seu endpoint recebe webhooks de múltiplos tenants. |
| Campos específicos | Cada 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.
comment_created, course_completed, lesson_completed e user_received_private_message) está em Cadastrando e verificando webhooks.
Antipattern: processar eventos síncronamente no endpoint
Idempotência no seu lado
Como entrega é at-least-once, você precisa detectar duplicatas. Use o headerX-Cativa-Execution-Id (sempre enviado e estável entre retries do mesmo evento) como chave de deduplicação:
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.
