Churn Risk Analyzer

Predict customer churn risk using usage patterns, support interactions, and engagement signals.

This workflow analyzes multiple data sources to identify at-risk customers and recommend retention interventions.

Implementation

1import { relay } from "@relayplane/workflows";
2
3const result = await relay
4 .workflow("churn-risk-analyzer")
5
6 // Step 1: Analyze usage patterns
7 .step("usage-analysis")
8 .with("openai:gpt-4o")
9 .prompt(`Analyze usage patterns for churn risk:
10
11Customer: {{customerName}}
12Account Created: {{accountAge}} days ago
13
14Usage Data (last 30 days):
15- Logins: {{loginCount}} (previous 30 days: {{previousLoginCount}})
16- Feature usage: {{featureUsage}}
17- API calls: {{apiCalls}} (previous: {{previousApiCalls}})
18- Active users: {{activeUsers}} of {{totalSeats}} seats
19
20Behavioral signals:
21- Login frequency trend
22- Feature adoption decline
23- Seat utilization
24- API usage trajectory
25
26Risk factors (0-10 scale for each):
27- Usage decline
28- Low feature adoption
29- Seat underutilization
30- Engagement drop`)
31
32 // Step 2: Analyze support interactions
33 .step("support-analysis")
34 .with("anthropic:claude-3.5-sonnet")
35 .depends("usage-analysis")
36 .prompt(`Analyze support interactions:
37
38Recent Tickets (last 60 days):
39{{supportTickets}}
40
41Assess:
42- Ticket frequency and trends
43- Resolution time satisfaction
44- Escalated issues
45- Repeated problems (indicates frustration)
46- Sentiment in recent interactions
47- Mentions of competitors or alternatives
48
49Support health score (0-10):
50Higher = healthy relationship
51Lower = at-risk due to support issues`)
52
53 // Step 3: Score relationship health
54 .step("relationship-score")
55 .with("openai:gpt-4o")
56 .depends("usage-analysis", "support-analysis")
57 .prompt(`Calculate overall churn risk:
58
59Usage Analysis: {{usage-analysis.output}}
60Support Analysis: {{support-analysis.output}}
61
62Additional signals:
63- Payment history: {{paymentHistory}}
64- Contract renewal date: {{renewalDate}}
65- Executive sponsor engaged: {{executiveSponsor}}
66- NPS score: {{npsScore}}
67
68Calculate composite churn risk score (0-100):
69- 0-30: Low risk (healthy)
70- 31-60: Medium risk (monitor)
71- 61-85: High risk (intervention needed)
72- 86-100: Critical risk (likely churning)
73
74Provide score breakdown with key factors.`)
75
76 // Step 4: Recommend interventions
77 .step("recommend-actions")
78 .with("anthropic:claude-3.5-sonnet")
79 .depends("usage-analysis", "support-analysis", "relationship-score")
80 .prompt(`Recommend retention actions:
81
82Risk Score: {{relationship-score.output}}
83Usage Issues: {{usage-analysis.output}}
84Support Issues: {{support-analysis.output}}
85
86Customer Context:
87- Plan: {{planTier}}
88- ARR: {{annualRevenue}}
89- Industry: {{industry}}
90
91Suggest interventions:
921. Immediate actions (this week)
932. Short-term (this month)
943. Long-term relationship building
95
96For each action:
97- Specific tactic
98- Owner (CSM, Sales, Product)
99- Success criteria
100- Estimated impact on retention
101
102Prioritize by ROI and urgency.`)
103
104 // Step 5: Draft outreach message
105 .step("draft-outreach")
106 .with("anthropic:claude-3.5-sonnet")
107 .depends("relationship-score", "recommend-actions")
108 .prompt(`Draft personalized outreach from CSM:
109
110Risk Assessment: {{relationship-score.output}}
111Recommended Actions: {{recommend-actions.output}}
112
113Customer: {{customerName}}
114CSM: {{csmName}}
115
116Email should:
117- Reference specific usage pattern (show we're paying attention)
118- Offer value (training, best practices, feature walkthrough)
119- Ask open-ended question about their goals
120- Soft check-in on satisfaction
121- NOT mention churn or sound desperate
122
123Tone: Genuinely helpful, proactive partnership
124Length: 80-120 words`)
125
126 .run({
127 customerName: "Acme Corp",
128 accountAge: 245,
129 loginCount: 12,
130 previousLoginCount: 45,
131 featureUsage: JSON.stringify({ workflows: 3, webhooks: 0, schedules: 1 }),
132 apiCalls: 1200,
133 previousApiCalls: 8500,
134 activeUsers: 2,
135 totalSeats: 10,
136 supportTickets: ticketHistory,
137 paymentHistory: "On-time, no issues",
138 renewalDate: "2024-12-15",
139 executiveSponsor: false,
140 npsScore: 6,
141 planTier: "Professional",
142 annualRevenue: 24000,
143 industry: "Financial Services",
144 csmName: "Sarah Chen",
145 });
146
147// Update CRM and trigger alerts
148await updateCRM({
149 accountId: customer.id,
150 churnRisk: result.steps["relationship-score"].output,
151 recommendations: result.steps["recommend-actions"].output,
152 draftOutreach: result.steps["draft-outreach"].output,
153});
154
155// Alert CSM if high risk
156const riskScore = JSON.parse(result.steps["relationship-score"].output).score;
157if (riskScore > 60) {
158 await sendSlack({
159 channel: "@sarah.chen",
160 message: `⚠️ HIGH CHURN RISK: Acme Corp (score: ${riskScore})\n\n${result.steps["recommend-actions"].output}`,
161 });
162}

