Skip to content

Query Health Data

import { Aside, Tabs, TabItem } from ‘@astrojs/starlight/components’;

VitaSync provides five health data endpoints that cover different query patterns — from raw data points to aggregated timeseries and per-day statistics.

All health endpoints require at minimum read scope.

GET /v1/users/{userId}/health
GET /v1/users/{userId}/health/summary
GET /v1/users/{userId}/health/timeseries
GET /v1/users/{userId}/health/daily-summaries
DELETE /v1/users/{userId}/health

Returns individual data points for a user, optionally filtered by metric type and date range.

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../health?metricType=steps&from=2025-06-01&to=2025-06-07&limit=100" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Query parameters:

ParameterTypeDefaultDescription
metricTypestringFilter to a single metric type (see full list below)
fromISO 8601 dateStart of the date range (inclusive)
toISO 8601 dateEnd of the date range (inclusive)
limitinteger100Records per page (1–1000)
offsetinteger0Skip N records (offset-based pagination)
cursorstringCursor for cursor-based pagination (see next page token)

Response (200 OK):

{
"data": [
{
"id": "01JA4MNPQR8STUVWXYZ00010",
"userId": "01JA4MNPQR8STUVWXYZ00001",
"providerId": "fitbit",
"metricType": "steps",
"value": 9823,
"unit": "count",
"recordedAt": "2025-06-06T00:00:00.000Z",
"data": null,
"source": "user",
"createdAt": "2025-06-07T09:00:00.000Z"
},
{
"id": "01JA4MNPQR8STUVWXYZ00011",
"userId": "01JA4MNPQR8STUVWXYZ00001",
"providerId": "fitbit",
"metricType": "steps",
"value": 12401,
"unit": "count",
"recordedAt": "2025-06-05T00:00:00.000Z",
"data": null,
"source": "user",
"createdAt": "2025-06-06T09:00:00.000Z"
}
],
"total": 42,
"limit": 100,
"offset": 0,
"nextCursor": "eyJpZCI6IjAxSkE0Li4uIn0="
}

Response fields:

FieldDescription
dataArray of metric data points
metricTypeThe type of metric (see full list below)
valueScalar value for simple metrics (steps, HR, weight, etc.)
unitUnit for the value (e.g. count, bpm, kg, meters)
dataStructured JSON for complex metrics (sleep stages, blood pressure, etc.) — null for scalar metrics
recordedAtWhen the metric was recorded by the device
sourceuser (device-measured), manual (user-entered), or computed
totalTotal matching records (for offset pagination UI)
nextCursorBase64 cursor for fetching the next page (null when no more pages)

Some metrics use the data JSONB field instead of value for structured information:

Sleep:

{
"metricType": "sleep",
"value": 7.4,
"unit": "hours",
"data": {
"stages": {
"deep": 95,
"light": 220,
"rem": 110,
"awake": 20
},
"efficiency": 88,
"startTime": "2025-06-05T23:30:00.000Z",
"endTime": "2025-06-06T07:05:00.000Z"
}
}

Blood Pressure:

{
"metricType": "blood_pressure",
"value": null,
"unit": "mmHg",
"data": {
"systolic": 118,
"diastolic": 76,
"pulse": 68
}
}

Heart Rate (intraday):

{
"metricType": "heart_rate",
"value": 72,
"unit": "bpm",
"data": {
"min": 48,
"max": 142,
"resting": 58,
"intraday": [
{ "time": "2025-06-06T08:00:00.000Z", "value": 72 },
{ "time": "2025-06-06T08:01:00.000Z", "value": 74 }
]
}
}

Returns the count of data points per metric type for a user. Useful for quickly checking what data is available.

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../health/summary" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Response (200 OK):

{
"steps": 42,
"heart_rate": 1440,
"resting_heart_rate": 30,
"sleep": 28,
"calories": 42,
"weight": 15,
"blood_oxygen": 30,
"heart_rate_variability": 28,
"workout": 12
}

Returns metric values bucketed over a time range. Useful for charting trends.

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../health/timeseries?metricType=steps&from=2025-06-01&to=2025-06-30&bucket=day" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Query parameters:

ParameterTypeRequiredDefaultDescription
metricTypestringYesThe metric type to aggregate
fromISO 8601YesStart of the range
toISO 8601YesEnd of the range
bucketstringNodayTime bucket size: minute, hour, day, week, or month

Response (200 OK):

{
"metricType": "steps",
"bucket": "day",
"from": "2025-06-01T00:00:00.000Z",
"to": "2025-06-30T00:00:00.000Z",
"data": [
{ "timestamp": "2025-06-01T00:00:00.000Z", "value": 8241, "count": 1 },
{ "timestamp": "2025-06-02T00:00:00.000Z", "value": 10532, "count": 1 },
{ "timestamp": "2025-06-03T00:00:00.000Z", "value": null, "count": 0 },
{ "timestamp": "2025-06-04T00:00:00.000Z", "value": 7890, "count": 1 }
]
}

