Skip to content

Repository files navigation

fitbitctl

A read-first, script-friendly Go CLI for health data synchronized by Fitbit devices and Google Pixel Watches through the new Google Health API v4.

This is a CLI-only project. Its Go packages are internal implementation details; the supported interface is the fitbitctl command.

Important

Google will turn down the legacy Fitbit Web API in September 2026. This project targets Google Health API v4 and Google OAuth 2.0 directly. Old Fitbit access and refresh tokens do not work with the new API; users must consent again.

Highlights

  • Google OAuth 2.0 authorization-code flow with PKCE, state, and automatic refresh
  • Browser/loopback login for humans and a two-step headless flow for agents
  • Private JSON token storage with atomic replacement
  • Lossless access to every documented data-point union type
  • Raw and reconciled streams, physical and civil-day rollups, and exercise TCX
  • Paired Pixel Watch/Fitbit device, identity, profile, and settings inspection
  • Retries for rate limits and transient server failures
  • Stable JSON, top-level field projection, clean stdout, and actionable errors
  • No interactive prompts or browser launches with --no-input or --json

Install

Install from source with Go 1.24 or newer:

go install github.com/mathisarends/fitbitctl/cmd/fitbitctl@latest

Or build from a checkout:

make build
./bin/fitbitctl --help

On Windows without make:

go build -o bin/fitbitctl.exe ./cmd/fitbitctl

Configure Google Health

  1. Create or select a Google Cloud project.
  2. Enable Google Health API.
  3. Configure an external OAuth consent screen and add your Google account as a test user while the app is in testing.
  4. Add only the Google Health read scopes you intend to use. fitbitctl requests all nine current read scopes by default; --scopes can narrow this.
  5. Create a Web application OAuth client and register this exact authorized redirect URI:
http://localhost:8089/callback

Localhost HTTP redirect URIs are explicitly allowed by Google's OAuth rules. Copy .env.example to .env and add the OAuth client credentials:

FITBITCTL_CLIENT_ID=your-client-id.apps.googleusercontent.com
FITBITCTL_CLIENT_SECRET=your-client-secret
FITBITCTL_REDIRECT_URI=http://localhost:8089/callback

See Google's current Health API setup guide and scope list. All Google Health scopes are restricted. Public apps require OAuth verification and a security review; testing-mode limits and refresh-token expiration still apply.

Authorize

For a guided terminal flow:

fitbitctl auth login --open
fitbitctl auth status

For a headless or agent flow, the first command creates a short-lived PKCE session. Pass the resulting callback URL or authorization code to the second:

fitbitctl --json auth url
fitbitctl --json --no-input auth login --code 'CALLBACK_URL_OR_CODE'
fitbitctl --json auth status

Request a smaller scope set when full access is unnecessary:

fitbitctl auth login --open --scopes activity,health,sleep,settings

Tokens are hidden by auth status. Revealing them requires the explicit --show-secrets flag. The default token path is fitbitctl/token.json below the operating system's user config directory.

Read Pixel Watch data

Discover the current data catalog first:

fitbitctl data types
fitbitctl --json --fields=id,kind,operations data types

Then query raw or reconciled data. Date-only values use the API's documented daily/civil semantics and UTC midnight for physical filters; RFC3339 timestamps preserve precise ranges.

fitbitctl data list steps --start 2026-07-01 --end 2026-07-08
fitbitctl data list heart-rate --start 2026-07-01T08:00:00+02:00 --end 2026-07-01T10:00:00+02:00 --all-pages
fitbitctl data reconcile sleep --start 2026-07-01 --end 2026-07-08 --data-source-family google-wearables
fitbitctl data list daily-resting-heart-rate --start 2026-07-01 --end 2026-08-01
fitbitctl data list oxygen-saturation --start 2026-07-01 --end 2026-07-08

Aggregate high-volume streams and restrict aggregation to Google wearable data:

fitbitctl data rollup steps --start 2026-07-01T00:00:00Z --end 2026-07-08T00:00:00Z --window 1h
fitbitctl data daily-rollup heart-rate --start 2026-07-01 --end 2026-07-08 --data-source-family google-wearables

Inspect account/device metadata and export a recorded workout:

fitbitctl identity
fitbitctl profile
fitbitctl settings
fitbitctl device list
fitbitctl exercise export-tcx EXERCISE_ID --output run.tcx

The API supports all historical data recorded for the account, but each request is limited to a 14- or 90-day range depending on type and remains subject to rate limits. --all-pages follows page tokens; it does not split an oversized date range automatically.

Agent and scripting contract

Add --json to any JSON-producing command and --compact for NDJSON-friendly single-line output. --fields selects top-level response fields and implies JSON:

fitbitctl --json --compact data list steps --start 2026-07-01 --end 2026-07-02
fitbitctl --fields=healthUserId,legacyUserId identity
fitbitctl --fields=id,operations --compact data types
  • stdout contains command data only.
  • Human hints, login URLs, diagnostics, and errors go to stderr.
  • JSON errors use { "error": { "code", "message", "hint", "status" } }.
  • --fields rejects misspellings and reports valid choices.
  • --no-input guarantees that the command will not prompt or open a browser.
  • --json also disables interactive login so automation never hangs.

See docs/cli.md for the full command, filtering, output, and exit-code contract.

Data availability and privacy

Pixel Watches do not send data directly to this CLI. They sync to the Google Health/Fitbit mobile app first; the API exposes data after that sync. Available types depend on the watch model, enabled features, region, permissions, and any required subscription. Medical-adjacent types such as ECG and irregular rhythm notifications may be absent even when their scopes were granted.

Health data and OAuth refresh tokens are sensitive. Do not commit .env, token files, exported JSON, or TCX tracks. Prefer the minimum required scopes and use a dedicated Google Cloud project whose consent screen accurately describes how data is used.

Development

make fmt
make test
make vet
make build

The implementation target and API decisions are recorded in SPEC.md. Release instructions are in docs/releasing.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages