Skip to main content

How it works

When a watched user’s churn risk crosses their threshold, ChurnKit sends a signed HTTP POST to the webhook URL you registered with watch().
User's score crosses threshold

ChurnKit signs payload with HMAC-SHA256

POST https://yourapp.com/hooks/churn-alert

Your server verifies signature → processes alert

Webhook payload

{
  "event": "churn_risk_alert",
  "userId": "user_123",
  "score": 0.84,
  "tier": "high",
  "signals": ["no_login_7d", "support_spike", "export_all_data"],
  "recommendation": "This user is at high risk. Reach out immediately.",
  "triggeredAt": "2024-06-01T14:22:00Z"
}

Event types

EventWhen
churn_risk_alertUser’s score crossed the watch threshold

HTTP headers

HeaderValue
Content-Typeapplication/json
X-ChurnKit-Signaturesha256=<hmac_hex>
X-ChurnKit-TimestampUnix timestamp (seconds)

Responding to webhooks

Return a 2xx status code to acknowledge receipt. ChurnKit retries failed deliveries (non-2xx or timeout) with exponential backoff for up to 72 hours.
// Always return 200 quickly — process async if needed
export async function POST(req: Request) {
  const body = await req.text()

  // Verify first
  const valid = await verifyWebhookSignature(
    body,
    req.headers.get('x-churnkit-signature') ?? '',
    process.env.CHURNKIT_WEBHOOK_SECRET!
  )
  if (!valid) return new Response('Unauthorized', { status: 401 })

  // Acknowledge immediately, process async
  const payload = JSON.parse(body)
  processAlertAsync(payload) // don't await

  return Response.json({ ok: true })
}

Getting your webhook secret

Your webhook signing secret is shown in the FlowsBuilt Console under API Keys. Add it to your environment:
CHURNKIT_WEBHOOK_SECRET=whsec_your_secret_here
Always verify signatures. Never process a webhook payload before confirming its authenticity.

Next steps

Verify Signature

Step-by-step guide to signature verification in Node.js, Next.js, and Express.