Callbacks Reference
The four callbacks the Web SDK exposes — onRealtime, onStage, onResult, onError.
The Web SDK exposes a thin facade: four callbacks. Everything else is internal.
onRealtime(cb)
Fires roughly once per second during a measurement. The payload is a small partial — a live heart rate and the current quality only. Use it to drive live UI; do not treat it as the final result.
m.onRealtime((update) => {
update.heartRate; // number | null (live bpm)
update.quality.level; // "good" | "fair" | "poor"
update.quality.score; // number | null (0..1)
});onStage(cb)
Fires whenever the measurement moves to a new step, from start() until the
result arrives. Use it for progress copy; onRealtime tells you nothing while
the camera and the models are still coming up.
m.onStage((stage) => {
// 'requestingCamera' | 'loadingModels' | 'ready'
// on-device also: 'preparingWorkers' | 'initializingSdk'
// cloud also: 'connecting' | 'uploading' | 'processing'
});'uploading' and 'processing' are cloud-specific and mean the stream did not
survive: the SDK is finishing the measurement as a batch upload. Live metrics
have stopped at that point, so switch the UI over instead of leaving a pulse
frozen on screen. See Cloud overview.
The set is open-ended by design — treat an unrecognized stage as "still working" rather than as an error.
onResult(cb)
Fires once, on completion, with the full measurement result. Metrics are grouped into sections:
m.onResult((result) => {
result.quality.level; // "good" | "fair" | "poor" (required, never null)
result.quality.usable; // boolean
result.cardiac.heartRate.value; // number | null
result.hrv.sdnnMs; // number | null (headline)
result.hrv.rmssdMs; // number | null
result.respiratory.breathingRate.value; // number | null
result.stress.index; // number | null (0..100)
// Beta sections — wellness only, nullable, each carries tier: "beta".
result.bloodPressure.systolicMmHg; // number | null
result.spo2.value; // number | null
result.emotion.dominant; // string | null
result.behavior.attentionPercent; // number | null
result.sdkVersion; // "0.1.0" — this package
result.modelsVersion; // "wv-5" — the model bundle it loaded
});sdkVersion and modelsVersion name the build that produced the numbers. The
SDK fills them in and carries them into the submitted body, so the console can
show which engine versions are live in production; modelsVersion is absent when
a custom driver does not report one. See
Submitting measurements.
Any metric may be null when the capture is unreliable — neccessory returns
null rather than fabricating a number. When quality.level is "poor" every
metric is null: treat that as "no measurement", not "a bad measurement". Always
handle null and respect result.quality.usable. See
Signal quality.
onError(cb)
Fires on any error during setup or measurement. start() reports failures here
rather than rejecting, so this single path covers both.
m.onError((err) => {
err.code; // a short machine-readable code
err.message; // a human-readable message (no internal details)
});Next: Configuration.