> ## Documentation Index
> Fetch the complete documentation index at: https://developer.neurofit.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Metrics

> What each metric means, its units, the quality and breathing-rate confidence tiers, and the validated accuracy against a Polar H10 chest strap.

One 60-second reading returns the metrics below in a `VitalsResult`. Readings are processed entirely on the
phone with deterministic signal processing, not machine learning. No images are stored or transmitted; the SDK
returns only these metrics, a quality tier and a confidence tier for the breathing rate.

<Note>
  The NEUROFIT Vitals SDK is not a medical device. The metrics describe autonomic and cardiorespiratory state for
  wellness and self-tracking; they do not diagnose, treat or prevent any condition.
</Note>

## Result fields

| Field | Unit | Meaning |
| - | - | - |
| `heartRateBpm` | beats per minute | Mean heart rate over the reading. |
| `rmssdMs` | ms | HRV (RMSSD): the root mean square of successive differences between normal heartbeat intervals. The HRV number wearables report. Higher generally reflects more parasympathetic (rest-and-digest) activity. |
| `sdnnMs` | ms | SDNN: the standard deviation of normal heartbeat intervals over the reading. Reflects overall variability. |
| `baevskyStressIndex` | dimensionless | Baevsky stress index. Higher values reflect a more rigid, sympathetic-dominant rhythm. Often shown on a log scale. |
| `sd2sd1` | ratio | Poincaré SD2:SD1. The ratio of long-term to short-term variability. It is derived from SDNN and RMSSD (SD1 = RMSSD / sqrt 2; SD2 = sqrt(2 SDNN squared minus SD1 squared)) and is absent when either input is missing or the expression is undefined. |
| `breathingRateBrpm` | breaths per minute | Breathing rate over the reading. Validated for paced breathing at 6 breaths per minute; present free-breathing values as an estimate. |
| `breathingRateConfidence` | tier | `high`, `medium` or `low` (Android `HIGH`, `MEDIUM`, `LOW`). Present exactly when `breathingRateBrpm` is present. See below. |
| `quality` | tier | `clean` (3), `usable` (2) or `withheld` (1). See below. |
| `id`, `capturedAt` | | A unique reading id (iOS `UUID`, Android `String`) and the completion time (iOS `Date`, Android epoch milliseconds). Quote the id if you contact NEUROFIT about a reading. |
| `sdkVersion` | | The SDK that produced the reading, `1.0.0` for this release. Store it with the result. |

Metrics other than heart rate are optional (`nil` / `null`) when they could not be recovered; every value is
finite. Heart rate is the one metric a completed reading always has; a reading with no heart rate ends in
`failed(noHeartRate)` rather than a result.

During the reading, `LivePreview` carries provisional values: heart rate from the first seconds and HRV (RMSSD)
from about 20 s. They are for display only; store the final `VitalsResult`.

## Quality tier

The SDK grades every reading and withholds the ones it cannot stand behind.

| Tier | Meaning | What to do |
| - | - | - |
| `clean` | High-quality signal throughout. | Show the metrics. |
| `usable` | Good signal with some imperfect stretches. Accuracy figures below include both `clean` and `usable` readings. | Show the metrics. |
| `withheld` | The SDK is not confident in the HRV metrics. `rmssdMs`, `sdnnMs`, `baevskyStressIndex` and `sd2sd1` may be absent. | Do not show HRV numbers. Offer a retry. Do not store the reading as an outcome. |

A reading whose values fall outside physiological plausibility is also graded `withheld`, and its `sd2sd1` and
`baevskyStressIndex` are left out.

In the validation study the SDK withheld 3.3% of readings.

## Breathing-rate confidence

Every breathing rate comes with a tier that says how it was measured and how far to trust it.

| Tier | Meaning | What to do |
| - | - | - |
| `high` | Measured from the phone's motion. | Show the rate. |
| `medium` | A strong camera estimate. | Show the rate. |
| `low` | A weaker camera estimate. | Show it as approximate, for example "about 14 breaths per minute". |

