Effortless health monitoring powered by the official Fitbit (by Google) API. No apps, no dashboards — just ask and get your health stats instantly.
Only shows what you ask for — no unnecessary data.
You say...Reports..."how did I sleep" / "sleep"Duration, efficiency, all stages, nap"just my steps"Steps only"activity today"Steps, calories, distance, active mins, HR zones"full report" / "everything" / "summary"All available data"fitbit" / "health"Complete daily summary
Sleep:
Activity:
The Fitbit OAuth flow requests these scopes by default (override via FITBIT_SCOPES env var):
ScopePurposeWhy neededactivityDaily activity summarySteps, calories, distance, active minutessleepSleep recordsDuration, efficiency, stages, napsheartrateHeart rate dataResting HR + HR zonesprofileUser profile basicsDisplay name, timezone alignmentweightBody weightOptional — included by default for completeness
The OAuth is one-time setup — the callback server runs only during initial authentication, then tokens are stored locally and auto-refreshed.
https://github.com/yourusername/openclawhttp://localhost:8080 (for local) or your redirect URIbash
export FITBIT_CLIENT_ID="your_client_id"
export FITBIT_CLIENT_SECRET="your_client_secret"
export FITBIT_REDIRECT_URI="http://localhost:8080"
export FITBIT_TZ="Europe/London" # Your timezone
Or add to ~/.openclaw/.env:
text
FITBIT_CLIENT_ID=your_client_id
FITBIT_CLIENT_SECRET=your_client_secret
FITBIT_REDIRECT_URI=http://localhost:8080
FITBIT_TZ=Europe/London
Run the OAuth login script:
bash
python3 scripts/fitbit_oauth_login.py
This will:
~/.config/openclaw/fitbit/token.jsonTokens are automatically refreshed when they expire.
The skill uses a 3-step pipeline:
bash
# Step 1: Fetch raw data from Fitbit API
# IMPORTANT: For sleep queries (morning), use --date today not yesterday!
# Fitbit returns last night's sleep under today's date.
python3 scripts/fitbit_fetch_daily.py --date today --out /tmp/fitbit_raw.json
# Step 2: Normalize into clean format (extracts actual sleep time, stages, activity)
python3 scripts/fitbit_normalize_daily.py /tmp/fitbit_raw.json --out /tmp/fitbit_day.json
# Step 3: Render for display (use --channel discord, telegram, or generic)
python3 scripts/fitbit_render.py /tmp/fitbit_day.json --channel discord
For a specific date (YYYY-MM-DD format):
bash
python3 scripts/fitbit_fetch_daily.py --date 2026-03-25 --out /tmp/fitbit_raw.json
For sleep section only:
bash
python3 scripts/fitbit_render.py /tmp/fitbit_day.json --channel discord --section sleep
Critical date rule: When user asks about sleep in the morning (e.g., "how did I sleep"), use --date today. Fitbit's sleep API associates sleep with the date you woke up, so last night's sleep (Mar 25 11pm → Mar 26 7am) appears under date "today" (Mar 26). Only use --date yesterday for activity-only queries when you specifically want the previous full day's activity data.
Important: Always run the full pipeline (fetch → normalize → render). Never use raw API duration field directly — it includes wake periods inside the sleep window. The normalized duration_minutes field (which maps to Fitbit's minutesAsleep) is the actual sleep time.
Sleep report:
text
Fitbit — 2026-03-21
- Sleep: 7h 32m (score 85) | 93% efficiency
- Stages: Deep: 1h 42m, Light: 3h 20m, REM: 1h 45m, Wake: 45m
- Nap: 1h 6m
Full daily summary:
text
Fitbit — 2026-03-21
- Sleep: 7h 32m (score 85) | 93% efficiency
- Stages: Deep: 1h 42m, Light: 3h 20m, REM: 1h 45m, Wake: 45m
- Nap: 1h 6m
- Steps: 8,234
- Calories: 1,892 (1,048 BMR)
- Distance: 6.2 km
- Resting HR: 58 bpm
- Active mins: V. Active: 45m, Fair: 23m, Light: 1h 24m, Sedentary: 8h 12m
- HR Zones: Out of Range: 12h, Fat Burn: 1h 30m, Cardio: 32m, Peak: 8m
Steps only:
text
- Steps: 8,234
No third-party dependencies required. Uses Python standard library:
urllib.request - HTTP requestsjson - JSON parsingdatetime - Date handlingzoneinfo - Timezone support (Python 3.9+)Environment variables not loaded. Source your .env file or ensure variables are set in the gateway environment:
bash
source ~/.openclaw/.env
Tokens auto-refresh. If you see this error repeatedly:
~/.config/openclaw/fitbit/token.jsonpython3 scripts/fitbit_oauth_login.pyFITBIT_TZ matches your timezone--date yesterday to confirm data existsThis may indicate isMainSleep flag isn't set correctly on your Fitbit account. The skill filters records by this flag — some older Fitbit devices don't set it properly.
Not all Fitbit accounts/devices provide sleep scores. This is a Fitbit API limitation, not the skill. Efficiency and stages are always reported when available.
GET /1/user/-/activities/date/{date}.json - Daily activity summaryGET /1.2/user/-/sleep/date/{date}.json - Sleep recordsreferences/fitbit_api.mdreferences/output_schema.md