Fintech / Neobank template

The Fintech / Neobank template — a primacy-and-dormancy churn model built on direct-deposit, balance, and transaction signals, with no new engine math.

Pick Fintech / Neobank / Payments when you create a project (or apply the template from Settings → Templates) and your dashboard is built around primacy — is this the customer's main account? — plus dormancy and friction. It reuses the built-in account-fact ops for flags and balance, so there's no new scoring math: primacy and KYC arrive as account attributes, balance as the account's value, and the rest as transaction events.

Primacy & balance are account facts, not events

Set direct_deposit and kyc_completed flags and the monetary_value balance (with valueBasis: "balance") via the account upsertPUT /api/accounts/{externalId}. Everything else is a card / bill-pay / decline event.

How a value becomes a score

Event and balance components map a raw value to a 0–100 score at their good / warn thresholds (100 at good, 30 at warn, linear between). Flag components (direct deposit, KYC) score a fixed 100 when present, or a floor when absent. Overall health is the weight-proportional average, banded Healthy ≥ 80 · Watch ≥ 60 · Risky ≥ 40 · Cold < 40.

Primacy

The heart of neobank retention. Direct deposit is the single strongest primacy signal — payroll-linked accounts hold higher balances and stay open far longer. Pair it with transaction frequency (is this the card they swipe?) and balance (is their money actually here?).

Evidence: direct-deposit accounts keep ~23% higher balances and stay open roughly 2× longer, and direct-deposit users are ~6× more engaged; the top three primacy drivers are direct deposit, bill pay, and digital engagement (The Financial Brand, Pinwheel).

3 signalscombined weight 50≈50% of score
Direct deposit / payroll (primacy)direct_deposit

Whether payroll direct deposit is set up.

Pass / failweight 20
How we collect it
Set the `direct_deposit` account flag via the account upsert (`PUT /api/accounts/{externalId}` with `attributes.direct_deposit = true`) or SDK identify.
How to read it
Present → 100; absent → the floor you set (35 in the template). No threshold curve — it's a fixed-score flag.
How to analyze it
Direct deposit is the single strongest primacy signal: payroll-linked accounts hold higher balances and stay open far longer. Its absence is a real churn risk, not just missing data.
What to do
Run a switch-your-paycheck campaign for accounts without it; make direct-deposit setup a first-week activation goal.
Tune it
Raise the absent floor if your product doesn't depend on payroll; keep the weight high — this is the dominant retention driver. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Transaction frequency (30d)card_transaction

Card transactions in the last 30 days.

Higher is bettergood ≥ 15warn ≤ 2weight 16
How we collect it
Send `card_transaction` on each card purchase (map `transaction.card` / `transaction.completed`).
How to read it
Raw value is the transaction count. 15+ scores 100; ≤ 2 scores 30. Active spending is core primacy behaviour.
How to analyze it
A neobank only wins if it's the card people actually swipe. Frequency separates the primary account from a parked, dormant one.
What to do
Reactivate low-frequency cardholders with rewards, round-ups, or a top-of-wallet incentive.
Tune it
Set the band to your users' normal monthly spend cadence. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Account balancemonetary_value

Current balance (the `balance` value basis).

Higher is bettergood ≥ 2000warn ≤ 50weight 14
How we collect it
Set `monetary_value` (with `valueBasis: "balance"`) via the account upsert, or let a billing provider project it.
How to read it
Raw value is the current balance, banded by your good/warn thresholds. A near-zero balance scores at the floor.
How to analyze it
A depleting balance precedes account abandonment — funds leaving is often the last step before a silent close.
What to do
Watch for balance drawdowns on primary accounts; a sudden drain plus rising recency is a strong pull-out signal.
Tune it
Set the band from your typical held balance; currency-normalize upstream. Weight, thresholds, and the metric spec are all editable in Settings → Components.

Dormancy & friction

What pulls a primary account apart. Rising recency between transactions is the earliest dormancy signal; bill pay is a sticky habit that raises switching cost; declined transactions are friction at the worst possible moment — the register.

Evidence: involuntary and friction signals (declines, stalled setup) are distinct, fixable churn buckets; recency is a core dormancy predictor across account-based financial products.

3 signalscombined weight 30≈30% of score
Days since last transactioncard_transaction

Recency of card activity.

