Overview
watch() creates a real-time alert for a specific user. When that user’s risk score exceeds threshold, ChurnKit POSTs a signed payload to your webhook URL. The cooldown prevents repeat alerts from firing too frequently.
Signature
churn.watch(
userId: string,
options: WatchOptions
): Promise<WatchedUser>
WatchOptions
Fire the webhook when score >= threshold. Must be between 0 and 1.
HTTPS URL to POST the alert payload to. Must be a valid https:// URL.
Minimum time between repeated alerts for this user. Format: positive integer + d (days) or h (hours). Examples: "24h", "7d", "1d".
WatchedUser (return value)
interface WatchedUser {
userId: string
threshold: number
webhook: string
cooldown: string
}
Examples
Basic watch
await churn.watch('user_123', {
threshold: 0.7,
webhook: 'https://yourapp.com/hooks/churn-alert',
cooldown: '24h',
})
Watch all trial users
const trialUsers = await db.getTrialUsers()
await Promise.all(trialUsers.map((user) =>
churn.watch(user.id, {
threshold: 0.6,
webhook: 'https://yourapp.com/hooks/trial-churn',
cooldown: '7d',
})
))
Webhook payload
When the alert fires, ChurnKit POSTs this JSON to your webhook URL:
{
"event": "churn_risk_alert",
"userId": "user_123",
"score": 0.84,
"tier": "high",
"signals": ["no_login_7d", "support_spike"],
"recommendation": "Reach out immediately.",
"triggeredAt": "2024-06-01T14:22:00Z"
}
Always verify the webhook signature before processing the payload.
Handling the webhook in Next.js
// app/api/webhooks/churn/route.ts
import { verifyWebhookSignature } from '@vgpprasad91/churnkit-sdk'
export async function POST(req: Request) {
const body = await req.text()
const sig = req.headers.get('x-churnkit-signature') ?? ''
const valid = await verifyWebhookSignature(body, sig, process.env.CHURNKIT_WEBHOOK_SECRET!)
if (!valid) return Response.json({ error: 'Invalid signature' }, { status: 401 })
const payload = JSON.parse(body)
if (payload.event === 'churn_risk_alert' && payload.tier === 'high') {
await notifyCustomerSuccess(payload.userId, payload)
}
return Response.json({ ok: true })
}
Errors
| Code | When |
|---|
VALIDATION_ERROR | Invalid threshold, webhook URL, or cooldown format |
UNAUTHORIZED | API key invalid |
TIMEOUT | Request timed out |