Back to blog

How to integrate Polar data into your health app

Open Wearables Team · · 5 min read

Key Takeaways

  • Polar uses the AccessLink API, which requires OAuth 2.0 setup, token management, and a polling model. Building this yourself means handling token refresh, transaction lifecycle, and per-user state storage before you get a single data point.
  • Open Wearables abstracts all of that. You connect a user once via a single OAuth endpoint, and subsequent syncs are one POST call.
  • The sync endpoint accepts optional parameters (samples, zones, route) so you pull only the data your app actually needs.
  • After sync, you read Polar data through the same generic endpoints (/events/workouts, /events/sleep, /timeseries) as every other provider. No Polar-specific parsing code in your app.
  • Open Wearables normalizes all values to canonical units: bpm for heart rate, meters for distance, Celsius for temperature, UTC for timestamps.
  • Polar coverage includes workouts, sleep with stages, and HRV. Continuous 24/7 data is not available through AccessLink.
  • The full local stack runs in under five minutes with git clone and docker compose up -d.

The Problem: What Direct Polar API Integration Actually Costs You

The Polar API (AccessLink) is well-documented and reasonably capable. If you sit down to integrate it directly, here is what you are actually building.

OAuth 2.0 flow. You register an application, implement the authorization redirect, handle the callback, exchange the code for access and refresh tokens, and store per-user credentials securely. Standard OAuth, but boilerplate you have to write and maintain.

Token lifecycle. AccessLink tokens expire. You need a refresh mechanism, error handling for when refresh fails, and a way to prompt re-authorization. If your token store goes stale, all syncs silently fail.

Polling and transaction management. AccessLink uses a pull model with transaction semantics. To retrieve new data, you create a transaction, list available items, fetch each item, and then commit the transaction. If you commit before fetching everything, you lose that batch. You need to handle partial failures, retries, and the case where there is no new data.

Data normalization. AccessLink returns heart rate in bpm and distance in meters in most endpoints, but timestamps are in ISO 8601 with timezone offsets that vary by device locale. Sleep stage data comes in a different shape than workout data. HRV metrics have their own structure. None of this maps directly to a common schema without work.

Multiply this by every other provider you plan to support and the integration surface becomes significant.

What Open Wearables Does Under the Hood

Open Wearables wraps AccessLink entirely. When you call its Polar endpoints, here is what happens inside:

  • OAuth credential storage and refresh are handled per user. Your app never touches Polar tokens directly.
  • Polling is managed by the sync call. Open Wearables creates the AccessLink transaction, iterates items, commits on success, and retries on transient errors.
  • All data is normalized before it reaches your app. Heart rate in bpm, distance in meters, temperature in Celsius, all timestamps in UTC.
  • Exercise type codes from AccessLink are mapped to a common activity type vocabulary.

The result is that your application code has no Polar-specific logic. You call the same endpoints you would call for any other provider.

Setup and OAuth Flow

            git clone https://github.com/the-momentum/open-wearables.git
cd open-wearables
docker compose up -d
          

The API is available at http://localhost:8000. All requests use the X-Open-Wearables-API-Key header.

Authorizing a user:

            GET /api/v1/oauth/polar/authorize?user_id={user_id}&redirect_uri={your_callback_url}
          

Open Wearables handles the AccessLink OAuth exchange and stores the credentials. Your callback receives confirmation that the user is connected. From this point, you do not manage Polar credentials for this user.

Syncing Data

Once a user is authorized, trigger a sync:

            POST /api/v1/providers/polar/users/{user_id}/sync
          

This fetches new workouts and sleep data since the last sync. Optional parameters give you control over payload size:

  • samples (default false): detailed heart rate samples per workout
  • zones (default false): heart rate zone breakdown
  • route (default false): GPS route data

Full sync with all optional data:

            POST /api/v1/providers/polar/users/{user_id}/sync?samples=true&zones=true&route=true
          

Use the baseline when you only need summary metrics or aggregate sleep. Pulling fewer fields means faster syncs and smaller stored payloads.

Reading Data

After sync, data is available through the standard provider-agnostic endpoints:

            GET /api/v1/users/{user_id}/events/workouts
GET /api/v1/users/{user_id}/events/sleep
GET /api/v1/users/{user_id}/timeseries
          

The provider field in each response tells you the source, but your query logic does not need to branch on it. If you are building a dashboard that shows runs from multiple devices, you query /events/workouts once. Polar runs, Garmin runs, and Suunto runs all come back in the same normalized format.

Sleep data includes fields for sleep stages (light, deep, REM) where the device provides them. Polar provides sleep stage data, so those fields will be populated. HRV is available through the timeseries endpoint.

Limitations to Know Before You Build

No continuous 24/7 data. AccessLink does not expose continuous heart rate streams or step counts in real time. If your app requires continuous HR monitoring or live activity tracking, Polar through this integration is not the right fit.

Polling latency. Because AccessLink is pull-based, data freshness depends on your sync frequency. There is no instant notification when a user completes a workout.

Webhook support is upcoming. Provider Webhook Subscriptions for Polar are on the Open Wearables roadmap, which will enable event-driven syncs when it ships.

Quickstart

            # 1. Clone and start the stack
git clone https://github.com/the-momentum/open-wearables.git
cd open-wearables
docker compose up -d

# 2. Authorize a user
curl "http://localhost:8000/api/v1/oauth/polar/authorize?user_id=user_001&redirect_uri=http://localhost:3000/callback" \
  -H "X-Open-Wearables-API-Key: your_key"

# 3. Trigger sync
curl -X POST http://localhost:8000/api/v1/providers/polar/users/user_001/sync \
  -H "X-Open-Wearables-API-Key: your_key"

# 4. Read workouts
curl http://localhost:8000/api/v1/users/user_001/events/workouts \
  -H "X-Open-Wearables-API-Key: your_key"

# 5. Sync with full detail
curl -X POST "http://localhost:8000/api/v1/providers/polar/users/user_001/sync?samples=true&zones=true&route=true" \
  -H "X-Open-Wearables-API-Key: your_key"
          

See Related Articles

FAQ

Does Open Wearables support real-time Polar data?

No. AccessLink is a polling API. There is no real-time or streaming data available through this integration. Provider Webhook Subscriptions for Polar are on the Open Wearables roadmap, which will reduce latency once available.

Can I pull Polar data alongside data from other providers in the same query?

Yes. After syncing, all data is stored in Open Wearables' normalized schema. Queries to /events/workouts, /events/sleep, and /timeseries return results across all connected providers for a given user.

What happens if a Polar user revokes access?

When AccessLink returns an authorization error during a sync, Open Wearables surfaces that as an error response. Your app should handle this by prompting the user to re-authorize via the OAuth endpoint.

Is HRV data available from Polar?

Yes. HRV data is available through the /timeseries endpoint after sync. Polar provides HRV from overnight recordings on supported devices. The data follows the same canonical schema as HRV from other providers.

How do the optional sync parameters affect stored data?

The samples, zones, and route parameters control what is fetched and stored during that sync call. If you sync without samples=true, heart rate sample arrays are not retrieved or stored for those workouts. Pull the detail you need at sync time.

Never miss an update

Stay updated with the latest in open wearables, developer tools, and health data integration.

Join our Community. No spam ever.