nil (iOS) or null (Android). Understanding this behaviour up front saves debugging time and ensures your app handles the field gracefully in production.
How It Is Derived
Each breath causes subtle, cyclical changes in the amplitude and baseline of the PPG waveform — a phenomenon known as respiratory modulation of the PPG. The SDK analyses this modulation across the 60-second scan window to extract a breathing frequency. Because the modulation can be weak or irregular (particularly during spontaneous free breathing or when the user breathes shallowly), the SDK applies a confidence threshold before committing to a value. Only when the extracted respiratory signal meets that threshold isbreathingRate populated.
Validated Accuracy
Validation was conducted under paced breathing at 6 breaths per minute — a controlled condition that produces a strong, regular respiratory modulation in the PPG signal.SDK Field Reference
breathingRate is a nullable Double? on the VitalsResult object on both platforms. Even when qualityTier is .accepted / QualityTier.ACCEPTED, breathingRate may be absent.
- Swift (iOS)
- Kotlin (Android)
Interpreting the Value
Normal resting breathing rate ranges for adults
Normal resting breathing rate ranges for adults
At rest, a healthy adult typically breathes between 12 and 20 times per minute. Values below 12 breaths/min (bradypnea) can appear in individuals who practice slow, deep breathing or meditation. Values above 20 breaths/min at rest (tachypnea) can be caused by anxiety, exertion, or physiological factors.Because the SDK’s breathing rate is validated under paced conditions at 6 breaths/min, values within the normal resting range (12–20 breaths/min) should be interpreted as indicative rather than precise until free-breathing validation data is published.
Why did my user not get a breathing rate?
Why did my user not get a breathing rate?
There are several reasons the confidence gate might withhold a breathing rate even in an accepted scan:
- Irregular breathing pattern: if the user was speaking, sighing, or breathing unevenly during the scan, the respiratory modulation in the PPG will be inconsistent.
- Very fast or very shallow breathing: rapid or shallow breaths produce weaker PPG modulation and may not clear the confidence threshold.
- Motion artifact: finger movement during the scan can obscure the low-amplitude respiratory signal even when the stronger cardiac signal remains usable.
- Individual physiology: some people naturally produce weaker respiratory PPG modulation than others.
Displaying breathing rate in your UI
Displaying breathing rate in your UI
Because
breathingRate is nullable, avoid designing a UI that treats its presence as guaranteed in every accepted scan. Recommended patterns include:- Displaying a ”—” or ”—” placeholder with a short label such as “Not detected this session” when the value is absent.
- Offering a tooltip or help text explaining that breathing rate requires a stronger signal than other metrics and may not always appear.
- Not flagging the absence of a breathing rate as an alert or warning — it is normal and expected in a meaningful fraction of accepted scans.
Neurofit Vitals is not a medical device. The
breathingRate value is intended for general wellness and fitness applications only, and must not be used for clinical diagnosis, treatment decisions, or monitoring of any medical condition.