Wahoo Connector
Dreeve imports anything dropped into its watch/ folder. Getting your Wahoo workouts into that
folder is what the Wahoo connector does: it periodically fetches workout activities from the Wahoo Fitness Cloud API, downloads the original .fit files, and drops them in. No manual exports.
Wahoo Cloud → connector → watch/ → Dreeve imports itThe connector is a separate container from its own repository, dreeveapp/dreeve-wahoo-connector. It is not part of Dreeve itself, it only writes files into the folder you already mount.
1. Register a Wahoo client
Section titled “1. Register a Wahoo client”- Sign in to the Wahoo Developer Portal.
- Click Create Application.
- Fill in the required fields:
- App Name:
dreeve-wahoo-connector(or your preferred name) - Redirect URI:
https://<this-host>:8085/callback(e.g.https://192.168.1.100:8085/callbackorhttp://localhost:8085/callback) - Webhook URI: Leave blank
- App Name:
- Submit the application and copy your Client ID and Client Secret.
2. Add the container
Section titled “2. Add the container”Add this alongside the app and daemon services in your
docker-compose.yml:
# Pulls workouts out of Wahoo Cloud into the watch folder. wahoo-connector: image: ghcr.io/dreeveapp/dreeve-wahoo-connector:latest container_name: dreeve-wahoo-connector restart: unless-stopped ports: - '8085:8085' env_file: ./.env volumes: # The same ./watch folder the app and daemon mount. - ./watch:/data/downloads - ./wahoo/config:/data/config3. Configure it
Section titled “3. Configure it”Add to your .env:
WAHOO_CLIENT_ID=your-client-idWAHOO_CLIENT_SECRET=your-client-secret# Where this connector is reachable in a browser for OAuth callbacks.WAHOO_REDIRECT_URI=https://<this-host>:8085/callback# Initial sync window: 1_day, 1_week, 1_month, 1_year, or all_timeSYNC_TIME_WINDOW=1_week# Cron expression for automated background downloads (default: daily at 02:00 UTC)SYNC_CRON=0 2 * * *4. Authorize it
Section titled “4. Authorize it”Start the container:
> docker compose up -d wahoo-connectorThen open https://<this-host>:8085 in your browser, accept the self-signed SSL certificate if prompted, and click Connect Wahoo Account.
After approving access on Wahoo’s site, you will be redirected back to the connector dashboard. An initial sync cycle runs automatically upon successful authorization.
Tokens are saved persistently to the ./wahoo/config volume and refresh automatically.
5. Start it
Section titled “5. Start it”> docker compose up -d> docker compose logs -f wahoo-connectorBackground sync runs according to SYNC_CRON (or on demand via the web dashboard). Downloaded workouts land in the watch folder as <date>_workout_<id>.fit, and the daemon container will import them, exactly as if you had dropped them there yourself.
How sync works
Section titled “How sync works”- Atomic file delivery: Files are written as temporary files (
.tmp) and atomically renamed to.fitupon completion, preventing Dreeve from parsing partial files. - Smart deduplication: Workouts are queried starting from newest first. Syncing stops early when encountering already downloaded activities. Download history is recorded persistently (
sync_history.json), ensuring sync remains fast and avoids re-downloads even after Dreeve processes and removes.fitfiles from the watch folder. - Dynamic rate limiting: Monitors Wahoo API
X-RateLimit-RemainingHTTP response headers in real time to avoid429 Too Many Requestserrors.
Configuration
Section titled “Configuration”| Variable | Default | What it does |
|---|---|---|
WAHOO_CLIENT_ID | - | Required. Client ID from Wahoo Developer Portal. |
WAHOO_CLIENT_SECRET | - | Required. Client Secret from Wahoo Developer Portal. |
WAHOO_REDIRECT_URI | https://localhost:8085/callback | OAuth redirect URI matching Wahoo App settings. |
SYNC_TIME_WINDOW | 1_week | Timeframe for sync cycles (1_day, 1_week, 1_month, 1_year, all_time). |
SYNC_CRON | 0 2 * * * | 5-field Cron expression for scheduled background downloads. |
PORT | 8085 | Port for the web dashboard & OAuth callback server. |
DATA_DIR | /data | Internal container base path for configuration and downloaded files. |
STATE_DIR | /data/config | Directory path to store authentication tokens and sync history. |
WATCH_DIR | /data/downloads | Directory path to deliver downloaded .fit files (Dreeve watch folder). |
LOG_LEVEL | INFO | Logging verbosity level (DEBUG, INFO, WARNING, ERROR). |
VERIFY_FILES_ON_DISK | false | If true, requires .fit files to remain on disk during deduplication checks. |
Commands & Endpoints
Section titled “Commands & Endpoints”# Start or update the container> docker compose up -d wahoo-connector
# View status via HTTP API> curl https://localhost:8085/api/status
# Trigger an immediate manual sync cycle> curl -X POST https://localhost:8085/api/sync