What is measured
The ten variables a measurement can return, what each one is, and what it needs before it can be computed.
A measurement produces a pulse signal, and everything else is worked out from it. Some variables come from that signal alone. Others need a still picture of the face. Others again need to know the person’s age, sex or body measurements.
This page says which is which. That is the difference between a variable that is missing and a variable that was never going to arrive.
| Variable | Key | Unit | Value shape |
|---|---|---|---|
| Heart rate | hr | bpm | { mean } |
| Breathing rate | br | cpm | { mean } |
| Heart rate variability | hrv | ms | { mean } |
| Stress level | strs | — | { level, scale } |
| Blood pressure | bp | mmHg | { systole, diastole } |
| Blood pressure risk | bpClass | — | { level, scale } |
| Visual age | physicalAge | years | number |
| Body mass index | bmi | kg/m² | number |
| BMI from face | faceBmi | kg/m² | number |
| Cardiovascular health score | healthScore | — | number |
What each one is
Heart rate, breathing rate and heart-rate variability come straight from the pulse wave. hr counts beats per minute over the capture. br counts breaths per minute, which is why the upper chest has to be visible. hrv measures how much the gap between two beats varies, in milliseconds.
Stress is a level on a scale, not a count. The value is { level, scale }, the scale being a { min, max } pair: for stress it runs from 1 to 5, so a level of 2 is the second band out of five. Always read the scale rather than assuming it.
Blood pressure comes in two forms. bp is an estimated pair of systolic and diastolic values, in mmHg, and it needs a calibration for the person being measured (see below). bpClass is a risk band, in the same { level, scale } shape as stress, on three bands by default. A product that shows a range rather than two numbers usually wants bpClass.
Visual age (physicalAge) is estimated from the face, in years. When you supply the person’s age, the value returned stays within three years of it.
Body mass index exists twice, and the difference matters. bmi is the arithmetic one, computed from the height and weight you supply. faceBmi is estimated from the picture of the face. They answer the same question by two different routes, so an integration that already has the person’s measurements has no reason to ask for the second.
Cardiovascular health score (healthScore) is a single figure that combines several of the others.
What each one needs
| Variable | Saphere Scan | Video API | Image API | Needs userData |
|---|---|---|---|---|
hr — heart rate | Yes | Yes | — | — |
br — breathing rate | Yes | Yes | — | — |
hrv — heart-rate variability | Yes | Yes | — | — |
strs — stress | Yes | Yes | — | — |
bp — blood pressure | Yes | Yes | — | externalId, and a calibration |
bpClass — blood pressure risk | Yes | Yes | — | weight, height, sex, age |
physicalAge — visual age | Yes | Yes | — | — |
faceBmi — body mass index from the face | Yes | — | Yes | — |
bmi — body mass index, computed | Yes | Yes | Yes | weight, height |
healthScore — cardiovascular score | Yes | Yes | — | weight, height, sex, age, smokingStatus |
The three middle columns are three routes to the same variables: the widget, a recorded video sent to the API, and a still image sent to the API. faceBmi is the one that comes from an image rather than from a video, because it is estimated from the face and not from the pulse. bmi needs neither: it is arithmetic on the height and weight you supply, so every route computes it.
The limits of each userData field are listed on the measurements page. The widget collects the same fields on its personal-information form, which is off by default, or takes them from your own code through createMeasureOptions.
bp is the one variable that also needs a history. It is computed against a calibration: an earlier measurement of the same person — the same externalId — recorded together with a reading taken with a blood-pressure monitor. The v1 module’s closing form is what records that reading. Without a calibration, bp comes back with NOT_CALIBRATED; without an externalId, with MISSING_USER_DATA_EXTERNAL_ID.
A missing field costs one variable, not the measurement
A variable that could not be computed comes back with an error code naming what was missing. Everything else finishes normally. You do not lose the heart rate because you did not know the person’s height.Your account decides what actually arrives
The variables an account may receive are configured on the account. A measurement can narrow them, with desiredVariables or unwantedVariables, but never widen them. Each result lists what it was entitled to in returnedVariables.
An empty result usually means no rights, not a failure
A measurement that comes back with a signal but no variables at all is the mark of an account that has been granted none. This is the normal state of a newly created test account. Look at the account before you look at the capture.Two variable names are accepted by the API but can never be granted to an account: physiologicalAge and hrvs. They exist only so that integrations already sending them keep working. Do not build anything on them.