Sleep data from every wearable, in one schema

Sleep stages, duration, efficiency and timing, normalised across every ring, watch and mattress sensor.

7 / 12

Providers connectable today

4

Webhook events in this family

seconds for durations, ISO-8601 timestamps for boundaries

Canonical units

What sleep looks like through one API

Sleep is the metric developers most often assume is standardised and most often discover is not. Every provider reports a duration, a set of stages and some efficiency figure, but almost nothing about how those numbers are produced is shared between them. Two devices on the same person on the same night routinely disagree by 30–50 minutes of total sleep time and by considerably more on individual stages.

WearLink normalises the parts that can honestly be normalised — session boundaries, total and per-stage durations in seconds, efficiency as a percentage, and the timestamps that anchor a session to a calendar date — and leaves the provider-specific scores alongside rather than pretending they are interchangeable. You get one object shape whether the night came from an Oura ring, a WHOOP band or an Eight Sleep mattress.

The hard part is not parsing sleep; it is deciding which night a session belongs to and knowing when a provider has silently revised it. Both are handled below the API surface, so your code sees a single settled record per session and a webhook when one changes.

Where providers disagree

The part that costs you weeks if you build this yourself. None of the following is a WearLink limitation — it is how the underlying providers actually behave.

Stage taxonomies do not line up

Some providers report four stages (awake, light, deep, REM), some collapse light and deep into a single "core" bucket, and some emit only asleep/awake. Summing a four-stage night and a two-stage night into the same chart produces a comparison that looks meaningful and is not. WearLink maps to the common set and marks which stages were actually measured versus inferred, so you can exclude devices that cannot answer the question you are asking.

Which day does a night belong to?

A session running 23:40 to 07:10 is attributed to the start date by some providers and the wake date by others. Get this wrong and every weekly aggregate is off by one for roughly half your users. WearLink stores both the session boundaries and an explicit attribution date so you can pick a convention and apply it uniformly.

Nights get revised after you fetch them

Oura recalculates as the ring syncs more data; Fitbit restates when a device backfills. A night you read at 08:00 can legitimately differ by 09:00. Polling once and caching produces silently stale data. WearLink refetches on the provider notification and emits a webhook with the corrected record.

Naps are inconsistently included

Some providers emit a separate short session for a daytime nap; others fold it into the main sleep record or drop it entirely. If your product computes "hours slept per day", the naps decision changes the answer. The normalised record flags session type so you can include or exclude deliberately.

Providers that supply sleep

Status is read from the same provider table the rest of the site uses, so nothing here can claim a provider is connectable when it is not. Coverage also varies by hardware generation within a brand.

ProviderCategoryStatus
OuraCloud OAuthLive
WHOOPCloud OAuthLive
FitbitCloud OAuthLive
WithingsCloud OAuthLive
GarminCloud OAuthOnboarding
PolarCloud OAuthOnboarding
SuuntoCloud OAuthOnboarding
UltrahumanCloud OAuthOnboarding
Eight SleepCloud OAuthOnboarding
Apple HealthMobile SDKMobile SDK
Google Health ConnectMobile SDKMobile SDK
Samsung HealthMobile SDKMobile SDK

Webhook events for sleep

Subscribe to the summary event for settled records, and to the series streams when you need the underlying samples. Event names below are generated from the backend enum, so they cannot drift out of date relative to the API.

Summary object

sleep.created

Series streams

series.sleeping_breathing_disturbances.createdseries.breathing_disturbance_index.createdseries.respiratory_rate.created

Frequently asked questions

Which wearables can WearLink pull sleep data from?
Sleep is mapped for Oura, WHOOP, Fitbit, Withings, Garmin, Polar, Suunto, Ultrahuman and Eight Sleep on the cloud side, plus Apple Health, Health Connect and Samsung Health via the mobile SDKs. Provider connection status varies — the table on this page shows what is connectable today.
Are sleep stages comparable between Oura and WHOOP?
Durations are comparable in the sense that both report seconds in each stage, but the underlying classifiers differ and will disagree on the same night. Treat cross-device stage comparisons as directional, not equivalent. Within a single user on a single device, trends are reliable.
How do I get notified when new sleep data arrives?
Subscribe to the sleep.created webhook event. WearLink delivers the full normalised session in the payload, so you do not need a follow-up API call, and re-delivers when a provider revises a night.
Can I get breathing and respiratory data with sleep?
Yes — series.respiratory_rate.created, series.sleeping_breathing_disturbances.created and series.breathing_disturbance_index.created carry the higher-resolution respiratory streams where the device supports them.

Related data types

15 normalised data families in total — see them all or browse integrations by provider.