API
Webhooks
Receba notificações de eventos em tempo real.
Webhooks
Webhooks notificam sua aplicação em tempo real quando eventos importantes acontecem na sua tribo: nova assinatura, saque pago, PR detectado, etc.
Configuração
No painel: Configurações → Webhooks → Adicionar endpoint.
- URL: HTTPS público (ex:
https://api.seuapp.com/webhooks/octalife) - Eventos: selecione os eventos que quer receber
- Secret: use o secret gerado pra validar a assinatura
Eventos disponíveis
| Evento | Quando dispara |
|---|---|
subscription.created | Membro nova assinatura (incl. trial) |
subscription.activated | Trial converteu pra paid |
subscription.canceled | Membro ou creator cancelou |
subscription.past_due | Pagamento falhou, retry agendado |
payout.paid | Saque caiu na conta bancária |
payout.failed | Saque falhou |
member.joined_community | Membro entrou (free preview) |
post.published | Post publicado no feed |
pr.detected | Membro bateu PR em algum exercício |
challenge.completed | Membro completou um desafio |
Formato do payload
{
"id": "evt_uuid",
"type": "subscription.created",
"created_at": "2026-04-15T10:30:00Z",
"data": {
"subscription_id": "uuid",
"community_id": "uuid",
"tier_id": "uuid",
"member_id": "uuid",
"status": "trialing",
"trial_end": "2026-04-22T10:30:00Z"
}
}Validando assinatura
Cada request inclui o header X-OctaLife-Signature:
X-OctaLife-Signature: t=1713178200,v1=abc123def456...Para validar:
import crypto from 'crypto';
function verifyWebhook(payload, signatureHeader, secret) {
const [tsPart, sigPart] = signatureHeader.split(',');
const timestamp = tsPart.split('=')[1];
const signature = sigPart.split('=')[1];
const signedPayload = `${timestamp}.${payload}`;
const expected = crypto.createHmac('sha256', secret).update(signedPayload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}Sempre valide a assinatura. Sem validação, qualquer um pode forjar eventos.
Retentativas
Em caso de erro (HTTP não-2xx ou timeout > 10s), retry exponencial: 5s, 30s, 5min, 1h, 6h, 24h. Após 5 tentativas falhas, o evento é abandonado e fica no log de eventos pra reprocessamento manual.
Boas práticas
- Responda rápido (< 200ms): faça o trabalho pesado em fila/background
- Idempotência: use
event.idpra deduplicar (evita processamento duplo em retries) - Log eventos: guarde payload pra debug
- Verifique sempre a assinatura antes de processar