Automated Monitoring

1// Daily churn risk check for all accounts
2import { relay } from "@relayplane/workflows";
3
4async function dailyChurnCheck() {
5 const accounts = await getActiveAccounts();
6
7 for (const account of accounts) {
8 const usage = await getUsageData(account.id, { days: 30 });
9 const tickets = await getSupportTickets(account.id, { days: 60 });
10
11 const analysis = await relay
12 .workflow("churn-risk-analyzer")
13 .run({
14 customerName: account.name,
15 accountAge: account.ageInDays,
16 loginCount: usage.logins.current,
17 previousLoginCount: usage.logins.previous,
18 // ... other parameters
19 });
20
21 const risk = JSON.parse(analysis.steps["relationship-score"].output);
22
23 // Store risk score history
24 await logChurnRisk({
25 accountId: account.id,
26 date: new Date(),
27 score: risk.score,
28 factors: risk.factors,
29 });
30
31 // Alert on score increase
32 if (risk.score > 60 && risk.scoreChange > 20) {
33 await notifyCSM(account.csm, {
34 account: account.name,
35 riskScore: risk.score,
36 recommendations: analysis.steps["recommend-actions"].output,
37 });
38 }
39 }
40}
41
42cron.schedule('0 6 * * *', dailyChurnCheck);

Sample Output

**Churn Risk Score: 72/100 - HIGH RISK** **Key Factors:** - Usage decline: 73% drop in API calls (8.5K → 1.2K) - Low engagement: 12 logins vs 45 previous month (-73%) - Seat waste: Using only 2 of 10 seats (20% utilization) - NPS: 6 (passive, at-risk) - No executive sponsor engaged **Red Flags:** - Champion may have left company (sudden usage drop) - Recent support ticket: "Exploring alternatives" - Contract renewal in 30 days **Immediate Actions:** 1. Executive Business Review within 7 days 2. Audit their use case - may have outgrown current setup 3. Offer personalized onboarding for new team members 4. Consider temporary discount to secure renewal

Success Metrics

  • Early Detection: Identify at-risk customers 45-60 days before churn
  • Intervention Rate: Save 40% of high-risk accounts with proactive outreach
  • Efficiency: Prioritize CSM time on accounts that matter most