Back to blog

Garmin Connect API: What You Can Fetch and How to Do It Faster

Open Wearables Team · · 8 min read

The Garmin API gives you access to workouts, health metrics, and device data from Garmin Connect. Here is what you can retrieve, how the OAuth 1.0 flow works, and when it makes sense to use a ready-made integration layer instead of building from scratch.

Key Takeaways

  • Garmin Connect API requires Partner Program approval before you get production credentials. Plan for this in your timeline
  • Garmin uses OAuth 1.0a, which requires signed requests (HMAC-SHA1) that most modern OAuth 2.0 libraries do not handle
  • Available data includes activities, daily health metrics (steps, sleep, SpO2, stress), continuous series (HR, cadence, power), and user profile
  • Garmin delivers activity data through webhooks, not polling. Your infrastructure needs a publicly accessible endpoint to receive it
  • The normalization problem compounds with every provider you add. The first integration looks fast; the third reveals every assumption you made
  • Open Wearables handles OAuth, token management, normalization, and deduplication as a self-hosted layer you deploy once

What the Garmin API Returns

Garmin Connect is the cloud platform that syncs data from all Garmin devices. A run logged on a Forerunner, power data from a cycling computer, a sleep cycle from a Venu, resting heart rate from a Fenix. Everything lands in Garmin Connect and is available through the garmin api.

The Garmin Health API (documented at developer.garmin.com/health-api) is the interface intended for external application developers. It is distinct from Garmin Connect IQ, which is for on-device apps. The Health API is what you use when you want to read Garmin health data from your backend.

What you can fetch:

  • Activities (Events): runs, cycling, swimming, triathlon. Each activity includes start and stop timestamps, distance, average and max heart rate, calories, sport type. GPS-tracked activities include full route data as a series of lat/lng points.
  • Health metrics: steps, resting heart rate, sleep phases (light, deep, REM), SpO2, stress score. This garmin health data is available as daily aggregates per user.
  • Continuous data (Series): heart rate sampled every few seconds during a workout, cadence, power for cyclists with a power meter. Granular time-series data is useful for load management algorithms or performance analysis.
  • Profile: weight, height, age, sex. Static data, but important for calibrating algorithms like VO2 max estimates or caloric targets.

One important caveat: access to the Garmin Health API requires going through the Garmin Partner Program. Garmin must review and approve your application before issuing production OAuth credentials. This is not a public open API with self-service access. Budget a few weeks for this step.

OAuth 1.0: Why It Takes More Work

Garmin uses OAuth 1.0a. Most modern libraries and newer providers have moved to OAuth 2.0, so OAuth 1.0 requires a bit more attention.

Standard OAuth 2.0 is two steps: authorization code and access token. OAuth 1.0a adds a third: a request token you must obtain before redirecting the user to authorize. On top of that, every API request must be signed (HMAC-SHA1) with a unique timestamp and nonce. OAuth 2.0 libraries will not do this for you.

In practice, the flow looks like this:

  1. Fetch a request token from Garmin (request signed with your app key)
  2. Redirect the user to Garmin for authorization (with the request token in the URL)
  3. After the callback, exchange the request token and verifier for an access token
  4. Sign every subsequent API request with the access token, timestamp, and nonce

For a single application with one provider, this is manageable. The problem starts when you also need Polar (its own OAuth 2.0 flow), Whoop (OAuth 2.0 with webhooks), and Apple Health (no OAuth at all, Flutter SDK). Each provider has a different flow, different token format, and different edge case behavior.

Token expiry is another layer. Garmin access tokens do not expire, but you still need to handle the case where a user revokes access or the token becomes invalid. For providers like Strava, tokens expire every six hours and require automatic refresh logic. Supporting multiple providers means building refresh logic for each one separately.

Webhook Delivery: What It Means for Your Infrastructure

Garmin delivers activity data through push webhooks, not through a polling endpoint you call on demand. When a user syncs their device, Garmin pushes the data to a callback URL you register.

This means your backend needs a publicly accessible endpoint at a stable URL to receive Garmin data. If you are building in a local development environment, you will need something like ngrok to expose your local server for testing. In production, the endpoint must be reliable: if it is down when Garmin pushes, you miss that sync.

The webhook payload contains the activity data in Garmin's schema. You process it, normalize it, and store it. If your endpoint returns an error, Garmin's retry behavior is limited, so the reliability requirement is real.

For comparison, Oura and Strava also use webhooks. Whoop is webhook-only. Polar and Suunto support polling. If you are building for multiple providers, you end up with a mix of push and pull patterns running in parallel.

Normalization: The Hidden Cost of Every Integration

