Platform
Biometrics API
Five signal families, sampled on the finger, typed end to end.

Signal families
Every metric the API serves belongs to one of five families. Each family is a separately grantable scope, so the wearer can share heart rate without sharing sleep. Request only the families your product reads.
| Name | Type | Description |
|---|---|---|
| hr | bpm · 1 Hz | Heart rate from the optical sensor, smoothed over 5 seconds. Requires biometrics:hr. |
| hrv | ms · 5 min | Heart rate variability as RMSSD and SDNN over rolling 5-minute windows. Requires biometrics:hrv. |
| temp | °C · 1 min | Skin temperature deviation from the wearer's rolling baseline, not absolute temperature. Requires biometrics:temp. |
| motion | class · 1 Hz | Activity classification (still, walk, run, cycle) plus step and cadence counters. Requires biometrics:motion. |
| sleep | stage · 30 s | Sleep stages (awake, light, deep, rem) with nightly summaries after wake. Requires biometrics:sleep. |
Unit and on-device sample rate per family. The scope named in each row is what the wearer sees and grants.
Read a window
Query any family over a time range. Points come back typed, with a per-point confidence score, and the response is stable across SDK versions.
/v1/biometrics/{signal}import { Vexo } from "@vexoring/sdk";
const vexo = new Vexo({ token: process.env.VEXO_USER_TOKEN }); // vx_user_9f2k...
const window = await vexo.biometrics.read("hrv", {
from: "2026-07-17T22:00:00Z",
to: "2026-07-18T06:00:00Z",
resolution: "5m",
});
console.log(window.points.length); // 96
console.log(window.points[0]);
// {
// ts: "2026-07-17T22:00:00Z",
// rmssd: 61,
// sdnn: 54,
// confidence: 0.97
// }Query parameters
| Name | Type | Description |
|---|---|---|
| fromrequired | RFC 3339 timestamp | Start of the window, inclusive. |
| torequired | RFC 3339 timestamp | End of the window, exclusive. Windows cap at 31 days per request. |
| resolution | string | Point spacing: raw, 1m, 5m, 1h, or 1d. Requests below a family's native rate return the native rate.Default: 5m |
Subscribe
For live use, subscribe to one or more families over a single websocket. Events arrive as each family's native window closes, so an hrv subscription ticks every five minutes and motion ticks every second.
const sub = vexo.biometrics.subscribe(["hrv", "temp"], (event) => {
if (event.signal === "hrv" && event.rmssd < 40) {
flagRecoveryDip(event.wearer, event.ts);
}
if (event.signal === "temp" && event.deviationC > 0.6) {
flagTempDeviation(event.wearer, event.ts);
}
});
// Revocation closes the socket with code 4403 within five seconds.
sub.on("close", ({ code }) => {
if (code === 4403) stopProcessing();
});Sampling and precision
The ring samples its optical and thermal sensors far faster than the API's published rates, then downsamples on-device to save battery and bound what leaves the wearer's hand. Published rates are the contract: they hold across firmware versions, and every point carries a confidence score from 0 to 1. Points below 0.8 confidence are flagged, never silently dropped.
On-device processing
Signal fusion, baseline modeling, and stage classification all run on the ring's coprocessor. The API is a read surface for derived metrics, not a pipe to the sensors.
