Customer health score
@usagemetrics/customer-health-score
Score customer health from usage, support, and billing signals with weights you can read and edit. Bands every account green, yellow, or red, names the top drivers, tracks change since the last score, and flags at-risk accounts renewing soon. Works from one CSV.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
What it makes
Real output from this kit
- Sample file1 KB, download to openHealthFrom the kit's tests
- Sample file6 KB, download to openHealthFrom the kit's tests
- Sample file1 KB, download to openHealthFrom the kit's tests
How this works
- It is a skill: written instructions Claude reads when your request matches what the skill is for. You do not call it by name; just ask for the task.
- While it works, it reads and changes files in the places it lists, nowhere else.
- It runs these commands on your computer: node scripts/health.mjs.
- Nothing runs until you choose to use it, and you can remove it any time.
SKILL.md
Customer health score
A health score people trust is one they can read. Every signal, its weight, and what counts as good or bad live in one small JSON file the team owns. The script does the math the same way every week, and every account gets its top drivers so the score leads to an action.
Inputs
data/accounts.csv: one row per account. Required:account_id. Useful:name,arr,renewal_date,previous_score(last run's score, for change). Then one column per signal, for example:Signal column From Example seat_utilizationactive users / paid seats, last 30 days 0.62 usage_trendchange in events, last 28 days vs prior 28 -0.12 core_feature_usersusers of the key feature, last 30 days 4 open_tickets,urgent_tickets_90d,csathelp desk export 2, 0, 4.4 days_past_duebilling system 32 exec_sponsorCRM (1 = yes) 1 The
saas-usage-dashboardJSON output has usage trend and active users per account; use it to fill usage columns.data/health-weights.json: copyexamples/weights.jsonif the user has none. Each signal hascolumn,weight,bad,good, and an optionallabelandgroup. A value atbadscores 0, atgoodscores 100, linear in between and clamped.goodcan be lower thanbad(for tickets and days past due).
Steps
- Check which signal columns exist and how many accounts have each. Signals with no column are skipped; tell the user.
- Review the weights with the user before the first run. Defaults: usage 50%, support 25%, billing 15%, relationship 10%. Ask whether that matches how they lose customers; adjust in
data/health-weights.json. Run:
node scripts/health.mjs data/accounts.csv --weights data/health-weights.json --as-of 2026-11-01 --out out/health- Report from
out/health.md: accounts and ARR per band, the priority accounts (red, or yellow and down 10+ points, renewing within 90 days), and the biggest drops. - Sanity check with the user: name two accounts they consider healthy and two they worry about, and see where they landed. If the score disagrees with the team's judgment, adjust weights or thresholds, not individual scores, and rerun.
- Remind the user to bring this run's
scorecolumn (inout/health.csv) into next run's accounts file asprevious_score, so changes show up. - For each priority account, offer the
churn-risk-reviewkit to plan the save.
Rules the script follows
- Score = weighted average of the signals that have a value. Missing values are left out and the weights renormalized.
- Accounts with data for less than 60% of the total weight (
min_weight_coverage) are not banded; they show asunknownso a thin record never looks healthy. - Bands default to green 70+, yellow 45 to 69, red under 45 (
bandsin the weights file). - Drivers are the signals scoring under 60, ordered by how many points they cost.
Output template
**Health, Nov 1:** 5 green ($274k), 3 yellow ($138k), 2 red ($50k), 1 not enough data.
Priority (renewing in 90 days): Bluebird Labs (25, down 39; usage trend -68%, seat use 35%), ...
Biggest drops: Bluebird -39, Fable -37, Harbor -33.Guardrails
- A score is a prompt for a conversation, not a verdict. Never present it to the customer.
- Do not edit a single account's score by hand. Change the weights file and rerun, so every account is treated the same way.
- Do not paste contact names or ticket text into chat.
README.md
Customer health score
Combines usage, support, and billing signals into one health score per account, using a weights file your team can read and change. Every account gets a band, its top drivers, its change since last time, and a flag if it is at risk and renewing soon.
Who it is for: customer success leads and founders who want a weekly at-risk list without buying a CS platform.
Example
Input: examples/accounts.csv (11 accounts, 8 signals) and examples/weights.json.
Output (out/health.md):
| Band | Accounts | ARR |
|---|---|---|
| green | 5 | $273,600 |
| yellow | 3 | $138,000 |
| red | 2 | $50,400 |
| **Bluebird Labs** | 25 red | -39 | $42,000 | 44 d | Usage trend (-0.68), Seat use (0.35), Core feature users (1) |Plus out/health.csv with every account, band, sub-scores by group, and drivers.
What it can access
- Runs
node scripts/health.mjs(Node built-ins only). - Reads
data/. Writesdata/health-weights.json(your weights) andout/health*. - No network, no CRM or help desk logins. You bring the exports.
Setup
None. Put one row per account in data/accounts.csv and ask Claude for a health score. It starts from the example weights and tunes them with you.
Files
- README.md
- SKILL.md
- examples/accounts.csv
- examples/weights.json
- kit.json
- scripts/health.mjs
- scripts/lib.mjs
Did it work?
0worked for them0did not work
Sign in to say whether it worked for you.
Nobody has said yet. Tried it? Tell the next person.
