Skip to content
Docs menu

Women's health

Menstrual-cycle tracking and pregnancy. The write methods here are irreversible health-data writes with no delete endpoint — read the warning at the top of src/services/womensHealth.ts before calling one.

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);

11 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.

MethodVerified
confirmMenstrualPeriodStartlive-verified
getMenstrualCalendarDatalive-verified
getMenstrualCycleSummarylive-verified
getMenstrualDataForDatelive-verified
getMenstrualLastConfirmedlive-verified
getMenstrualReportslive-verified
getPregnancySummarylive-verified
initMenstrualCycleSetuplive-verified
updateMenstrualCalendarlive-verified
updateMenstrualDailyLoglive-verified
updateMenstrualSettingslive-verified

confirmMenstrualPeriodStart

garmin.confirmMenstrualPeriodStart(periodStartDate: string | Date, periodLength: number, cycleLength: number, options?: {predictedCycle?: boolean}): Promise<unknown>
const result = await garmin.confirmMenstrualPeriodStart("2026-09-24", 1, 1);

Returns

unknown — Garmin's response is passed through unparsed. Cast it to whatever you need; this library does not model it.

POSTs /periodichealth-service/menstrualcycle/{periodStartDate} directly, NOT the dayview/calendar/lastconfirmed/summary sub-paths

Verification: live-verified

getMenstrualCalendarData

garmin.getMenstrualCalendarData(startdate: string | Date, enddate: string | Date): Promise<MenstrualCalendarData | null>
const result = await garmin.getMenstrualCalendarData("2026-09-24", "2026-09-24");

Returns

MenstrualCalendarData — 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.

passes through unchecked; Garmin rejects windows of 92+ inclusive days; not enforced here (caller's responsibility)

Verification: live-verified

getMenstrualCycleSummary

garmin.getMenstrualCycleSummary(fordate: string | Date): Promise<MenstrualCycleSummary | null>
const result = await garmin.getMenstrualCycleSummary("2026-09-24");

Returns

MenstrualCycleSummary — 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.

passes through unchecked

Verification: live-verified

getMenstrualDataForDate

garmin.getMenstrualDataForDate(fordate: string | Date): Promise<MenstrualDayView | null>
const result = await garmin.getMenstrualDataForDate("2026-09-24");

Returns

MenstrualDayView — 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.

passes through unchecked

Verification: live-verified

getMenstrualLastConfirmed

garmin.getMenstrualLastConfirmed(fordate: string | Date): Promise<MenstrualLastConfirmed | null>
const result = await garmin.getMenstrualLastConfirmed("2026-09-24");

Returns

MenstrualLastConfirmed — 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.

passes through unchecked

Verification: live-verified

getMenstrualReports

garmin.getMenstrualReports(fordate: string | Date, numberOfCycles?: number, options?: {nextReport?: boolean, reportType?: string, todayCalendarDate?: string | Date}): Promise<MenstrualReports | null>
const result = await garmin.getMenstrualReports("2026-09-24");

Returns

MenstrualReports — 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.

defaults numberOfCycles=6, nextReport=false, reportType="CYCLE", todayCalendarDate defaults to today; numberOfCycles restricted to {1,6,12} or throws GarminError; passes through unchecked

Verification: live-verified

getPregnancySummary

garmin.getPregnancySummary(): Promise<PregnancySummary | null>
const result = await garmin.getPregnancySummary();

Returns

PregnancySummary — 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.

passes through unchecked

Verification: live-verified

initMenstrualCycleSetup

garmin.initMenstrualCycleSetup(periodStartDate: string | Date, periodLength: number, cycleLength: number): Promise<unknown>
const result = await garmin.initMenstrualCycleSetup("2026-09-24", 1, 1);

Returns

unknown — Garmin's response is passed through unparsed. Cast it to whatever you need; this library does not model it.

does NOT also update tracking-preference settings (call updateMenstrualSettings separately for that); not intended for an already-configured account

Verification: live-verified

updateMenstrualCalendar

garmin.updateMenstrualCalendar(startdate: string | Date, enddate: string | Date, cycleDatesLists: (string | Date)[][], options?: {todayCalendarDate?: string | Date}): Promise<unknown>
const result = await garmin.updateMenstrualCalendar("2026-09-24", "2026-09-24", "2026-09-24");

Returns

unknown — Garmin's response is passed through unparsed. Cast it to whatever you need; this library does not model it.

full replace, not a merge; each cycleDatesLists group must be non-empty, consecutive calendar dates, and fall within [startdate, enddate], else throws GarminError

Verification: live-verified

updateMenstrualDailyLog

garmin.updateMenstrualDailyLog(calendarDate: string | Date, options?: {symptoms?: string[], moods?: string[], flow?: string, discharge?: string[], sexDrive?: string, sexualActivity?: string, notes?: string, ovulationDay?: boolean}): Promise<unknown>
const result = await garmin.updateMenstrualDailyLog("2026-09-24");

Returns

unknown — Garmin's response is passed through unparsed. Cast it to whatever you need; this library does not model it.

full-day replace, not a merge; at least one optional field required or throws GarminError; notes: undefined preserves the existing note, notes: "" clears it (distinct, load-bearing); discharge rejects combining "NO_DISCHARGE" with any other value

Verification: live-verified

updateMenstrualSettings

garmin.updateMenstrualSettings(settings: Record<string, unknown>, options?: {userSettingsId?: number}): Promise<unknown>
const result = await garmin.updateMenstrualSettings("settings");

Returns

unknown — Garmin's response is passed through unparsed. Cast it to whatever you need; this library does not model it.

settings must be non-empty or throws GarminError; multi-step: GETs /userprofile-service/userprofile/user-settings, overlays settings onto the current userMenstrualCycleSettings, then PUTs the same endpoint, including id if resolvable

Verification: live-verified

Methods in this category