Gaps (days with no data) are included as null values so chart rendering remains continuous.


Returns per-day totals for one or more metrics. More efficient than fetching each metric separately when building a daily dashboard.

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../health/daily-summaries?from=2025-06-01&to=2025-06-07&metricTypes=steps,calories,heart_rate" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Query parameters:

ParameterTypeRequiredDescription
fromISO 8601YesStart date
toISO 8601YesEnd date
metricTypescomma-separated stringNoFilter to specific metric types. Omit to return all available types

Response (200 OK):

[
{
"date": "2025-06-01",
"metrics": {
"steps": { "value": 8241, "unit": "count" },
"calories": { "value": 1892, "unit": "kcal" },
"heart_rate": { "value": 72, "unit": "bpm", "min": 48, "max": 142 }
}
},
{
"date": "2025-06-02",
"metrics": {
"steps": { "value": 10532, "unit": "count" },
"calories": { "value": 2104, "unit": "kcal" },
"heart_rate": { "value": 68, "unit": "bpm", "min": 52, "max": 118 }
}
}
]

Workouts, sleep sessions, and other structured events are separate from raw health metrics. They live in the events API:

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../events?eventType=workout&from=2025-06-01&to=2025-06-30&limit=20" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Query parameters:

ParameterTypeDefaultDescription
eventTypeworkout, sleep, activityFilter by event type
activityTypestringFor workouts: e.g. running, cycling, swimming
fromISO 8601Start date
toISO 8601End date
limitinteger501–200 events per page
cursorstringCursor for pagination

Response:

{
"data": [
{
"id": "01JA4MNPQR8STUVWXYZ00050",
"eventType": "workout",
"activityType": "running",
"startedAt": "2025-06-06T06:00:00.000Z",
"endedAt": "2025-06-06T06:45:00.000Z",
"durationSeconds": 2700,
"distanceMeters": 7200,
"caloriesKcal": 520,
"avgHeartRate": 158,
"maxHeartRate": 181,
"providerId": "garmin",
"data": {
"elevationGain": 85,
"avgPace": "6:15",
"laps": [
{ "distance": 1000, "time": 375, "avgHR": 152 }
]
}
}
],
"nextCursor": "eyJpZCI6IjAx..."
}

VitaSync automatically tracks personal bests per metric type, updated after every sync.

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../personal-records" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Response:

[
{
"metricType": "steps",
"category": "daily_max",
"value": 18432,
"unit": "count",
"recordedAt": "2025-05-12T00:00:00.000Z",
"providerId": "fitbit"
},
{
"metricType": "heart_rate_variability",
"category": "daily_max",
"value": 68,
"unit": "ms",
"recordedAt": "2025-04-20T00:00:00.000Z",
"providerId": "whoop"
}
]

Get the record for a specific metric:

Terminal window
curl "https://api.yourdomain.com/v1/users/01JA4.../personal-records/steps?category=daily_max" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Permanently deletes all health metrics for a user. This is irreversible. Requires admin scope.

Terminal window
curl -X DELETE "https://api.yourdomain.com/v1/users/01JA4.../health" \
-H "Authorization: Bearer $VITASYNC_API_KEY"

Response (200 OK):

{
"deleted": 14732
}

This deletes health metrics only. To delete the user record itself, use DELETE /v1/users/:userId.


Metric TypeUnitDescription
stepscountDaily step count
distancemetersDistance traveled
calorieskcalActive calories burned
active_minutesminutesMinutes in moderate+ activity zones
floorscountFloors climbed (Fitbit only)
Metric TypeUnitDescription
heart_ratebpmHeart rate samples (may include intraday in data)
resting_heart_ratebpmDaily resting heart rate
heart_rate_variabilitymsHRV (typically overnight RMSSD)
Metric TypeUnitDescription
sleephoursTotal sleep duration; stage breakdown in data field
sleep_scorescoreProvider composite sleep quality score (0–100)
Metric TypeUnitDescription
weightkgBody weight
body_fatpercentBody fat percentage
bmiindexBody mass index
blood_oxygenpercentBlood oxygen saturation (SpO2)
blood_pressuremmHgSystolic/diastolic in data field
temperaturecelsiusSkin or body temperature
blood_glucosemmol_lBlood glucose level
Metric TypeUnitDescription
stressscoreStress level (Garmin: 0–100)
hrv_statusstatusText HRV status band (WHOOP/Garmin)
recovery_scorepercentWHOOP recovery percentage (0–100)
readiness_scorescoreOura-style readiness (0–100)
strain_scorescoreWHOOP daily strain (0–21)
Metric TypeUnitDescription
respiratory_ratebreaths_per_minBreaths per minute (typically overnight)
spo2percentPulse oximetry reading
Metric TypeDescription
workoutIndividual workout session (use the Events API for structured data)