Wahoo Fitness Cloud API

Data & APIs

Access Wahoo Fitness Cloud API to fetch workouts, download FIT files, and analyze training data (power, HR, cadence, GPS).

Install

openclaw skills install wahoo-cloud

Wahoo Cloud Skill

Provides programmatic access to Wahoo Fitness Cloud data. This skill manages OAuth2 authentication, workout synchronization, and FIT file processing.

🚀 Agent Quickstart

When a user asks about their Wahoo workouts, training, or fitness data, use these workflows:

User IntentAction / Command
"Sync my Wahoo workouts"python3 {baseDir}/scripts/fetch_workouts.py
"Show my recent rides"Query the local SQLite DB: $WAHOO_BASE_DIR/wahoo.db (default: ~/.wahoo/wahoo.db) — schema below
"Parse this FIT file"python3 {baseDir}/scripts/parse_fit.py <PATH_TO_FIT>
"Connect/Set up Wahoo"1. Verify WAHOO_CLIENT_ID and WAHOO_CLIENT_SECRET exist.<br>2. If missing, ask user to provide them.<br>3. Run python3 {baseDir}/scripts/oauth_setup.py
"Token expired / persistent 401 errors"Run python3 {baseDir}/scripts/oauth_setup.py to re-authorize. Force-refresh without browser: python3 -c "import sys; sys.path.insert(0,'lib'); import wahoo_auth; wahoo_auth.refresh()"

🛠 Key Workflows

1. Authentication & Setup

This skill requires a Wahoo Developer App.

  • Credentials: Must be provided as WAHOO_CLIENT_ID and WAHOO_CLIENT_SECRET.
  • OAuth Flow: If tokens are missing or expired, run scripts/oauth_setup.py. This is an interactive process. You must present the URL to the user, wait for them to authenticate, and then ask them to paste the resulting redirect URL/code back into the terminal.
  • Token Storage: Tokens are stored at $WAHOO_BASE_DIR/secrets/wahoo_tokens.json (controlled by WAHOO_BASE_DIR env var, default ~/.wahoo).

2. Data Synchronization

  • Command: python3 scripts/fetch_workouts.py
  • Behavior: Idempotent. It fetches new workouts, downloads FIT files, and populates the local SQLite database.
  • Database Path: $WAHOO_BASE_DIR/wahoo.db (default: ~/.wahoo/wahoo.db)
  • Rate Limits: The script automatically handles Wahoo's sandbox rate limits (25 req / 5 min) using exponential backoff.

3. Querying Training Data

Once synced, use the following SQL patterns to answer user questions:

  • Recent Workouts: SELECT * FROM workouts ORDER BY starts DESC LIMIT 10;
  • Power/HR Series: SELECT timestamp, power_w, heart_rate, cadence FROM records WHERE workout_id = <id> ORDER BY timestamp;
  • Elevation/GPS: SELECT timestamp, position_lat_deg, position_long_deg, enhanced_altitude_m FROM records WHERE workout_id = <id>;

⚠️ Critical Constraints & Pitfalls

  • Rate Limiting: Wahoo Sandbox is strict. Do not attempt to loop calls rapidly; rely on the wahoo_api.py built-in backoff.
  • Data Types: The Wahoo API returns decimal values as strings. Always cast to float() before performing mathematical analysis.
  • Metric Conversion:
    • Meters to Miles: m / 1609.34
    • Meters/Second to MPH: m/s * 2.237
  • Workout Summaries: The /v1/workouts list endpoint returns null for workout_summary. You must call /v1/workouts/<id> to get specific metrics like NP, TSS, or the FIT file URL.

Error Reference

HTTP CodeMeaningResolution
401Token expired/invalid — auto-refresh runs onceRe-run oauth_setup.py if it keeps failing
403Insufficient scopeRe-authorize with missing scope in WAHOO_SCOPES
429Rate limitwahoo_api.py backs off automatically, use --limit to reduce call volume
404Workout not foundConfirm ID and ownership