Mobile app template

The Mobile consumer-app template — an early-retention model built around the D1/D7/D30 cohort curve, engagement rhythm, push, and monetization.

Pick Mobile consumer app when you create a project (or apply the template from Settings → Templates) and your dashboard is built around early retention — the D1/D7/D30 curve that decides whether a new install becomes a habit or an uninstall — plus engagement rhythm, push, and monetization. It's the one Tier-C vertical with a genuinely new scoring shape: the cohort_retention op.

Install date & push opt-in are account facts

Set installed_at (a date) and the push_opt_in flag via the account upsert. If you don't set installed_at, retention falls back to an app_installed event, then to the account's creation date.

How a value becomes a score

Event components map a raw value to a 0–100 score at their good / warn thresholds. Early retention scores the share of elapsed D1/D7/D30 milestones the user survived, and push opt-in is a fixed flag score. Overall health is the weight-proportional average, banded Healthy ≥ 80 · Watch ≥ 60 · Risky ≥ 40 · Cold < 40.

Retention & engagement

The core of mobile health. Early retention is the defining signal — the first days decide everything. Pair it with session frequency and recency (is the habit forming and holding?) and feature depth (did they find the value?).

Evidence: mobile retention is steep — median D1 ~26%, D7 ~13%, D30 ~7% (MWM) — so early-lifecycle retention has to be scored explicitly, not inferred from lagging engagement.

4 signalscombined weight 56≈56% of score
Early retention (D1 / D7 / D30)app_open

Share of the D1/D7/D30 milestones the user stayed active for.

Higher is betterweight 18
How we collect it
Send `app_open` on each launch and set `installed_at` on the account (via the account upsert) — or send an `app_installed` event; the op falls back to account creation.
How to read it
For each elapsed milestone (D1, D7, D30) from install, the user 'survived' if still active at or beyond it. Score is the share of survived milestones, 0–100. A cohort too young to have reached any milestone is skipped.
How to analyze it
Early retention is the defining mobile churn signal — benchmarks sit around D1 ~26%, D7 ~13%, D30 ~7%, so the first days decide the relationship.
What to do
Invest in first-session activation and a D1/D7 re-engagement loop; the early curve is where the most users are saved.
Tune it
Change the milestone offsets (`retentionDays`) to match your app's natural habit loop — a daily app cares about D1/D3/D7, a weekly one about D7/D14/D30. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Session frequency (30d)session

App sessions in the last 30 days.

Higher is bettergood ≥ 20warn ≤ 3weight 14
How we collect it
Send `session` on app opens (SDK auto-capture maps this by default).
How to read it
Raw value is the session count. 20+ scores 100; ≤ 3 scores 30. Frequency is the core habit signal.
How to analyze it
Consumer apps live or die on habit — a user who opens often has embedded the app into their routine.
What to do
Build daily-value hooks (streaks, fresh content, reminders) for low-frequency users before they lapse.
Tune it
Set the band to your app's natural cadence; a utility opened weekly reads differently from a daily social app. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Days since last openapp_open

Recency of app opens.

Lower is bettergood ≤ 3 dayswarn ≥ 14 daysweight 14
How we collect it
Derived from the latest `app_open` event.
How to read it
Raw value is days since the last open. ≤ 3d scores 100; ≥ 14d scores 30. Growing gaps precede uninstall.
How to analyze it
Recency is the earliest dormancy signal — the slide from daily to weekly to never is where churn happens.
What to do
Trigger a push or email as recency crosses your habit interval, before the app slips off the home screen.
Tune it
Tighten for daily-habit apps; loosen for episodic ones. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Feature / screen depthfeature_used

Share of distinct features / screens reached.

Higher is bettergood ≥ 40%warn ≤ 10%weight 10
How we collect it
Send `feature_used` (or map screen views) as the user explores the app.
How to read it
Raw value is the share of the configured feature set touched. Broad exploration scores high.
How to analyze it
Breadth of value found early strongly predicts retention — users who only see one screen rarely stay.
What to do
Guide new users to a second and third core feature; surface undiscovered value in-app.
Tune it
Set `totalFeatures` to your app's core surface count so the ratio is meaningful. Weight, thresholds, and the metric spec are all editable in Settings → Components.

Push & monetization

The retention levers. Push opt-in and engagement are among the strongest controllable retention drivers; paywall conversion marks the users who've committed with their wallet.

Evidence: apps using push see up to ~3× retention and global opt-in is ~67%, but over-notifying drives uninstalls — so opens, not sends, are what count (vmobify). Monetized users retain materially better than free users.

3 signalscombined weight 26≈26% of score
Push opt-inpush_opt_in

