Skip to main content
This guide walks you through a backend integration with Open Wearables: creating users, connecting them to cloud providers (Garmin, Oura, Whoop, Polar, …) via OAuth, and fetching normalized health data.
Apple Health, Health Connect and Samsung Health have no cloud API - their data comes from your mobile app through the SDK. For that part, see the Mobile SDK Integration Guide. Steps 1 and 4 below apply to both.

Prerequisites

  • An Open Wearables instance (self-hosted or cloud)
  • An API key from Settings → Credentials in the developer portal
  • Any backend language - examples use Python (httpx) and TypeScript

Authentication

Send the API key in the X-Open-Wearables-API-Key header:
The API key is not a Bearer token - Authorization: Bearer YOUR_API_KEY returns 401.

Integration Flow Overview

Backend integration flow: 1. your backend creates a user in Open Wearables, 2. gets an authorization URL, 3. your frontend redirects the user to the provider to sign in and approve access, 4. the provider calls back Open Wearables, 5. which redirects the user back to your redirect_uri, 6. Open Wearables backfills history and keeps syncing with the provider via pull or webhooks, 7. your backend fetches data with the API key.

Step 1: User Registration

When a user registers in your application, create a corresponding user in Open Wearables. All fields are optional - you can POST {} and get back a valid user.
The response contains the user’s id (UUID) along with the fields you sent - see Create User for the full shape.
Store the Open Wearables user id on your own user row. Every other call takes it, and Open Wearables doesn’t enforce uniqueness - calling POST /api/v1/users twice with the same email creates two users. Check your stored ID before creating one. The legacy external_user_id field is deprecated and no data endpoint accepts it, so don’t use it for deduplication.

Step 2: Connect Wearable Provider

List available providers

Which providers are enabled depends on your instance, so fetch the list at runtime:
  • enabled_only - only providers enabled in your instance (default false).
  • cloud_only - only OAuth providers, without SDK-only ones like Apple Health (default false). Use it for a web “connect” screen.
  • icon_url is relative - prepend your API base URL.

Get the authorization URL

Provider names are lowercase (garmin, oura, whoop, polar, suunto, …). Pass redirect_uri to send the user back to your app after OAuth:
Redirect the user to authorization_url. After they approve access, the provider calls Open Wearables, which stores the connection and redirects the user to your redirect_uri.

Check connection status

Each connection has a provider and a status (active, revoked or expired). See Get Connections for all fields.

Step 3: Historical Backfill (Automatic)

You don’t need to trigger a sync after OAuth. When a user connects a provider, Open Wearables dispatches a historical backfill:
  • up to 90 days for pull-based providers (Polar, Suunto, Oura, Whoop, Strava, …)
  • up to 30 days for Garmin, whose backfill is capped at 30 days before the user’s consent date
After that, new data arrives automatically - via provider webhooks or periodic polling, depending on the provider. See Historical Data for each provider’s maximum range. This is controlled by HISTORICAL_SYNC_ON_CONNECT (default true). The default is planned to change in a future release. To control the range yourself, set it to false and call POST /api/v1/providers/{provider}/users/{user_id}/sync/historical (days defaults to 90, max 365).

Step 4: Retrieve Health Data

Data endpoints return a paginated envelope:
Pass cursor=<next_cursor> until has_more is false. total_count is only set on the first page. Health scores use offset / limit instead of a cursor.

Activity summary

Daily steps, distance, floors, calories, active/sedentary minutes, intensity minutes, heart rate.

Sleep summary

Daily sleep duration, efficiency, stages, sessions, naps, and average HR/HRV/SpO2.

Body summary

Weight, height, BMI, body fat, averaged resting HR/HRV, latest temperature and blood pressure.

Timeseries

Granular samples (heart rate, steps, SpO2, …) with optional resolution bucketing.

Workouts

Workout sessions with type, duration, calories, distance, heart rate, pace, and elevation.

Health scores

Provider-computed sleep, recovery, readiness, stress, body battery, and strain scores.
Things to know when reading the data:
  • Nullable fields. Apart from identifiers, dates and source, any field can be null - providers report different subsets. See the coverage matrix.
  • source.provider is the provider slug (garmin, apple, health_connect, …). source.device is the raw device model.
  • Sleep durations are in minutes and exclude naps, which are reported separately.
  • Recovery summary returns data only for WHOOP.
  • Body summary is a single object, not a paginated list, and is null when the user has no body data.
  • Timeseries requires start_time and end_time. types is optional and repeated (?types=heart_rate&types=steps) - without it, all series types are returned.

Example client


Troubleshooting

If your app runs in Docker and Open Wearables runs on the host machine:
docker-compose.yml
Use X-Open-Wearables-API-Key: YOUR_API_KEY, not Authorization: Bearer YOUR_API_KEY.
The backfill runs asynchronously and takes from seconds to several minutes, depending on the provider and the amount of history - Garmin can take hours. last_synced_at on the connection is set when the user connects, so it doesn’t tell you whether the backfill finished. Check GET /api/v1/users/{user_id}/sync/runs for sync progress instead.If HISTORICAL_SYNC_ON_CONNECT=false on your instance, no backfill runs automatically - see Step 3.
Check that start_time / end_time cover the period you expect, and that the user has that series type - GET /api/v1/users/{user_id}/summaries/data shows what’s been ingested.
Pass redirect_uri when requesting the authorization URL.

Next Steps

API Reference

All endpoints with request and response schemas.

Mobile SDK

Add Apple Health, Health Connect and Samsung Health via your mobile app.

Provider Setup

Configure OAuth credentials for each provider.

Data Model

Understand the unified health data model.