Skip to main content
Open Wearables supports connecting to multiple wearable providers including Garmin, Whoop, Strava, Polar, and Suunto. Each provider uses OAuth 2.0 for secure authentication.

Supported Providers

Before connecting, check which providers are available and enabled:
curl -X GET "https://api.openwearables.com/api/v1/oauth/providers?enabled_only=true&cloud_only=true" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response:
[
  {
    "id": "garmin",
    "name": "Garmin",
    "icon_url": "https://example.com/garmin-icon.png",
    "has_cloud_api": true,
    "is_enabled": true
  },
  {
    "id": "whoop",
    "name": "Whoop",
    "icon_url": "https://example.com/whoop-icon.png",
    "has_cloud_api": true,
    "is_enabled": true
  }
]
Use cloud_only=true to filter only OAuth-enabled providers. Some providers may support local device sync only.

OAuth Connection Flow

1

Get authorization URL

Request an authorization URL for the user to visit:
curl -X GET "https://api.openwearables.com/api/v1/oauth/garmin/authorize?user_id=550e8400-e29b-41d4-a716-446655440000&redirect_uri=https://yourapp.com/success" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response:
{
  "authorization_url": "https://connect.garmin.com/oauthConfirm?oauth_token=abc123...",
  "state": "xyz789..."
}
user_id
UUID
required
Open Wearables user ID to connect
redirect_uri
string
Optional URL to redirect user after successful connection. If omitted, uses default success page.
2

Redirect user to authorization URL

Send the user to the authorization_url in their browser. They’ll log in to their wearable provider account and grant permissions.
// Redirect user to authorization URL
window.location.href = response.authorization_url;
3

Handle callback

After authorization, the provider redirects back to Open Wearables callback URL:
https://api.openwearables.com/api/v1/oauth/garmin/callback?code=AUTH_CODE&state=xyz789...
Open Wearables automatically:
  • Exchanges the authorization code for access tokens
  • Stores the connection in the database
  • Triggers an initial data sync
  • For Garmin: Starts a 30-day historical data backfill
  • Redirects to your redirect_uri or the default success page
You don’t need to implement the callback endpoint - Open Wearables handles this automatically.
4

Verify connection

Check that the connection was created successfully:
curl -X GET https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/connections \
  -H "Authorization: Bearer YOUR_API_KEY"
Response:
[
  {
    "id": "conn_123",
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "provider": "garmin",
    "provider_user_id": "garmin_user_456",
    "scope": "ACTIVITY_EXPORT HEALTH_EXPORT",
    "created_at": "2026-03-07T10:30:00Z",
    "is_active": true
  }
]

Provider-Specific Notes

Garmin

  • Automatic backfill: On first connection, Garmin automatically backfills up to 30 days of historical data
  • Webhook support: Real-time data updates via push/ping webhooks
  • Data types: Activities, sleep, daily summaries, heart rate, stress, HRV, body composition, and more
  • Permissions: Requires ACTIVITY_EXPORT and HEALTH_EXPORT scopes

Whoop

  • Recovery scores: Provides detailed recovery, strain, and sleep metrics
  • Real-time data: Updates throughout the day as user syncs their device
  • Rate limits: Respects Whoop API rate limits (200 requests per 5 minutes)

Strava

  • Activity focused: Primarily provides workout/activity data
  • Public activities: Only syncs public activities by default
  • Webhook support: Real-time activity updates via webhooks

Polar

  • Training data: Comprehensive training metrics and heart rate zones
  • Sleep analysis: Detailed sleep stage data

Suunto

  • Outdoor activities: Strong support for outdoor sports and GPS tracking
  • Training insights: Detailed exercise and recovery metrics

Connection Management

List User Connections

curl -X GET https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/connections \
  -H "Authorization: Bearer YOUR_API_KEY"

Check Connection Status

Connections can become inactive if:
  • User revokes access from the provider’s website
  • Access token expires and refresh fails
  • Provider account is deleted
The is_active field in the connection response indicates current status.
If a connection becomes inactive, you’ll need to restart the OAuth flow to re-establish the connection.

Webhooks for Real-Time Updates

Many providers support webhooks to push data in real-time instead of polling:
  • Garmin: Push and ping notifications for activities, sleep, and wellness data
  • Strava: Activity creation/update webhooks
Webhooks are automatically configured when you connect a user. No additional setup required.

Testing Connections

For development and testing:
  1. Use sandbox environments when available (Garmin, Strava)
  2. Test with your own accounts first
  3. Check logs in the Open Wearables dashboard for connection errors
  4. Verify data sync by querying the events or summaries endpoints

Troubleshooting

Connection fails during OAuth

  • Verify the user_id exists in your system
  • Check that the provider is enabled in your account settings
  • Ensure your API key has proper permissions

No data appears after connection

  • Wait a few minutes for initial sync to complete
  • Check connection status - it should be is_active: true
  • For Garmin backfill, check the backfill status endpoint
  • Review webhook logs if applicable

Token expired errors

  • Open Wearables automatically refreshes tokens when needed
  • If refresh fails, the connection becomes inactive
  • User will need to reconnect via OAuth flow

Next Steps

Access Data

Retrieve workouts, sleep, and health metrics

Webhooks

Set up webhooks to receive real-time data updates

Build docs developers (and LLMs) love