Churn Events
Churn events represent customer cancellations and failed payments. Each event triggers AI-powered recovery workflows.
Event Status Lifecycle
Every churn event moves through a defined lifecycle:
new → processing → variants_generated → email_sent → recovered / lost
| Status | Description |
|---|
new | Event received, waiting to be processed |
processing | AI is analyzing the event and customer data |
variants_generated | 9 recovery email variants have been generated |
email_sent | A recovery email has been sent to the customer |
recovered | Customer reactivated or payment succeeded |
lost | Recovery window expired without reactivation |
Create a Churn Event
Create a new churn event manually (alternative to webhooks).
POST /projects/:slug/churn-events
Request Body
Customer’s email address.
Type of churn: cancellation or payment_failed.
Free-text reason for cancellation. Drives AI strategy selection.
Monthly recurring revenue in cents.
ISO 4217 currency code. Defaults to usd.
Days the customer has been subscribed.
Example Request
curl -X POST https://api.windbackai.com/api/v1/projects/my-project/churn-events \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"customer_email": "jane@example.com",
"customer_name": "Jane Smith",
"event_type": "cancellation",
"cancel_reason": "Too expensive for our team",
"mrr": 4999,
"currency": "usd",
"plan_name": "Team Pro",
"tenure_days": 180
}'
Example Response
{
"data": {
"id": "evt_abc123",
"project_id": "prj_xyz",
"customer_email": "jane@example.com",
"customer_name": "Jane Smith",
"event_type": "cancellation",
"cancel_reason": "Too expensive for our team",
"status": "new",
"mrr": 4999,
"currency": "usd",
"plan_name": "Team Pro",
"tenure_days": 180,
"provider": "api",
"created_at": "2025-12-01T10:00:00Z",
"updated_at": "2025-12-01T10:00:00Z"
}
}
List Churn Events
Retrieve a paginated list of churn events for a project.
GET /projects/:slug/churn-events
Query Parameters
Items per page (max 100).
Filter by status: new, processing, variants_generated, email_sent, recovered, lost.
Filter by type: cancellation or payment_failed.
Example Request
curl "https://api.windbackai.com/api/v1/projects/my-project/churn-events?status=new&page=1&per_page=10" \
-H "X-API-Key: sk_live_abc123..."
Example Response
{
"data": [
{
"id": "evt_abc123",
"customer_email": "jane@example.com",
"event_type": "cancellation",
"status": "new",
"mrr": 4999,
"created_at": "2025-12-01T10:00:00Z"
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 42
}
}
Get a Churn Event
Retrieve a single churn event by ID.
GET /projects/:slug/churn-events/:id
Example Request
curl https://api.windbackai.com/api/v1/projects/my-project/churn-events/evt_abc123 \
-H "X-API-Key: sk_live_abc123..."
Example Response
{
"data": {
"id": "evt_abc123",
"project_id": "prj_xyz",
"customer_email": "jane@example.com",
"customer_name": "Jane Smith",
"event_type": "cancellation",
"cancel_reason": "Too expensive for our team",
"status": "variants_generated",
"mrr": 4999,
"currency": "usd",
"plan_name": "Team Pro",
"tenure_days": 180,
"provider": "stripe",
"variants": [
{
"id": "var_001",
"strategy": "value_recap",
"subject": "Jane, here's what you'll miss",
"body": "Hi Jane, ...",
"status": "draft"
}
],
"created_at": "2025-12-01T10:00:00Z",
"updated_at": "2025-12-01T10:05:00Z"
}
}
Mark as Recovered
Mark a churn event as recovered when the customer reactivates.
POST /projects/:slug/churn-events/:id/recovered
Example Request
curl -X POST https://api.windbackai.com/api/v1/projects/my-project/churn-events/evt_abc123/recovered \
-H "X-API-Key: sk_live_abc123..."
Example Response
{
"data": {
"id": "evt_abc123",
"status": "recovered",
"recovered_at": "2025-12-05T14:30:00Z"
}
}
Stripe and Razorpay integrations automatically mark events as recovered when a payment_succeeded or payment.captured event is received.
Update Cancel Reason
Update the cancel reason on an existing churn event. Useful when the reason is collected after the event is created.
PATCH /projects/:slug/churn-events/:id/cancel-reason
Request Body
The updated cancel reason.
Example Request
curl -X PATCH https://api.windbackai.com/api/v1/projects/my-project/churn-events/evt_abc123/cancel-reason \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"cancel_reason": "Switching to a competitor with better integrations"}'
Example Response
{
"data": {
"id": "evt_abc123",
"cancel_reason": "Switching to a competitor with better integrations",
"updated_at": "2025-12-01T11:00:00Z"
}
}