Skip to main content

ha-garmin

Python client for Garmin Connect API, designed for Home Assistant integration.

Features

  • Native Garmin Connect API integration
  • Robust authentication with multiple login strategies and automatic fallbacks
  • MFA support with automatic endpoint fallback
  • Token persistence - save and restore sessions to avoid re-login
  • Automatic token refresh - proactively refreshes before expiry
  • Retry with backoff for rate limits (429) and server errors (5xx)
  • Midnight fallback - automatically uses yesterday's data when today isn't ready yet
  • Coordinator-based fetch - optimized data fetching for Home Assistant multi-coordinator pattern
  • Data transformations - automatic unit conversions (seconds→minutes, grams→kg)

Installation

pip install ha-garmin

Optional: install with improved browser UA generation:

pip install ha-garmin[ua]

Usage

Standalone script

Authentication is synchronous; data fetches run in a thread pool and are awaited.

import asyncio
from datetime import date
from ha_garmin import GarminAuth, GarminClient, GarminMFARequired

# Auth is synchronous
auth = GarminAuth()

if not auth.load_session(".garmin_tokens.json"):
    try:
        auth.login("email@example.com", "password")
    except GarminMFARequired:
        mfa_code = input("Enter MFA code: ")
        auth.complete_mfa(mfa_code)
    auth.save_session(".garmin_tokens.json")

client = GarminClient(auth)


async def fetch_all():
    today = date.today()
    core_data     = await client.fetch_core_data(today)      # Steps, HR, sleep, stress
    body_data     = await client.fetch_body_data(today)      # Weight, body composition, fitness age
    activity_data = await client.fetch_activity_data(today)  # Activities, workouts, training calendar
    training_data = await client.fetch_training_data(today)  # HRV, training status
    goals_data    = await client.fetch_goals_data()          # Goals, badges
    gear_data     = await client.fetch_gear_data()           # Gear, alarms, solar, devices


asyncio.run(fetch_all())

Home Assistant integration

Set up auth during async_setup_entry and pass the client to your coordinators.

from datetime import date, timedelta
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from ha_garmin import GarminAuth, GarminClient

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    auth = GarminAuth()

    token_path = hass.config.path(".storage/garmin_tokens.json")
    if not auth.load_session(token_path):
        # Initial login must have been completed via the config flow
        raise ConfigEntryAuthFailed("No valid Garmin session")

    client = GarminClient(auth)

    coordinator = GarminCoreCoordinator(hass, client)
    await coordinator.async_config_entry_first_refresh()

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
    return True


class GarminCoreCoordinator(DataUpdateCoordinator):
    def __init__(self, hass: HomeAssistant, client: GarminClient) -> None:
        super().__init__(hass, logger=_LOGGER, name="Garmin core", update_interval=timedelta(minutes=15))
        self._client = client

    async def _async_update_data(self) -> dict:
        return await self._client.fetch_core_data(date.today())

Coordinator Fetch Methods

Optimized methods that group related API calls for Home Assistant coordinators:

Method API Calls Data Returned
fetch_core_data() 3 Steps, distance, calories, HR, stress, sleep, skin temperature change, body battery, SPO2
fetch_body_data() 3 Weight, BMI, body fat, hydration, fitness age
fetch_activity_data() 6+ Activities, workouts, HR zones, polylines, training calendar (scheduled workouts, plan goal event or calendar race)
fetch_training_data() 8+ Training readiness, status, VO2 Max, HRV, lactate, endurance/hill scores, power-to-weight
fetch_goals_data() 4 Goals (active/future/history), badges, user level
fetch_gear_data() 6+ Gear items, stats, device alarms, solar intensity (daily avg + gain), devices, last sync, paired sensors
fetch_blood_pressure_data() 1 Blood pressure measurements
fetch_menstrual_data() 2 Menstrual cycle data
fetch_nutrition_data() 1 Nutrition log: consumed macros, goals, per-meal breakdown

Write / Action Methods

Methods for logging data back to Garmin Connect, suitable for Home Assistant services:

Method Description
add_nutrition_log(calories, carbs, protein, fat, name) Log a Quick Add nutrition entry (requires Connect+)
set_hydration(value_in_ml) Log hydration intake
set_blood_pressure(systolic, diastolic, pulse) Log a blood pressure measurement
add_body_composition(weight, percent_fat, ...) Log weight / body composition via FIT upload
create_activity(name, type, start, duration_min) Create a manual activity
upload_activity(file_path) Upload a FIT / GPX / TCX file
set_active_gear(activity_type, setting, gear_uuid) Set default gear for an activity type
add_gear_to_activity(gear_uuid, activity_id) Associate gear with an activity

