Skip to main content

Overview

Each wearable provider has different requirements and parameters for syncing data. This guide covers the specifics for each supported provider.
Provider names in API paths must be lowercase: garmin, polar, suunto, whoop, apple

Garmin

Garmin uses a backfill API that accepts time range parameters to specify what data to sync.

Sync Parameters

ParameterRequiredFormatDescription
summary_start_timeRecommendedISO 8601 or Unix timestampStart of sync range
summary_end_timeRecommendedISO 8601 or Unix timestampEnd of sync range
While time parameters are optional, providing them ensures you get data for a specific date range. Without them, the sync behavior depends on Garmin’s default response.

Example

# Using ISO 8601 dates
curl -X POST "http://localhost:8000/api/v1/providers/garmin/users/{user_id}/sync?data_type=all&summary_start_time=2025-01-01T00:00:00Z&summary_end_time=2025-01-31T00:00:00Z" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

# Using Unix timestamps
curl -X POST "http://localhost:8000/api/v1/providers/garmin/users/{user_id}/sync?data_type=all&summary_start_time=1735689600&summary_end_time=1738368000" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

Polar

Polar uses the AccessLink API with simpler sync requirements.

Sync Parameters

ParameterDefaultDescription
samplesfalseInclude detailed sample data (HR samples, etc.)
zonesfalseInclude heart rate zone information
routefalseInclude GPS route data

Example

# Basic sync
curl -X POST "http://localhost:8000/api/v1/providers/polar/users/{user_id}/sync" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

# With additional data
curl -X POST "http://localhost:8000/api/v1/providers/polar/users/{user_id}/sync?samples=true&zones=true&route=true" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"
Enabling samples, zones, and route increases sync time but provides more detailed workout data.

Suunto

Suunto supports both workouts and 24/7 data (sleep, recovery, activity samples).

Sync Parameters

ParameterDefaultDescription
since0Unix timestamp to sync from (0 = all available)
limit50Items per request (max: 100)
offset0Pagination offset
filter_by_modification_timetrueFilter by modification vs creation time

Data Types

ValueDescription
workoutsWorkout/exercise sessions
24724/7 data: sleep, recovery, activity samples
allBoth workouts and 24/7 data

Example

# Sync all data from last 30 days
THIRTY_DAYS_AGO=$(date -v-30d +%s)
curl -X POST "http://localhost:8000/api/v1/providers/suunto/users/{user_id}/sync?data_type=all&since=${THIRTY_DAYS_AGO}&limit=100" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

# Sync only workouts
curl -X POST "http://localhost:8000/api/v1/providers/suunto/users/{user_id}/sync?data_type=workouts" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

Whoop

Whoop uses OAuth 2.0 and supports both workouts and 24/7 data (sleep, recovery, body measurements).

Setup

  1. Create an application at developer.whoop.com
  2. Set your redirect URI to http://localhost:8000/api/v1/oauth/whoop/callback
  3. Configure environment variables:
WHOOP_CLIENT_ID=your-client-id
WHOOP_CLIENT_SECRET=your-client-secret
WHOOP_REDIRECT_URI=http://localhost:8000/api/v1/oauth/whoop/callback
WHOOP_DEFAULT_SCOPE=offline read:cycles read:sleep read:recovery read:workout

Sync Parameters

Whoop does not require provider-specific query parameters. Use the standard data_type parameter to control what gets synced.
data_type ValueDescription
workoutsWorkout/exercise sessions
247Sleep sessions, recovery metrics, body measurements
allBoth workouts and 24/7 data
When no date range is specified, Whoop defaults to syncing the last 30 days of data.

Data Collected

Workouts: heart rate (avg/max), energy burned, distance, elevation gain, duration. Sleep (247): total duration, time in bed, efficiency score, sleep stages (deep, light, REM, awake), nap detection. Recovery (247): recovery score, resting heart rate, HRV (RMSSD), SpO2 percentage, skin temperature. Body measurements (247): height, weight.

Example

# Sync all Whoop data
curl -X POST "http://localhost:8000/api/v1/providers/whoop/users/{user_id}/sync?data_type=all" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

# Sync only workouts
curl -X POST "http://localhost:8000/api/v1/providers/whoop/users/{user_id}/sync?data_type=workouts" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

# Sync only sleep & recovery data
curl -X POST "http://localhost:8000/api/v1/providers/whoop/users/{user_id}/sync?data_type=247" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"

Apple Health

Apple Health data is imported via the mobile SDK rather than cloud API sync.
Apple Health requires the Open Wearables mobile SDK. Cloud sync is not available for Apple Health.

Checking Connection Status

Before syncing, verify the user has an active connection:
curl -X GET "http://localhost:8000/api/v1/users/{user_id}/connections" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"
Response:
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "user_id": "user-uuid",
    "provider": "garmin",
    "status": "active",
    "last_synced_at": "2025-01-15T12:00:00Z",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T12:00:00Z"
  }
]
Connection status can be: active, revoked, or expired. If no connection exists for a provider, the user needs to complete OAuth first.

Available Providers

Check which providers are enabled in your instance:
curl -X GET "http://localhost:8000/api/v1/oauth/providers?enabled_only=true" \
  -H "X-Open-Wearables-API-Key: YOUR_API_KEY"
Response:
[
  {
    "provider": "garmin",
    "name": "Garmin",
    "has_cloud_api": true,
    "is_enabled": true,
    "icon_url": "/static/provider-icons/garmin.svg"
  }
]
icon_url is a relative URL (e.g., /static/provider-icons/garmin.svg). Resolve it against your API base URL to get the full path - for example, https://your-api.example.com/static/provider-icons/garmin.svg.