Lower is bettergood ≤ 7 dayswarn ≥ 30 daysweight 12
How we collect it
Same `card_transaction` event — recency is derived from the latest one.
How to read it
Raw value is days since the last transaction. ≤ 7d scores 100; ≥ 30d scores 30.
How to analyze it
Growing gaps between transactions are the earliest dormancy signal, well before the account formally closes.
What to do
Nudge as recency crosses a week or two: a card-linked offer, a bill reminder, or a balance alert.
Tune it
Tighten for debit-first users who transact daily; loosen for savings-style accounts. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Bill pay set up (90d)bill_pay

Recurring bill payments in the last 90 days.

Higher is bettergood ≥ 1warn 0weight 10
How we collect it
Send `bill_pay` when a bill payment is made (map `bill.paid`).
How to read it
Raw value is the bill-pay count. Any bill pay scores 100; none scores the floor.
How to analyze it
Bill pay is a sticky primacy behaviour — it raises switching cost and signals the account is embedded in the customer's financial routine.
What to do
Promote bill-pay setup during onboarding; it's one of the highest-retention actions a new account can take.
Tune it
Keep the weight moderate — bill pay is powerful but not every segment uses it. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Declined transactions (30d)transaction_declined

Declined card attempts in the last 30 days.

Lower is bettergood 0warn ≥ 5weight 8
How we collect it
Send `transaction_declined` on each declined attempt (map `payment.declined`).
How to read it
Raw value is the decline count. 0 scores 100; 5+ scores 30.
How to analyze it
Declines are friction at the worst moment — at the register. Repeated declines push users to a competitor's card.
What to do
Investigate decline causes (limits, holds, fraud rules) for affected users and proactively reach out.
Tune it
Lower the warn threshold if your risk rules are strict and false-decline-prone. Weight, thresholds, and the metric spec are all editable in Settings → Components.

Engagement & relationship

The activation and relationship layer. KYC completion gates whether an account ever really activates; digital engagement is a top-three primacy driver; and money-related support sentiment escalates fast when it turns negative.

Evidence: accounts that stall in KYC rarely activate; digital engagement ranks alongside direct deposit and bill pay as a primacy driver; financial complaints carry outsized churn risk when unresolved.

3 signalscombined weight 20≈20% of score
KYC / setup completekyc_completed

Whether identity verification finished.

Pass / failweight 8
How we collect it
Set the `kyc_completed` account flag via the account upsert when verification passes.
How to read it
Complete → 100; incomplete → the floor (25 in the template). A fixed-score flag.
How to analyze it
Accounts stuck in KYC rarely activate and churn early — an unverified account is barely an account at all.
What to do
Chase stalled verifications hard in the first days; simplify the document flow where drop-off clusters.
Tune it
Keep the absent floor low — incomplete KYC is a serious activation risk. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Digital engagement (30d)session

App sessions in the last 30 days.

Higher is bettergood ≥ 10warn ≤ 1weight 8
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. 10+ scores 100; ≤ 1 scores 30.
How to analyze it
Digital engagement is a top-three primacy driver alongside direct deposit and bill pay — engaged users check, move, and manage money in-app.
What to do
Re-engage low-session users with insights, alerts, or goals that pull them back into the app.
Tune it
Set the band to your app's natural check-in cadence. Weight, thresholds, and the metric spec are all editable in Settings → Components.
Support sentiment (negative)support_ticket_negative

Negative-tagged support contacts (90d).

Lower is bettergood 0warn ≥ 2weight 4
How we collect it
Negative-tagged tickets from your support integration map to `support_ticket_negative`.
How to read it
Raw value is the negative-contact count. 0 scores 100; 2+ scores 30.
How to analyze it
Money-related frustration escalates fast — a couple of negative contacts can precede a closed account.
What to do
Prioritise financial-services complaints; a fast, empathetic resolution retains more than any feature.
Tune it
Keep the weight low so a single bad interaction doesn't dominate an otherwise healthy account. Weight, thresholds, and the metric spec are all editable in Settings → Components.

Sending the data

Flags and balance 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
direct_depositaccount flagPUT /api/accounts/{id}attributes.direct_deposit = true
kyc_completedaccount flagPUT /api/accounts/{id}attributes.kyc_completed = true
monetary_valueaccount valuePUT /api/accounts/{id}monetaryValue, valueBasis: "balance"
card_transactioneventon each card purchase
bill_payeventon each bill payment
transaction_declinedeventon each declined attempt

Common raw names (transaction.card, bill.paid, payment.declined, …) are pre-mapped, so most stacks resolve out of the box.

Next