Wellness
Daily health: steps, heart rate, sleep, HRV, stress, SpO2, respiration, hydration, blood pressure and intensity minutes. Most take a calendar date.
Every method below hangs off a Garmin instance. See Installation & setup for how to construct one:
import { GarminClient, Garmin, FileTokenStore } from "garminconnect-js";
const client = new GarminClient({ tokenStore: new FileTokenStore("./tokens") });
if (!(await client.loadTokens())) throw new Error("not connected to Garmin");
const garmin = new Garmin(client);
31 methods. The verification column says what has been
confirmed against a live Garmin account, not merely unit-tested —
AGENTS.md carries the full evidence per method.
| Method | Verified |
|---|---|
addHydrationData | live-verified |
deleteBloodPressure | live-verified |
getAllDayEvents | live-verified |
getAllDayStress | live-verified |
getBloodPressure | live-verified |
getBodyBattery | live-verified |
getBodyBatteryEvents | live-verified |
getCaloriesDaily | live-verified |
getDailyStats | live-verified |
getDailySteps | live-verified |
getFloors | live-verified |
getHeartRates | live-verified |
getHrvData | live-verified |
getHrvDataRange | live-verified |
getHydrationData | live-verified |
getIntensityMinutesData | live-verified |
getRespirationData | live-verified |
getRhrDaily | live-verified |
getRhrDay | live-verified |
getSleepDaily | live-verified |
getSleepData | live-verified |
getSpo2Data | live-verified |
getStats | live-verified |
getStatsAndBody | live-verified |
getStepsData | live-verified |
getStressData | live-verified |
getUserSummary | live-verified |
getWeeklyIntensityMinutes | live-verified |
getWeeklySteps | live-verified |
getWeeklyStress | live-verified |
setBloodPressure | live-verified |
addHydrationData
garmin.addHydrationData(valueInMl: number, when?: Date, cdate?: string | Date): Promise<HydrationLogResult | null>
const result = await garmin.addHydrationData(1);
Returns
HydrationLogResult — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
raw milliliters, magnitude capped at 10000, negative values allowed; no delete endpoint exists, so not safely round-trippable
Verification: live-verified
deleteBloodPressure
garmin.deleteBloodPressure(version: number | string, cdate: string | Date): Promise<unknown>
const result = await garmin.deleteBloodPressure(activityId, "2026-09-24");
Returns
unknown — Garmin's response is passed through unparsed. Cast it to whatever you need; this library does not model it.
deletes one reading by its version, taken from getBloodPressure
Verification: live-verified
getAllDayEvents
garmin.getAllDayEvents(cdate: string | Date): Promise<DailyEventsData | null>
const result = await garmin.getAllDayEvents("2026-09-24");
Returns
DailyEventsData — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getAllDayStress
garmin.getAllDayStress(cdate: string | Date): Promise<DailyStressData | null>
const result = await garmin.getAllDayStress("2026-09-24");
Returns
DailyStressData — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getBloodPressure
garmin.getBloodPressure(startdate: string | Date, enddate?: string | Date): Promise<BloodPressureRange | null>
const result = await garmin.getBloodPressure("2026-09-24");
Returns
BloodPressureRange:
| Field | Type | Always present |
|---|---|---|
measurementSummaries | unknown[] | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
enddate defaults to startdate
Verification: live-verified
getBodyBattery
garmin.getBodyBattery(startdate: string | Date, enddate?: string | Date): Promise<BodyBatteryEntry[]>
const result = await garmin.getBodyBattery("2026-09-24");
Returns
An array of BodyBatteryEntry:
| Field | Type | Always present |
|---|---|---|
date | string | no |
charged | number | no |
drained | number | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getBodyBatteryEvents
garmin.getBodyBatteryEvents(cdate: string | Date): Promise<BodyBatteryEvent[] | null>
const result = await garmin.getBodyBatteryEvents("2026-09-24");
Returns
An array of BodyBatteryEvent:
| Field | Type | Always present |
|---|---|---|
eventType | string | no |
eventStartTimeGmt | string | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getCaloriesDaily
garmin.getCaloriesDaily(start: string | Date, end: string | Date): Promise<CaloriesDailyEntry[]>
const result = await garmin.getCaloriesDaily("2026-09-24", "2026-09-24");
Returns
An array of CaloriesDailyEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
active | number | no |
resting | number | no |
total | number | no |
merges active (metricId 22) and resting/BMR (metricId 23) series into [{calendarDate, active, resting, total}]
Verification: live-verified
getDailyStats
garmin.getDailyStats(start: string | Date, end: string | Date, statsType: DailyStatsType): Promise<DailyStatsEntry[]>
const result = await garmin.getDailyStats("2026-09-24", "2026-09-24", statsType);
Returns
An array of DailyStatsEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | yes |
values | { | yes |
totalCalories | `number | null` |
activeCalories | `number | null` |
restingCalories | `number | null` |
totalSteps | `number | null` |
totalDistance | `number | null` |
stepGoal | `number | null` |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
GETs /usersummary-service/stats/daily/{start}/{end}?statsType=CALORIES|STEPS; statsType is exactly "CALORIES" or "STEPS" (any other value, lower-case included, is a Garmin 404). Garmin 400s when end - start > 27, so longer ranges are fetched in 28-day windows and the rows concatenated; Garmin's per-request aggregations (averages) are DROPPED rather than returned wrong for a chunked range. A range with no data returns [] (Garmin answers null). Overlaps getDailySteps/getCaloriesDaily; this one returns total/active/resting calories together, and steps with totalDistance and stepGoal
Verification: live-verified
getDailySteps
garmin.getDailySteps(start: string | Date, end: string | Date): Promise<DailyStepsEntry[] | null>
const result = await garmin.getDailySteps("2026-09-24", "2026-09-24");
Returns
An array of DailyStepsEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
totalSteps | number | no |
stepGoal | number | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
auto-chunks ranges over Garmin's 28-day-per-request limit into ≤28-day windows and concatenates; a single request within the limit passes its (possibly null) result through unchecked
Verification: live-verified
getFloors
garmin.getFloors(cdate: string | Date): Promise<FloorsData>
const result = await garmin.getFloors("2026-09-24");
Returns
FloorsData:
| Field | Type | Always present |
|---|---|---|
floorValuesArray | unknown[] | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
throws GarminError if Garmin returns nothing
Verification: live-verified
getHeartRates
garmin.getHeartRates(cdate: string | Date): Promise<HeartRateData>
const result = await garmin.getHeartRates("2026-09-24");
Returns
HeartRateData:
| Field | Type | Always present |
|---|---|---|
restingHeartRate | number | no |
maxHeartRate | number | no |
minHeartRate | number | no |
heartRateValues | `[number, number | null][]` |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getHrvData
garmin.getHrvData(cdate: string | Date): Promise<HrvData | null>
const result = await garmin.getHrvData("2026-09-24");
Returns
HrvData:
| Field | Type | Always present |
|---|---|---|
hrvSummary | Record<string, unknown> | no |
hrvReadings | Record<string, unknown>[] | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getHrvDataRange
garmin.getHrvDataRange(start: string | Date, end: string | Date): Promise<HrvDataRange | null>
const result = await garmin.getHrvDataRange("2026-09-24", "2026-09-24");
Returns
HrvDataRange — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getHydrationData
garmin.getHydrationData(cdate: string | Date): Promise<HydrationLogResult | null>
const result = await garmin.getHydrationData("2026-09-24");
Returns
HydrationLogResult — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getIntensityMinutesData
garmin.getIntensityMinutesData(cdate: string | Date): Promise<IntensityMinutesData | null>
const result = await garmin.getIntensityMinutesData("2026-09-24");
Returns
IntensityMinutesData — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getRespirationData
garmin.getRespirationData(cdate: string | Date): Promise<RespirationData | null>
const result = await garmin.getRespirationData("2026-09-24");
Returns
RespirationData — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getRhrDaily
garmin.getRhrDaily(start: string | Date, end: string | Date): Promise<RhrDailyEntry[]>
const result = await garmin.getRhrDaily("2026-09-24", "2026-09-24");
Returns
An array of RhrDailyEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
value | number | no |
reshapes allMetrics.metricsMap into [{calendarDate, value}], dropping null values
Verification: live-verified
getRhrDay
garmin.getRhrDay(cdate: string | Date): Promise<RhrDayData | null>
const result = await garmin.getRhrDay("2026-09-24");
Returns
RhrDayData — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
Verification: live-verified
getSleepDaily
garmin.getSleepDaily(start: string | Date, end: string | Date): Promise<SleepDailyEntry[]>
const result = await garmin.getSleepDaily("2026-09-24", "2026-09-24");
Returns
An array of SleepDailyEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Garmin's endpoint has a documented 28-day-per-request limit; ranges beyond that are auto-chunked, de-duplicated by calendarDate, and sorted
Verification: live-verified
getSleepData
garmin.getSleepData(cdate: string | Date): Promise<SleepData | null>
const result = await garmin.getSleepData("2026-09-24");
Returns
SleepData:
| Field | Type | Always present |
|---|---|---|
dailySleepDTO | Record<string, unknown> | no |
sleepLevels | Record<string, unknown>[] | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getSpo2Data
garmin.getSpo2Data(cdate: string | Date): Promise<Spo2Data | null>
const result = await garmin.getSpo2Data("2026-09-24");
Returns
Spo2Data:
| Field | Type | Always present |
|---|---|---|
lastSevenDaysAvgSpO2 | number | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
coerces a string lastSevenDaysAvgSpO2 to a number
Verification: live-verified
getStats
garmin.getStats(cdate: string | Date): Promise<UserSummary>
const result = await garmin.getStats("2026-09-24");
Returns
UserSummary:
| Field | Type | Always present |
|---|---|---|
totalSteps | number | no |
totalDistanceMeters | number | no |
activeKilocalories | number | no |
privacyProtected | boolean | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
alias of getUserSummary
Verification: live-verified
getStatsAndBody
garmin.getStatsAndBody(cdate: string | Date): Promise<StatsAndBody>
const result = await garmin.getStatsAndBody("2026-09-24");
Returns
StatsAndBody
merges getUserSummary with the body-composition totalAverage block, delegating to getBodyComposition (bodyComposition service) for the latter
Verification: live-verified
getStepsData
garmin.getStepsData(cdate: string | Date): Promise<StepsEntry[]>
const result = await garmin.getStepsData("2026-09-24");
Returns
An array of StepsEntry:
| Field | Type | Always present |
|---|---|---|
startGMT | string | no |
endGMT | string | no |
steps | number | no |
primaryActivityLevel | string | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getStressData
garmin.getStressData(cdate: string | Date): Promise<DailyStressData | null>
const result = await garmin.getStressData("2026-09-24");
Returns
DailyStressData — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
identical URL to getAllDayStress; an alias
Verification: live-verified
getUserSummary
garmin.getUserSummary(cdate: string | Date): Promise<UserSummary>
const result = await garmin.getUserSummary("2026-09-24");
Returns
UserSummary:
| Field | Type | Always present |
|---|---|---|
totalSteps | number | no |
totalDistanceMeters | number | no |
activeKilocalories | number | no |
privacyProtected | boolean | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getWeeklyIntensityMinutes
garmin.getWeeklyIntensityMinutes(start: string | Date, end: string | Date): Promise<WeeklyIntensityMinutesEntry[] | null>
const result = await garmin.getWeeklyIntensityMinutes("2026-09-24", "2026-09-24");
Returns
An array of WeeklyIntensityMinutesEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
Verification: live-verified
getWeeklySteps
garmin.getWeeklySteps(end: string | Date, weeks?: number): Promise<WeeklyStepsEntry[] | null>
const result = await garmin.getWeeklySteps("2026-09-24");
Returns
An array of WeeklyStepsEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
totalSteps | number | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
weeks defaults to 52, must be a positive integer
Verification: live-verified
getWeeklyStress
garmin.getWeeklyStress(end: string | Date, weeks?: number): Promise<WeeklyStressEntry[] | null>
const result = await garmin.getWeeklyStress("2026-09-24");
Returns
An array of WeeklyStressEntry:
| Field | Type | Always present |
|---|---|---|
calendarDate | string | no |
Plus every other field Garmin sends: this type carries an index signature because the real response is wider than the fields above, which are the ones this library relies on or has observed. Read an actual response before depending on a field that is not listed.
same weeks default/validation as getWeeklySteps
Verification: live-verified
setBloodPressure
garmin.setBloodPressure(systolic: number, diastolic: number, pulse?: number, when?: Date, notes?: string): Promise<BloodPressureSetResult | null>
const result = await garmin.setBloodPressure(1, 1);
Returns
BloodPressureSetResult — an object whose fields this library does not model. Garmin's response is passed through unparsed, so read one to see what you get, or use a Record<string, unknown> and narrow it yourself.
validates systolic 70-260, diastolic 40-150, pulse (if given) 20-250, all integers; when defaults to new Date()
Verification: live-verified