ha-garmin

raw JSON →
0.1.19 verified Sat May 09 auth: no python

Python client for the Garmin Connect API. Version 0.1.19 supports Garmin SSO/Loading (OAuth1/OAuth2) authentication and provides methods to fetch activities, body composition, daily summaries, heart rate, sleep, stress, fitness age, training readiness, and more. Features include automatic token refresh and activity upload. Released under MIT license, with regular updates.

pip install ha-garmin
error 400 invalid_grant
cause Chinese Garmin accounts need CN-specific endpoint.
fix
Upgrade to v0.1.16+ which routes to diauth.garmin.cn.
error AttributeError: 'float' object has no attribute 'get'
cause Garmin API returns mostRecentVO2Max as float instead of dict in some cases.
fix
Upgrade to v0.1.17+.
error ModuleNotFoundError: No module named 'garminconnect'
cause Installed package 'ha-garmin' but used wrong import path.
fix
Use 'from garminconnect import Garmin' (not 'ha_garmin').
breaking In v0.1.18 and earlier, the 'get_lactate_threshold' method could discard heart rate data. Upgrade to v0.1.17+ for fixed behavior.
fix Update to v0.1.19: pip install --upgrade ha-garmin
breaking In v0.1.16, Chinese accounts must use the correct domain. The fix routes diauth to diauth.garmin.cn. If you got '400 invalid_grant', upgrade to v0.1.16+.
fix Upgrade to v0.1.16+.
gotcha The Garmin API sometimes returns 'mostRecentVO2Max' as a bare float instead of a dict. In older versions this caused AttributeError.
fix Upgrade to v0.1.17+.
gotcha Token refresh is automatic, but if you clear tokens or have network issues, login may fail. Ensure 'is_logged_in' check before sensitive operations.
fix Always call api.login() after creating a new instance, or catch exceptions.

Basic login and data retrieval. Set environment variables GARMIN_EMAIL and GARMIN_PASSWORD.

import os
from garminconnect import Garmin

api = Garmin(
    email=os.environ.get('GARMIN_EMAIL', ''),
    password=os.environ.get('GARMIN_PASSWORD', '')
)
api.login()

# Fetch today's activities
activities = api.get_activities(0, 10)
print(activities)

# Fetch daily summary
summary = api.get_daily_summary('2025-01-15')
print(summary)