Measurements and health data
Use this guide to choose a measurement category, understand its data shape, and read or save values through @ovok/core. Each declared category has a separate page with field details and an app-level example.
The SDK maps supported measurements to FHIR Observation resources. A category key selects the measurement shape; it does not by itself guarantee that the SDK can read or save that category.
Measurement support
The SDK declares 22 measurement category keys. Eighteen currently have a typed observation read mapping and save service. Four are declared keys without a working measurement workflow.
| Category | Key | Read | Save |
|---|---|---|---|
| Blood glucose | bloodGlucose | Yes | Yes |
| Blood pressure | bloodPressure | Yes | Yes |
| ECG | ecg | Yes | Yes |
| Blood oxygen and pulse rate | bloodOxygenPulseRate | Yes | Yes |
| Body weight | bodyWeight | Yes | Yes |
| Body temperature | temperature | Yes | Yes |
| Urine analysis | urineAnalysis | Yes | Yes |
| Uric acid legacy key | uricAcid | Yes, deprecated alias | Yes, deprecated alias |
| Heart rate | heartRate | Yes | Yes |
| Heart-rate variability | heartRateVariability | Yes | Yes |
| Respiratory rate | respiratoryRate | Yes | Yes |
| VO₂ max | vo2Max | Yes | Yes |
| Step count | stepCount | Yes | Yes |
| Resting heart rate | restingHeartRate | Yes | Yes |
| Walking heart-rate average | walkingHeartRateAverage | Yes | Yes |
| Symptom questionnaire | symptomQuestionnaire | No | No |
| COSINUSS multiparameter | cosinussMultiParam | No | No |
| Photo upload | photoUpload | No | No |
| Spirometry panel | spirometryPanel | No | No |
| Lipid panel | lipidPanel | Yes | Yes |
| Respiratory therapy | respiratoryTherapy | Yes | Yes |
| Baby sleep | babySleep | Yes | Yes |
The four unsupported keys are present in the enum only, except that spirometry also has a data shape declaration. None has a complete typed observation read and save workflow. Do not pass them to the measurement hooks or save method and expect the SDK to handle them.
Measurement types
Each linked page documents the category key, public fields, units, read mapping, save behavior, limitations, and an example:
- Blood glucose
- Blood pressure
- ECG
- Blood oxygen and pulse rate
- Body weight
- Body temperature
- COSINUSS multiparameter
- Urine analysis
- Uric acid legacy key
- Heart rate
- Heart-rate variability
- Respiratory rate
- VO₂ max
- Photo upload
- Spirometry panel
- Step count
- Resting heart rate
- Walking heart-rate average
- Symptom questionnaire
- Lipid panel
- Respiratory therapy
- Baby sleep
Read measurements in React
Render the component below OvokProvider and call useObservations() from a client-side component. Pass one or more supported category keys. Use patientId and period to scope the search.
import { MeasurementTypeKey, useObservations } from '@ovok/core';
const types = [
MeasurementTypeKey.bloodGlucose,
MeasurementTypeKey.heartRate,
] as const;
export function HealthReadings({ patientId }: { patientId?: string }) {
const { measurements, observations, loading, error } = useObservations({
types,
patientId,
period: { start: new Date('2026-10-01T00:00:00Z') },
});
if (loading) return <p>Loading readings…</p>;
if (error) return <p role="alert">{error.message}</p>;
return (
<section>
<p>{measurements.length} mapped measurement groups</p>
<p>{observations.length} matching Observation resources</p>
</section>
);
}
The hook returns mapped measurements, the original read-only observations, a loading flag, and an optional error. A single measurement can map to multiple Observations, and one ECG recording or urine strip can contain multiple related resources. Keep the original resources when the interface needs source metadata or effective times not represented in the typed measurement.
If patientId is omitted, the hook does not add a patient filter. Use an explicit patient ID when the screen must be scoped to one patient. See the useObservations reference for the full query options and state behavior.
Save measurements
Use useSaveMeasurement() in React, or call saveMeasurement() on a configured OvokClient from non-component code. Every request needs a typed measurement.
| Request field | Required | Purpose |
|---|---|---|
measurement | Yes | Category key and category-specific values. |
patientId | No | When supplied, targets Patient/{id}. When omitted, the SDK uses the signed-in profile reference, which can be a Patient or Practitioner. |
effectiveDateTime | No | Effective time for categories that use a single observation time. Some categories, such as step count, use measurement-specific interval fields. |
device | No | Device details associated with the observations. |
The shared device shape accepts name, localName, manufacturerData, manufacturerName, model, sn, id, and optional batteryPercentage from 0 to 100.
import { MeasurementTypeKey, OvokClient } from '@ovok/core';
const client = new OvokClient({
baseUrl: 'https://api.sandbox.ovok.com',
fhirUrlPath: '/fhir/R4/',
});
async function saveReading() {
return client.saveMeasurement({
measurement: {
measurementTypeKey: MeasurementTypeKey.heartRate,
heartRate: 72,
},
effectiveDateTime: new Date(),
});
}
Without offline queueing, a completed request returns a saved result or rejects with an error. When the opt-in offline queue is enabled, the result can instead have status: 'queued' and a queue ID. Treat that result as pending until a later queue flush confirms the save. See useSaveMeasurement and offline measurement saves.
Units, precision, and dates
Use the units stated on each category page. Direct SDK saves do not generally convert user-entered units. Some services round values to a documented precision before saving; the page for each category lists that behavior.
Use JavaScript Date values for date fields. The request-level effectiveDateTime applies to categories that store a single effective time. Step counts can specify a start and end interval, ECG uses its recordedAt field for recording time, and urine analysis uses recordedAt for the strip time. See the individual type page for category-specific timing behavior.
Data sources and interpretation
The SDK maps and transports values. It does not establish which devices or platform integrations produce data for a project, interpret a measurement clinically, or diagnose a condition. Data availability depends on the app’s permissions, device source, and project configuration. Check the data ingestion guide for platform-side ingestion behavior.
For the resource format and coded observation representation, see the FHIR Observation reference. Questionnaire answers use a separate QuestionnaireResponse workflow; see the QuestionnaireResponse reference and the symptom questionnaire category page.