The breathing-rate accuracy figure below describes the validation study's higher-confidence camera results.
The tier is separate from the quality tier above.

## Validated accuracy

The figures come from the NEUROFIT validation study: 30 participants, 265 accepted readings, each a 60-second
seated reading taken while wearing a Polar H10 chest strap, with the strap's beat-to-beat timing as the
reference. Half the readings were at rest and half during paced breathing at 6 breaths per minute. Three
readings with frequent irregular heartbeats were excluded. The two investigators are excluded from every figure.

| Metric | Mean absolute error | r | 95% limits of agreement | Notes |
| - | - | - | - | - |
| Heart rate | 0.46 bpm | 0.999 | -1.4 to +0.9 bpm | 90% of readings within 1 bpm |
| HRV (RMSSD) | 3.39 ms | 0.979 | -9.1 to +9.8 ms | 94.7% within 10 ms, none off by 20 ms or more |
| SDNN | 4.13 ms | 0.984 | -9.8 to +12.0 ms | |
| Baevsky stress index (ln) | 0.18 | 0.970 | -0.51 to +0.42 | 76% of readings within 25% of the strap value |
| Poincaré SD2:SD1 | 0.28 | 0.908 | -0.81 to +0.77 | Error tracks RMSSD error |
| Breathing rate (paced 6 brpm) | 0.46 brpm | n/a | n/a | 89% within 1 brpm, on higher-confidence results |

### Consistent across groups

No group had a reading off by 20 ms or more. Groups with one or two people describe those individuals, not the
whole group.

| Group | Participants | Readings | RMSSD error (ms) | Within 10 ms |
| - | - | - | - | - |
| iOS | 21 | 178 | 2.81 | 97% |
| Android | 9 | 87 | 4.58 | 91% |
| Resting | 30 | 134 | 2.98 | 96% |
| Paced breathing | 30 | 131 | 3.80 | 93% |
| Monk skin tone 2 | 4 | 33 | 2.16 | 97% |
| Monk skin tone 3 | 3 | 28 | 1.48 | 100% |
| Monk skin tone 4 | 5 | 46 | 4.14 | 91% |
| Monk skin tone 5 | 9 | 79 | 2.97 | 96% |
| Monk skin tone 6 | 6 | 53 | 5.13 | 91% |
| Monk skin tone 8 | 3 | 26 | 3.39 | 96% |
| Female | 12 | 105 | 3.50 | 95% |
| Male | 18 | 160 | 3.32 | 94% |
| Age 18–24 | 1 | 8 | 2.00 | 100% |
| Age 25–34 | 21 | 181 | 3.66 | 94% |
| Age 35–44 | 5 | 47 | 3.37 | 91% |
| Age 45–54 | 1 | 10 | 1.01 | 100% |
| Age 55–64 | 2 | 19 | 2.70 | 100% |

The full method and plots are in the
[validation report (PDF)](https://neurofit.app/assets/pdf/neurofit-vitals-sdk-validation-report-2026-09.pdf).
These are interim development results; the finished system is being tested blind on new participants, and the
figures will be updated as the study grows.

## Limits of the validation

The accuracy figures apply to **seated, still, 60-second readings**. Not yet claimed:

* Accuracy for Monk skin tones 7, 9 and 10 (no participants in the study so far).
* Accuracy during movement.
* Breathing rate outside paced breathing at 6 breaths per minute.
* Readings shorter or longer than 60 seconds.

Most participants were 25 to 34 years old.

## Presenting the numbers

* Round heart rate and HRV (RMSSD) to whole numbers, breathing rate to one decimal.
* When `breathingRateConfidence` is `low`, mark the breathing rate as approximate.
* Say "HRV (RMSSD)" the first time you show HRV, so users comparing with a wearable know which HRV it is.
* Compare a person with their own baseline, not with population tables; see
  [Outcomes best practices](/outcomes-best-practices).
* When `quality` is `withheld`, show a calm retry prompt rather than a number.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.