Integrations

beta

Your users connect a provider account once; Sahha syncs their data continuously — server-side, no SDK to ship.

Introduction

Integrations pull health data straight from a provider's cloud — Garmin , Oura , Whoop — into Sahha, with no SDK on the device . The user connects their provider account once; Sahha syncs their data continuously onto the same profile. It's the third way to get data into Sahha, alongside the SDK and REST API .

Public beta

Integrations are in public beta and ready to build with today. We're still refining the API surface as it matures and will call out any breaking changes here as they land.


Supported providers

Provider Slug Device Connection Status
Garmin garmin Watch Cloud OAuth Beta Garmin approval required
Oura oura Ring Cloud OAuth Beta self sign-up
Whoop whoop Band Cloud OAuth Coming soon
Samsung Health Phone / watch On-device SDK Coming soon collected via the SDK

The slug is the value you pass as {provider} throughout the API (see Connect a user ).

Need another provider?

Request one in the Slack Community — tell us the provider and the data you need. Demand drives our priority.


Data coverage

What you get depends on the provider, the user's device, and the scopes you enable. Sahha normalizes every provider into the same data logs , biomarkers , scores and archetypes — so once data is in, you consume it the same way regardless of source.

The matrix below is indicative . See each provider's page for the authoritative, scope-by-scope list.

Data GarminOuraWhoop (soon)
Steps & activity
Sleep & sleep stages
Heart rate
Heart rate variability
Blood oxygen (SpO₂)
Respiratory rate
Body temperature
Workouts & exercise
VO₂ max / fitness
Body composition
Menstrual cycle
Blood pressure
Demographics

available · not provided. Exact availability depends on the user's device and the scopes you enable — see each provider's page.

Scores are computed from whatever you collect

Sahha Scores (Sleep, Activity, Readiness, Wellbeing, Mental) are derived from the underlying data — so a connected provider contributes to scores automatically, even if it doesn't expose a matching raw metric. More data sources generally mean more complete scores.


Data freshness & history

Every provider is push-based : the provider notifies Sahha over webhooks as new data is recorded, so data usually lands within minutes of the user's device syncing to the provider's cloud. Sahha does not poll on a fixed schedule.

When a user first connects, Sahha backfills the last 30 days of available history, then syncs continuously from then on.

Provider Live sync Backfill on connect
Garmin Push (webhooks) 30 days — Requires the user to grant Garmin's historical-data permission
Oura Push (subscriptions) 30 days
Whoop (soon) Push (webhooks) 30 days

Latency depends on the device

End-to-end freshness is bounded by when the user's device syncs to the provider — e.g. an Oura ring that syncs once each morning delivers the night's data at that point, not in real time. Sahha forwards it within minutes of receiving it.

Garmin historical permission

If a Garmin user does not grant historical-data permission during authorization, the 30-day backfill is skipped and only data recorded after connection flows in. Going-forward sync is unaffected.


How it works

Integrations use three concepts. The same vocabulary appears in the dashboard and the API:

Term What it is
Provider A data source you can connect — Garmin, Oura, Whoop.
Integration Your configured app for a provider — the OAuth credentials and scopes you set up once in the Sahha Dashboard.
Connection One end-user's authorized link to a provider, created when they complete the OAuth flow.

Setting up a provider is three steps:

  1. Create an app with the provider — register in the provider's developer console to obtain OAuth credentials.
  2. Create an integration in Sahha — add those credentials to your project in the Sahha Dashboard .
  3. Connect an end user — start the OAuth flow for a user via the Sahha API or SDK. Once they authorize, Sahha begins syncing automatically.

Follow the provider-specific guide above for exact console steps and scopes.


Connect a user

Once an integration is configured, you trigger the connection flow per end user. There are two ways: the API (server-driven or web flows) and the SDK (native mobile).

Before you start

You need:

  • A configured integration for the provider (the three steps above).
  • A profile token for the end user — this scopes the connection to that specific user. See Authentication for how tokens work and Getting Started to obtain one.
  • The end user to have an account with the provider (e.g. a Garmin Connect or Oura account).

Examples use the sandbox environment ( sandbox-api.sahha.ai). Swap to api.sahha.ai for production — see Environments .

Option A — Sahha API

The connection is a standard OAuth redirect round-trip:

  1. You call Sahha's authorize endpoint with the user's profile token. Sahha returns an authorizationUrl.
  2. You redirect the user's browser to that authorizationUrl (the provider's consent screen).
  3. The user approves access on the provider's site.
  4. The provider redirects back to Sahha's callback; Sahha stores the connection and starts syncing.
  5. Sahha redirects the user to your redirectUrl so your app can show a success state.

The optional redirectUrl must match an entry in the integration's Redirect URL Whitelist; if omitted, Sahha uses the first whitelisted URL.

curl -X GET "https://sandbox-api.sahha.ai/api/v1/integration/oauth/{provider}/authorize?redirectUrl=https://yourapp.com/integrations/callback" \
-H "Authorization: profile {your-profile-token}"
{
"authorizationUrl": "https://connect.garmin.com/oauthConfirm?..."
}

Replace {provider} with the provider's slug from the Supported providers table (e.g. garmin). Each provider's page has the full request and language-specific snippets.

Once a user is connected, you read their data the same way as any other Sahha data — via the REST API or Webhooks . There's nothing integration-specific about consuming it.

Option B — Sahha SDK

Coming soon

SDK support for Integrations is in development. The connection flow will be initiated from the native SDK; the API above is available today.


Managing connections

A connection moves through a simple lifecycle: connected → (token expires) needs re-auth → disconnected . You can see and manage every connection in the Sahha Dashboard under Integrations → Connections .

Disconnecting a user

A connection can be revoked in any of three ways:

  • From the Sahha Dashboard under Integrations → Connections
  • By calling the disconnect endpoint below
  • By the user, from their own provider account settings

Sahha stops ingesting data immediately on disconnection.

Method Endpoint
DELETE /api/v1/integration/connection/{accountId}/{connectionId}

Disconnecting is a server-side admin action, so it uses your account token — not a user's profile token (see Authentication ). Find the {accountId} and {connectionId} in the Sahha Dashboard under Integrations → Connections .

curl -X DELETE "https://sandbox-api.sahha.ai/api/v1/integration/connection/{accountId}/{connectionId}" \
-H "Authorization: account {your-account-token}"

Returns 204 No Content on success.

Deleting an integration

Deleting an integration from the dashboard also deletes and deregisters every connection under it — every user connected with those credentials is disconnected.


Troubleshooting

A user connected but no data is arriving

Confirm the integration's scopes match the scopes enabled on your provider app — a mismatch causes the OAuth flow to fail silently or return empty data. For providers that deliver via webhooks (e.g. Garmin), also confirm the endpoints are enabled and set to push , not pull.

The OAuth flow fails immediately

The most common cause is requesting a scope your provider app doesn't have access to. Deselect any scopes your app isn't approved for, then retry. Also check that the redirectUrl you passed matches an entry in the Redirect URL Whitelist.

How far back does data go when a user first connects?

The historical backfill window depends on the provider. See the provider page for specifics; new data flows continuously once connected.


Support

Need help? Contact support@sahha.ai or join the Slack Community . </content> </invoke>

Next
SDK