Garmin returns a running activity as a JSON object with fields in its own schema. Polar returns the same activity differently: different field names, different units (Garmin returns distance in meters, Polar in kilometers), different timestamp format. Apple Health does its own thing.

A user training with a Garmin Fenix often also has a phone with Apple Health syncing the same runs. If your application listens to both providers, the same workout will appear twice in your data. Deduplication based on start time and distance is only an approximation, because providers differ by small amounts in timestamps.

Sleep data is particularly inconsistent across providers. One provider may report a single sleep block with a duration. Another reports phases: light, deep, REM, awake, in separate records. A third reports segments with different phase definitions. Any downstream calculation that uses sleep as a signal (recovery scores, readiness metrics, sleep debt) has to resolve this before it can produce a meaningful result.

This is the cost that is almost always underestimated at the planning stage. The first API integration is quick. The second requires a normalization layer. The third reveals all the edge cases that were missed earlier.

When Direct Integration Makes Sense, and When It Does Not

Makes sense when:

  • You are building an internal tool only for Garmin users
  • You have no plans to add other providers
  • You have time for Partner Program approval and handling OAuth 1.0 and webhook infrastructure

Starts to not make sense when:

  • You plan to support more than one provider now or in the future
  • You want to build intelligent features (sleep score, recovery, trend analysis) rather than just displaying raw data
  • Time to implementation is a constraint

Based on experience across dozens of healthtech projects, handling a single provider from scratch takes between 6 and 12 months of engineering time. Each additional provider adds less, but the normalization layer between them has a fixed cost that grows with every edge case you discover in production.

Open Wearables as a Ready-Made Integration Layer

Open Wearables is an open-source platform for aggregating wearable device data. MIT license, self-hosted, zero per-user fees.

Garmin is one of the supported providers. The platform also supports Polar, Suunto, Whoop, Oura, Strava, Fitbit, Apple HealthKit, Samsung Health, and Google Health Connect.

Instead of handling OAuth 1.0 directly, you get a single unified data model:

  • EventRecord with EventRecordDetails: activities with aggregated values and timestamps
  • DataPointSeries: continuous data (heart rate, cadence) as normalized series
  • PersonalRecord: static user data

Deduplication and normalization across providers are built in. When a user has both a Garmin and Apple Health syncing the same run, it will not appear twice in your data.

Garmin webhook registration is handled by OW. You do not need to set up separate webhook infrastructure for Garmin; incoming data arrives through the same normalized API as other providers.

Setup:

            git clone https://github.com/the-momentum/open-wearables
cd open-wearables
cp .env.example .env
# Add your Garmin Client ID and Client Secret
docker compose up -d
make init
          

First API call after connecting a Garmin account through OAuth:

            curl -H "X-API-Key: YOUR_API_KEY" \
  http://localhost:8000/api/v1/workouts
          

The response structure is the same regardless of whether the workout came from Garmin, Polar, or any other provider. Your application code does not branch on provider.

If you need more than raw data, the platform also includes open algorithms for sleep score, recovery, HRV, and VO2 max. Every algorithm is in the repository, readable and modifiable.

Related articles

FAQ

Does Garmin require my users to have a Garmin Connect account?

Yes. The Garmin Health API reads from Garmin Connect. Your users must have a Garmin Connect account and connect it to your application through the OAuth flow. Data syncs when they sync their device to Garmin Connect, which on most devices happens over Bluetooth to the Garmin Connect app on their phone.

Does Open Wearables handle Garmin's webhook delivery?

Yes. OW registers and manages Garmin webhook endpoints. You do not need to set up separate webhook infrastructure for Garmin; data arrives through the same normalized API as other providers.

How long does Garmin Partner Program approval take?

Timelines vary and are not publicly documented. Garmin reviews applications and may request additional information about your use case. Check the current process at developer.garmin.com. This is typically the most unpredictable part of the Garmin integration timeline.

What data does Garmin not expose through the Health API?

Not all data visible in the Garmin Connect app is available through the Health API. Real-time streaming data (live workouts) and some advanced metrics from newer sensors may not be available, or may require specific partnership tiers. Check the Garmin Health API documentation at developer.garmin.com for the current scope of available data types.

Can I fetch historical data after a user first connects?

Backfill availability depends on the data type and your Garmin partnership agreement. Check the current scope at developer.garmin.com, as this varies by partnership tier. New data arrives via webhook going forward after the initial connection.

What happens when a user connects both Garmin and another device that records the same activity?

Open Wearables stores records from each provider separately, deduplicated by external ID within a provider. A run recorded on a Garmin watch and synced to Strava will produce two records. Merging them is application-level logic, because the definition of the same activity depends on your use case.

Never miss an update

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

Join our Community. No spam ever.