Nutrition logging

Requires a Garmin Connect+ subscription and initial setup through the Garmin Connect app (the app creates the meal slots that the API needs).

await client.add_nutrition_log(
    calories=500,
    carbs=60,       # optional, grams
    protein=30,     # optional, grams
    fat=15,         # optional, grams
    name="Lunch",   # optional label
)

The method automatically fetches the correct meal slot ID and time for the day. If no meal slots are configured yet, open the Garmin Connect app and set up your nutrition plan first.

Individual API Methods

Method Description
get_user_profile() User profile info
get_user_settings() Profile settings (userData, incl. VO2 Max running/cycling)
get_daily_steps() Steps for date range
get_body_composition() Weight, BMI, body fat
get_fitness_age() Fitness age metrics
get_hydration_data() Daily hydration
get_activities() Most recent activities (newest first, no date filter)
get_activity(activity_id) Single activity summary (includes e-bike fields)
get_activity_details() Detailed activity with polyline
get_activity_hr_in_timezones() HR time in zones
download_activity(activity_id, file_format) Download activity file (fit/original/tcx/gpx/kml/csv)
get_workouts() Workout library (created/saved workouts, not when scheduled)
get_scheduled_workouts(year, month) Training calendar for a month: self-scheduled + Garmin Coach / adaptive-plan workouts
get_training_readiness() Training readiness score
get_training_status() Training status
get_morning_training_readiness() Morning readiness
get_endurance_score() Endurance score
get_hill_score() Hill score
get_lactate_threshold() Lactate threshold
get_power_to_weight(target_date) FTP / power-to-weight data
get_goals() User goals by status
get_earned_badges() Earned badges
get_gear() User gear items
get_gear_stats() Gear statistics
get_gear_defaults() Default gear settings
get_devices() Connected devices
get_sensors() Paired ANT+/BLE sensors and battery status
get_device_alarms() Device alarms
get_device_solar_data() Solar intensity data per device
get_device_last_used() Last used device and last sync time
get_device_settings() Device settings
get_blood_pressure() Blood pressure data
get_menstrual_data() Menstrual cycle data
get_menstrual_calendar() Menstrual calendar
get_nutrition_log() Daily nutrition log (Connect+)

Data Transformations

The library automatically adds computed fields for convenience:

  • Time conversions: sleepTimeSeconds → sleepTimeMinutes
  • Activity time: highlyActiveSeconds → highlyActiveMinutes
  • Weight: weight (grams) → weightKg
  • Stress: stressQualifier → stressQualifierText (capitalized)
  • Nested flattening: HRV status, training readiness, scores
  • VO2 Max: training status (running, else cycling), then profile settings, then recent activities
  • Training plan goal: the plan's goal event, else the upcoming (primary) race on your calendar
  • Skin temperature: avgSkinTempDeviationC is the nightly change from your baseline, not an absolute temperature
  • Sanity checks: a metabolicAge that can't be an age in years is returned as None

License

MIT

Metadata

Release files for ha-garmin 0.1.49

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ha-garmin 0.1.49
File Size Uploaded Provenance
ha_garmin-0.1.49.tar.gz 81.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ha-garmin 0.1.49
File Interpreter ABI Platform
ha_garmin-0.1.49-py3-none-any.whl Python 3 none any Details

Total release size: 137.2 kB

Release files / ha_garmin-0.1.49.tar.gz

Download URL ha_garmin-0.1.49.tar.gz
Size 81.2 kB
Tags Source
SHA-256 checksum
How to use checksums
9af0d73c4592356745f60f57e68d43f156d9dcc091f9629352c94586c851cd5f
BLAKE2b-256 checksum
How to use checksums
5fd0958257e6f164a90b3c9993316155c2e9c9e31eafe25d48d9877af9630f77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release files / ha_garmin-0.1.49-py3-none-any.whl

Download URL ha_garmin-0.1.49-py3-none-any.whl
Size 56.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
63170ac85b25d0b0122f33e5a194df60d7c6157519aaceb4fb3bfd1cf7a6de86
BLAKE2b-256 checksum
How to use checksums
845377f74ea43e22d9a0ad6710fbbb8236d3f8dd2e2d14d6121f28e265c9d9c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Security for ha-garmin 0.1.49

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.49 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page