Raw metrics tell you what happened. Scores tell you what it means. Sonar computes eight health scores from the normalized data in the catalog — each a value from 0 to 100, updated in real time as new data arrives.
Available Scores
| Score | What it measures | metric_id |
|---|---|---|
| Recovery | Readiness for physical exertion | recovery_score |
| Strain | Cumulative daily load | strain_score |
| Sleep | Sleep quality and consistency | sleep_score |
| Stress | Physiological stress burden | stress_score |
| Inactive Stress | Stress during waking inactivity | inactive_stress_score |
| Sleep Stress | Stress during sleep | sleep_stress_score |
| Energy Reserve | Available energy for activity | energy_reserve_score |
| Nutrition | Nutritional intake balance | nutrition_score |
The overall stress_score is the daily average across both Inactive Stress and Sleep Stress. All score metric_ids and their key inputs are listed in the Data Catalog.
How Scores Work
Every score is a 0–100 value normalized against population baselines — a recovery score of 78 means the same thing regardless of the user. Scores recompute automatically whenever new underlying data arrives, typically within minutes of a device sync.
Each score response includes a factors array that explains why the score has its current value — which inputs contributed, how much, and in which direction. This lets you build explainable health UIs rather than opaque numbers.
Personalized baselines. Scores adapt to the individual. Rather than comparing against fixed thresholds, Sonar builds rolling baselines from each user's own history — a resting heart rate of 55 bpm might be normal for one user and a red flag for another. The longer a user is connected, the more personalized the scores become.
Real-time granularity. All scores recompute when new data arrives. Stress and Energy Reserve additionally operate at 6-minute intervals — giving you the resolution to build real-time dashboards, not just daily summaries.
Partial data resilience. When some inputs are missing, scores adjust their internal weighting rather than returning nothing. A Recovery score with only sleep data is less precise than one with sleep, HRV, and resting heart rate — but it still computes.
Score Details
Recovery
Recovery combines five factors: sleep quality, overnight vitals (HRV and heart rate trends), sickness detection, previous day's strain, and heart rate dip. Sleep vitals carry the most weight — they're the strongest signal of autonomic recovery.
The sickness detection component monitors respiratory rate, body temperature, and blood oxygen against the user's personal baselines. When vitals deviate abnormally, Recovery drops — often before the user feels symptoms. This makes Recovery useful not just for training readiness, but as an early health warning system.
Strain
Strain measures cumulative cardiovascular load throughout the day. It's driven by heart rate relative to the user's own max HR and resting HR — higher intensities contribute disproportionately more than low-level activity. A 30-minute run might add as much strain as several hours of walking.
The curve is intentionally nonlinear: easy activity barely moves the needle, moderate effort builds steadily, and high-intensity work drives strain up fast. This mirrors how the body actually accumulates fatigue.
Sleep
Sleep is a composite of three subscores: sleep quality (efficiency, deep sleep, REM, and sleep bank), sleep vitals (how HRV and heart rate recovered overnight compared to the user's baseline), and timing consistency (how regular the sleep schedule is).
Quality carries the most weight — a user who gets enough deep and REM sleep in an efficient session will score well even with slight schedule variation. Timing consistency can only reduce the score, not improve it — it acts as a penalty for irregular schedules, reflecting the science on circadian rhythm disruption.
Stress
Stress analyzes heart rate and HRV variations in real time, updating every 6 minutes with smoothing to filter noise while preserving real changes. It uses different sensitivity models for daytime and sleep — the same physiological signal means different things depending on context.
Workout periods are excluded automatically — elevated HR during exercise isn't stress. The daily stress_score averages across the full day, while sleep_stress_score and inactive_stress_score let you see when stress occurs.
Energy Reserve
Energy Reserve models the body's available energy as a continuous 0–100 value that rises during sleep, drops during workouts, and fluctuates with stress throughout the day. Like Stress, it updates at 6-minute intervals.
The model is context-aware: recovery rate during sleep depends on how depleted the user is (faster when exhausted, slower when already charged), workout discharge scales with intensity, and sustained stress gradually drains energy even without physical activity. The result is an intuitive "battery level" that reflects how the user actually feels.
Nutrition
Nutrition scores daily intake against personalized macro targets generated from the user's demographics (age, sex, height, weight) and health goal — weight loss, athletic performance, or general wellness. Each goal shifts the balance between calories, protein, carbs, fat, and fiber.
Scoring uses a bell-curve model centered on each target — hitting the target scores highest, and deviations in either direction reduce the score. Eating too little protein is just as penalized as eating too much. This rewards balanced nutrition rather than just caloric restriction.
Output Schema
Current Scores
Query the latest scores for a user. Scores recompute automatically as new data arrives.
GET /v1/users/{user_id}/scores
{
"data": [
{
"type": "recovery_score",
"value": 78,
"computed_at": "2026-03-01T08:30:00Z",
"factors": [
{ "name": "hrv_trend", "contribution": 0.35, "direction": "positive" },
{ "name": "sleep_quality", "contribution": 0.28, "direction": "positive" },
{ "name": "resting_heart_rate", "contribution": 0.22, "direction": "neutral" }
]
},
{ "type": "strain_score", "value": 42, "computed_at": "2026-03-01T14:00:00Z", "factors": [] },
{ "type": "sleep_score", "value": 85, "computed_at": "2026-03-01T08:30:00Z", "factors": [] },
{ "type": "stress_score", "value": 22, "computed_at": "2026-03-01T14:00:00Z", "factors": [] },
{ "type": "nutrition_score", "value": 65, "computed_at": "2026-03-01T12:00:00Z", "factors": [] },
{ "type": "energy_reserve_score", "value": 71, "computed_at": "2026-03-01T14:00:00Z", "factors": [] }
]
}
Score History
Query daily score values over a date range. Use this to build trend charts or compare periods.
GET /v1/users/{user_id}/scores/history?types=recovery_score,sleep_score&start_date=2026-02-01&end_date=2026-02-28
{
"data": [
{ "date": "2026-02-01", "type": "recovery_score", "value": 68 },
{ "date": "2026-02-01", "type": "sleep_score", "value": 74 },
{ "date": "2026-02-02", "type": "recovery_score", "value": 78 },
{ "date": "2026-02-02", "type": "sleep_score", "value": 85 }
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
types |
string | no | Comma-separated score types (default: all). E.g., recovery_score,sleep_score |
start_date |
string | yes | Start date (ISO 8601) |
end_date |
string | yes | End date (ISO 8601) |
To react when scores recompute — for example, refreshing a dashboard or triggering a push notification — configure a webhook and Sonar will notify your server whenever a score updates. See Data Delivery.
Data Requirements
Sonar computes scores with whatever data is available — scores become more accurate as more data flows in. A minimum of 24 hours of data is needed for the first computation.
| Score | Minimum data needed |
|---|---|
| Recovery | Sleep data + overnight heart rate or HRV |
| Strain | Heart rate data |
| Sleep | A sleep session with duration |
| Stress | Heart rate or HRV data (both improve accuracy) |
| Energy Reserve | Vitals and sleep history (reaches full accuracy after ~14 days) |
| Nutrition | At least one macronutrient or caloric entry |
Frequently Asked Questions
How long until scores are fully personalized? Scores start computing after 24 hours. Baseline-dependent features like sickness detection and sleep vitals comparison reach full accuracy after about 4 weeks of data, as the rolling baselines stabilize.
Can scores go down when more data arrives? Yes. Scores always reflect the latest full picture. A mid-day strain score might change as afternoon activity comes in, and Recovery will drop if overnight vitals indicate poor autonomic recovery — even if sleep duration was adequate.
Do scores work with any device? Scores compute from whatever metrics are available in the Data Catalog. A device that provides heart rate, HRV, and sleep stages will power most scores. Nutrition scores require a connected nutrition app. See Data Requirements for specifics.
Go Deeper
- Data Catalog — All 70+ metrics that feed into score computation
Sonar