Loading...

Client Success Intelligence

Turn every renewal from "trust us" to "here's what you got."
When a sponsor asks "what did I get for my $50K?" — you have the answer in one click. DataOS connects every sponsorship to government contacts captured and contract awards influenced. Renewals stop being a pitch and start being a proof.
Active Sponsors
...
Median Health Score
...
Revenue at Risk
...
High-Risk Accounts
...
Expansion Candidates
...
Customer Health Score Distribution Composite Score
Loading health scores…
A 0–100 composite blending churn risk (M2 model), product usage tier, health-check cadence, onboarding execution, Insider strategic-call cadence, QBR cadence, pipeline health, and account tenure. Each account's top drivers column shows which 3 components are pulling the score down — that's where the CSM should act.
CS Operations KPIs — accounts
KPI Coverage Numerator Denominator Target vs Target
Loading…
Median time to first onboarding outreach
CSM Leaderboard (top 10 by accounts) Live
CSM Owner ID Accounts Health-check coverage (30d) Onboarded on time
Loading…
Email Engagement Coverage — accounts
KPI Coverage Numerator Denominator Target vs Target
Loading…
Cohort Engagement Rates Live
Renewal Forecast Accuracy Backtest
Cohort Quarter Contracts Actually Churned Flagged ≥60d Early-Warning Rate Predicted Churn Actual Churn Variance (pp)
Loading…
Built nightly by snapshotting churn_probability into ml/churn_snapshots.parquet. For every contract whose end-date has passed, we look back ~60 days and compare what the model said to the actual renewal outcome. Targets: early-warning rate ≥75%, forecast variance ±5pp.
Churn Risk Breakdown ML Model
Loading churn analysis…
Total Revenue at Risk
Combined revenue from accounts showing high or medium churn signals. The ML model identifies accounts with declining engagement, shrinking spend, or deteriorating usage patterns.
At-Risk Accounts 0 accounts
Account Name Health Revenue Risk Level Revenue at Risk Top Drivers Tenure
Loading…
Cross-Sell Expansion Signals ML Model
Loading expansion signals…
The cross-sell model identifies accounts likely to add product categories based on their engagement history, peer behavior, and procurement signals. Higher probability scores indicate stronger expansion opportunity.
Subscription Products Live
Loading product data…
Usage Tiers ML Model
Loading usage tiers…
Subscription Growth ML Model
Loading subscription growth…
Customer Health Score — Build Plan README
This page is the operational surface for the Customer Health Score initiative authored by Angela Fultz Nordstrom. It blends the existing ML stack (churn risk, usage tier, expansion probability) with per-account CS-Operations cadence (onboarding, health checks, QBRs, Insider strategic calls) to produce a composite 0–100 score per account, plus a backtest of the renewal forecast itself. Below is what's already shipped, what's in warmup, and what still requires new data integration.
✓ Shipped — Sprint 1 Live on this page
Capability Where it lives How it's built
Composite Health Score (0–100)
8 components, transparent weights
Health Score tab + at-risk table column etl/build_account_health_score.pyindexes/index_account_health_score.parquet. Blends churn (M2), usage tier, health-check cadence, onboarding execution, Insider calls, QBR cadence, pipeline health, and tenure.
CS Operations KPIs
6 KPIs vs Angela's targets
CS Operations tab etl/build_cs_activity_index.pyindexes/index_cs_activity_monthly.parquet + indexes/index_cs_account_summary.parquet. Sources activities.parquet (Salesforce custom fields: Activity_Type__c, Health_Check_Type__c) joined to ml_contracts.parquet for the StartDate anchor.
CSM Leaderboard
Per-owner cadence rollup
CS Operations tab Same activity index, grouped by OwnerId.
At-Risk drill enriched At-Risk Accounts tab Adds Health Score, Score Band, Top Drivers columns by joining index_account_health_score on the existing churn-risk filter.
Renewal forecast accuracy
Snapshots churn predictions nightly for 60-day backtest
Forecast Accuracy tab etl/build_renewal_forecast_accuracy.py appends to ml/churn_snapshots.parquet (rolling 365d) and publishes per-quarter cohorts to indexes/index_renewal_forecast_accuracy.parquet.
⏱ In Warmup — Code shipped, awaiting data Warmup
Capability Status What it needs
≥60-day early-warning rate Snapshotting now The backtest needs ≥60 days of accumulated ml/churn_snapshots.parquet history. First eligible cohort lands ~60 days after the first nightly run that included build_renewal_forecast_accuracy. The Forecast Accuracy tab shows the warmup ETA.
Per-account email engagement
Open / click / QBR coverage / value-driven email coverage
Awaiting HubSpot ETL run Three new extractors are wired into master_etl.run_hubspot_etl: hubspot_entities (Contact + Company + Engagement) and hubspot_email_events (CampaignEmailEvent rolling 90-day, chunked watermark). The downstream rollup etl/build_account_email_engagement.py is also live in build_all_indexes. All three skip silently when their parquets are missing — running the master ETL once on the local network (where the HubSpot Azure SQL firewall allows) is enough to light up the Engagement tab.
○ Not Yet Built — Requires New Data Source Roadmap
Capability Source needed Plan
Training Satisfaction Score
NPS / CSAT
Alchemer surveys New extractor etl/alchemer_surveys.py to pull survey responses from the Alchemer REST API, joined on Email back to HubSpot Contact → Company → SF account. Adds a 7th component (component_csat) to the Health Score and a CSAT trend column to the at-risk table. ETA: 1 sprint once Alchemer API credentials are issued.
Direct product usage telemetry
Navigator + Insider login activity, per-feature usage
Product event logs (Mixpanel / app DB) Today's usage_tier is ML-derived from product history (procurements, attribution). True usage telemetry would replace it with measured logins / saved-search count / report downloads per account, sharpening the component_usage signal. Net-new ETL etl/product_usage_events.py; blocked on getting an event-stream consumer in place.
Onboarding training completion within 30d Alchemer + LMS The Salesforce activity classifier already detects training tasks (Activity_Type__c LIKE '%Training%'). The missing piece is completion confirmation — currently tracked in Alchemer post-training surveys. Same ETL as the Training Satisfaction work above.
Health Score account-detail drill
Click any account → see all 8 components + history
None — UI work Component scores are already in index_account_health_score.parquet. Build a modal or side panel triggered by clicking the Health column, rendering the 8 components as a radar chart with each component's source links (e.g. "cadence: see last 5 health-checks → /api/account/<id>/activities?type=health_check").
Score history / trend lines None — needs nightly snapshot accumulation The build_account_health_score ETL doesn't yet snapshot its output. Mirror the build_renewal_forecast_accuracy pattern: append the per-account score nightly to indexes/index_account_health_score_history.parquet, then render a sparkline next to each at-risk row.
CS playbook automation
"Account dropped from Healthy → Watch → ping CSM"
None — needs notifications wiring Once score history is logged (above), a daily diff job can fire Slack / email alerts via the existing core.notifications service. Similar to the existing pipeline-stall alerts — just keyed on score_band transitions.
⚙ How to Extend the Score Dev Notes

The composite score is intentionally a transparent weighted sum, not a learned model — when CS asks "stop counting QBR cadence so heavily" we flip a number, not retrain. To retune:

  1. Edit WEIGHTS at the top of etl/build_account_health_score.py. Must sum to 100.
  2. Re-run python -m etl.build_account_health_score — finishes in <5 s on the active customer cohort (~1K accounts).
  3. Refresh this page; the bands and at-risk drivers recompute against the new weights on the next API hit.

To add a 9th component (e.g. survey CSAT once Alchemer lands): implement a _component_csat() expression that returns a 0–100 polars column, register it in the WEIGHTS dict, and add the label to _DRIVER_LABELS so the top-3-drivers column picks it up. Cohort-only components return None for out-of-cohort accounts so the weighted average normalizes correctly — see _component_insider for the pattern.

Notifications

No notifications

Create Opportunity

DATA OS

Opportunity Created

DataOS
Install DataOS Add to home screen for quick access
All Features