Whether push notifications are enabled.

Pass / failweight 8
How we collect it
Set the `push_opt_in` account flag via the account upsert when the user grants permission.
How to read it
Enabled → 100; disabled/unknown → the floor (45 in the template). A fixed-score flag.
How to analyze it
Apps using push see up to ~3× retention, and global opt-in is ~67%; opt-in is a powerful, controllable retention lever.
What to do
Earn the opt-in with a well-timed, value-first prompt; win back opted-out users through other channels.
Tune it
Raise the absent floor if your app doesn't rely on push; keep it below present so opt-in still matters. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Push engagement (30d)push_opened

Opened push notifications in the last 30 days.

Higher is bettergood ≥ 5warn 0weight 8
How we collect it
Send `push_opened` when a notification is tapped (map `notification.opened`).
How to read it
Raw value is the opened-push count. 5+ scores 100; none scores the floor.
How to analyze it
Engaged notifications pull users back — but over-notifying drives uninstalls, so opens (not sends) are what matter.
What to do
Optimize for relevance and timing over volume; prune notification types with low open rates.
Tune it
Set the band to your healthy monthly push-open rate. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Paywall conversion (90d)iap_purchase

In-app purchases ÷ paywall views, as a %.

Higher is bettergood ≥ 5%warn 0%weight 10
How we collect it
Send `paywall_view` when the paywall shows and `iap_purchase` on purchase; the `ratio` op divides them.
How to read it
Raw value is view-to-purchase conversion. ≥ 5% scores 100; 0% scores 30.
How to analyze it
Monetized users retain and churn less — a paying user has committed in a way a free user hasn't.
What to do
Test paywall placement, timing, and offer; a user who sees the paywall but never converts is unmet intent.
Tune it
Anchor `good`/`warn` to your own conversion benchmark, which varies widely by app category. Weight, thresholds, and the metric spec are all editable in Settings → Components.

Friction & trend

What breaks the habit. Crashes and frustration drive uninstalls fast, and a sharp week-over-week activity drop is an early dormancy signal that moves before the user formally leaves.

Evidence: friction and crashes are leading uninstall drivers on mobile; week-over-week engagement decline reliably precedes churn.

2 signalscombined weight 18≈18% of score
Crashes & frustration (30d)frustration_score

Rage-clicks, crashes, and errors captured by the SDK.

Lower is bettergood 0warn ≥ 8weight 10
How we collect it
SDK auto-capture maps rage-clicks and errors to `frustration_score`.
How to read it
Raw value is the friction count. 0 scores 100; 8+ scores 30.
How to analyze it
Friction drives uninstalls fast on mobile — a crash at the wrong moment can end the relationship instantly.
What to do
Prioritise crash and rage-click hotspots; a smooth app is table stakes for retention.
Tune it
Lower warn for polished apps where any friction is notable. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Activity drop (WoW)any event

Week-over-week drop in event volume.

Lower is bettergood ≤ 20warn ≥ 60weight 8
How we collect it
Computed from every event on the account — no dedicated event needed.
How to read it
Raw value is the percentage drop vs. the prior week. A small drop scores high; near-total silence scores low.
How to analyze it
A sharp week-over-week drop is an early dormancy signal — the habit is breaking before the user formally leaves.
What to do
Re-engage as the drop steepens; pair with recency for the full dormancy picture.
Tune it
Loosen for spiky, episodic apps where week-to-week swings are normal. Weight, thresholds, and the metric spec are all editable in Settings → Components.

Sending the data

Install date and push opt-in go through the account upsert; the rest are events. Send events via the SDK or the HTTP API; map your names in Settings → Event map.

SignalKindHow to send
installed_ataccount datePUT /api/accounts/{id}attributes.installed_at
push_opt_inaccount flagPUT /api/accounts/{id}attributes.push_opt_in = true
app_openeventon each launch
sessioneventon each session
push_openedeventon each notification tap
iap_purchase / paywall_vieweventson purchase / paywall shown
app_installedeventon first install (a fallback source for the install date when installed_at isn't set)

Common raw names (app.open, notification.opened, iap.purchase, paywall.shown, …) are pre-mapped, so most SDKs resolve out of the box.

Optional signals

These aren't scored by the default template but are recognized signals you can send and later build a custom component on:

SignalWhen to sendWhy it's useful
app_uninstalledOn uninstall (e.g. push-token invalidation)The terminal churn event — a definitive confirmation for reporting or a hard-cold rule.
push_enabledWhen the user enables push in-appAn event-based alternative to the push_opt_in account flag if you'd rather track opt-in over time than as a single state.

Next