Winback for at-risk users
Catch users whose behavior pattern is decaying — before they fully churn — and route them to a winback screen on their next session.
Use this when you have behavioral data — session frequency, feature usage, cohort baselines — that can flag "slowing down" before a calendar gap opens. Don't use this when you only have calendar signal (last-open timestamp); reach for Reactivation after inactivity instead. Also skip if the product is used every few days under normal conditions — the baseline is too shallow to drift against.
Goal
Churn prediction that waits for 30 days of inactivity is too late — by the time you act, the user has the app in an uninstall folder. This recipe fires on the next session after a behavioral drop (for example, weekly sessions fell from 5 to 1) and shows a winback surface: a value-recap screen, a small incentive, or a shortcut to the feature the user used to love. You are intervening while the user still has the app on their home screen.
Setup
In the dashboard
Create a campaign
winback-at-risk.Trigger: session start.
Conditions:
risk_status = "at_risk"andsubscription_status != "pro_new"(do not hassle users who just paid).Action: fire
yourapp://winback/welcome-back— a short screen that references the user's previous favorite feature and offers a small incentive if appropriate.Frequency: once per transition into
at_risk. When the user re-engages andrisk_statusflips back tohealthy, the campaign can match again if they slip later.Exclude users whose
last_session_atis more than 30 days old — those need a different flow in a different channel.
In the app (engineering hand-off)
Compute the risk signal in the app or an upstream service. Keep the definition simple and stable:
// Pseudocode: compare last 7 days to prior 28-day baseline const status = recentRate < baseline * 0.3 ? 'at_risk' : 'healthy'; await Amply.setCustomProperty('risk_status', status); await Amply.setCustomProperty('last_core_feature', lastFeature);Write
risk_statusbefore the session starts, so the first campaign evaluation sees the current value.Track the outcome for measurement:
await Amply.track({ name: 'WinbackShown' }); await Amply.track({ name: 'WinbackConverted' });
How it runs
User used the app ~5 times per week for a month, then dropped to ~1 per week.
On the first session after the drop, the app recomputes the risk signal:
risk_status = "at_risk".Session starts. Amply evaluates campaigns.
winback-at-riskmatches.Amply fires
yourapp://winback/welcome-back. The screen shows "Your weekly streak is still here — one tap to pick up where you left off," referring to the user's last core feature. The app tracksWinbackShown.User taps through, uses the feature again. Over the next week, usage recovers. The app recomputes
risk_status = "healthy".If usage drops again months later, the campaign can match again. If the user goes dark for 30+ days, they fall out of this campaign's audience and belong to reactivation or email instead.
Metrics to watch
Winback conversion rate: share of
WinbackShownusers who come back to healthy within 14 days. Compare to a hold-out that never saw the screen.False-positive rate of the at-risk signal: users flagged at-risk who would have recovered anyway. A noisy signal burns the surface.
Long-term retention of winback-recovered users — 60 and 90 days out. A superficial recovery does not count.
Share of your free-to-paid users who ever hit at-risk. Rising share is a product-quality signal, not a campaign problem.
Related
Reactivation after inactivity — the coarser calendar-based version, used when you have no behavioral signal
Post-trial recovery — for trial users specifically
Targeting an audience — expressing
risk_statusconditionsUser attributes — why risk status belongs on the user
Tracking events — winback event instrumentation
AI-assisted integration — describe this campaign in plain language and have your AI assistant build it
Last updated