Oura Ring is a smart ring health tracking platform that provides a REST API for accessing sleep, activity, readiness, heart rate, daily health scores, and 50+ biometric metrics via OAuth2. Developers can build integrations that allow users to share their Oura Ring data with third-party services, supporting endpoints for sleep stages, workout detection, SpO2, heart rate variability, body temperature, and more. The platform also supports webhooks for near real-time data updates.
Oura Ring publishes 21 APIs on the APIs.io network, including Daily Activity Routes API, Daily Cardiovascular Age Routes API, Daily Readiness Routes API, and 18 more. Tagged areas include Health, Wearables, Sleep, Fitness, and Heart Rate.
The Oura Ring catalog on APIs.io includes 1 JSON-LD context and 1 Spectral governance ruleset.
Oura Ring’s developer surface includes authentication, documentation, engineering blog, pricing, and 15 more developer resources.
The Daily Activity scope includes daily activity summary values and detailed activity levels. Activity levels are expressed in [metabolic equivalent of task minutes](https://en....
Cardiovascular Age is an estimate of the health of your cardiovascular system in relation to your actual age. See more details [here](https://support.ouraring.com/hc/en-us/artic...
The daily stress route includes a summary of the number of minutes the user spends in high stress and high recovery each day. This is a great way to see how your stress and reco...
The Enhanced Tags data scope includes tags that Oura users enter within the Oura mobile app. Enhanced Tags can be added for any lifestyle choice, habit, mood change, or environm...
The Heart Rate data scope includes time-series heart rate data throughout the day and night. Heart rate is provided at 5-minute increments. For heart rate data recorded from a S...
The Personal Info scope includes personal information (e.g. age, email, weight, and height) about the user. You can access the id on the personal_info route with any access toke...
Fake user data that you can access without an Oura account. There is a corresponding sandbox endpoint to each available data type. This is useful for testing and development pur...
The Sessions data scope provides information on how users engage with guided and unguided sessions in the Oura app, including the user's biometric trends during the sessions.
VO2 Max is a measure of the maximum volume of oxygen that an individual can use during intense exercise. See more details [here](https://support.ouraring.com/hc/en-us/articles/2...
# Webhooks for Real-Time Data Updates ## What are Webhooks? Webhooks are a way for the Oura API to notify your application when new data is available, instead of requiring your ...
The Workout data scope includes information about user workouts. This is a diverse, growing list of workouts that help inform how the user is training and exercising.
Oura Ring is a smart ring for sleep, recovery, and activity tracking. The API covers sleep stages, readiness scores, activity metrics, heart rate, HRV, SpO2, and workout detecti...
aid: oura
name: Oura Ring
description: Oura Ring is a smart ring health tracking platform that provides a REST API for accessing sleep, activity, readiness,
heart rate, daily health scores, and 50+ biometric metrics via OAuth2. Developers can build integrations that allow users
to share their Oura Ring data with third-party services, supporting endpoints for sleep stages, workout detection, SpO2,
heart rate variability, body temperature, and more. The platform also supports webhooks for near real-time data updates.
type: Index
accessModel:
pricing: free
onboarding: self-serve
trial: false
try_now: true
public: false
label: Free · Self-serve signup
confidence: high
source:
- plans
- authentication
generated: '2026-07-22'
method: derived
image: https://kinlane-images.s3.amazonaws.com/shared/apis-json/icons/oura.png
url: https://raw.githubusercontent.com/api-evangelist/oura/refs/heads/main/apis.yml
created: '2026-06-13'
modified: '2026-06-13'
specificationVersion: '0.19'
tags:
- Health
- Wearables
- Sleep
- Fitness
- Heart Rate
- Readiness
- Smart Ring
- Biometrics
apis:
- aid: oura:oura-daily-activity-routes-api
name: Oura Ring Daily Activity Routes API
description: The Daily Activity scope includes daily activity summary values and detailed activity levels. Activity levels
are expressed in [metabolic equivalent of task minutes](https://en.wikipedia.org/wiki/Metabolic_equivalent) (MET mins).
Oura tracks activity based on the movement.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Activity Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-activity-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-daily-cardiovascular-age-routes-api
name: Oura Ring Daily Cardiovascular Age Routes API
description: Cardiovascular Age is an estimate of the health of your cardiovascular system in relation to your actual age.
See more details [here](https://support.ouraring.com/hc/en-us/articles/28451491040019-Cardiovascular-Age).
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Cardiovascular Age Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-cardiovascular-age-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-daily-readiness-routes-api
name: Oura Ring Daily Readiness Routes API
description: Readiness tells how ready you are for the day.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Readiness Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-readiness-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-daily-resilience-routes-api
name: Oura Ring Daily Resilience Routes API
description: Resilience is an estimate of your ability to withstand physiological stress and recover from it over time.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Resilience Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-resilience-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-daily-sleep-routes-api
name: Oura Ring Daily Sleep Routes API
description: Sleep period is a nearly continuous, longish period of time spent lying down in bed.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Sleep Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-sleep-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-daily-spo2-routes-api
name: Oura Ring Daily Spo2 Routes API
description: The Daily SpO2 (blood oxygenation) routes include daily SpO2 average. Data will only be available for users
with a Gen 3 Oura Ring
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Spo2 Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-spo2-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-daily-stress-routes-api
name: Oura Ring Daily Stress Routes API
description: The daily stress route includes a summary of the number of minutes the user spends in high stress and high
recovery each day. This is a great way to see how your stress and recovery are trending over time. Stress and recovery
are mutally exclusive. E.g. one can only be stressed or recovered at any given moement - and cannot be stressed and recovered
at the same time.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Daily Stress Routes
properties:
- type: OpenAPI
url: openapi/oura-daily-stress-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-enhanced-tag-routes-api
name: Oura Ring Enhanced Tag Routes API
description: 'The Enhanced Tags data scope includes tags that Oura users enter within the Oura mobile app. Enhanced Tags
can be added for any lifestyle choice, habit, mood change, or environmental factor an Oura user wants to monitor the effects
of. Enhanced Tags also contain context on a tag''s start and end time, whether a tag repeats daily, and comments.
[Learn more about how Oura users add Enhanced Tags](https://support.ouraring.com/hc/en-us/articles/360038676993-How-to-Use-Tags)'
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Enhanced Tag Routes
properties:
- type: OpenAPI
url: openapi/oura-enhanced-tag-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-heart-rate-routes-api
name: Oura Ring Heart Rate Routes API
description: The Heart Rate data scope includes time-series heart rate data throughout the day and night. Heart rate is
provided at 5-minute increments. For heart rate data recorded from a Session, see Sessions endpoint.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Heart Rate Routes
properties:
- type: OpenAPI
url: openapi/oura-heart-rate-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-personal-info-routes-api
name: Oura Ring Personal Info Routes API
description: The Personal Info scope includes personal information (e.g. age, email, weight, and height) about the user.
You can access the id on the personal_info route with any access token (no scopes are required).
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Personal Info Routes
properties:
- type: OpenAPI
url: openapi/oura-personal-info-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-rest-mode-period-routes-api
name: Oura Ring Rest Mode Period Routes API
description: The Rest Mode scope includes information about rest mode periods. This includes the start, end time and detaials
of the rest mode period.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Rest Mode Period Routes
properties:
- type: OpenAPI
url: openapi/oura-rest-mode-period-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-ring-battery-level-routes-api
name: Oura Ring Ring Battery Level Routes API
description: The Ring Battery Level Routes API from Oura Ring — 1 operation(s) for ring battery level routes.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Ring Battery Level Routes
properties:
- type: OpenAPI
url: openapi/oura-ring-battery-level-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-ring-configuration-routes-api
name: Oura Ring Ring Configuration Routes API
description: The Ring Configuration scope includes information about the user's ring(s). This includes the model, size,
color, etc.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Ring Configuration Routes
properties:
- type: OpenAPI
url: openapi/oura-ring-configuration-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-sandbox-routes-api
name: Oura Ring Sandbox Routes API
description: Fake user data that you can access without an Oura account. There is a corresponding sandbox endpoint to each
available data type. This is useful for testing and development purposes. The data is not real and should not be used
for any production purposes. The data is generated by Oura and is not based on any real user data. The data is not updated
in real-time and is not guaranteed to be accurate. The rate limit for the sandbox endpoints is shared with your rate limit
on other data endpoints.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Sandbox Routes
properties:
- type: OpenAPI
url: openapi/oura-sandbox-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-session-routes-api
name: Oura Ring Session Routes API
description: The Sessions data scope provides information on how users engage with guided and unguided sessions in the Oura
app, including the user's biometric trends during the sessions.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Session Routes
properties:
- type: OpenAPI
url: openapi/oura-session-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-sleep-routes-api
name: Oura Ring Sleep Routes API
description: Returns Oura Sleep data for the specified Oura user within a given timeframe. A user can have multiple sleep
periods per day.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Sleep Routes
properties:
- type: OpenAPI
url: openapi/oura-sleep-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-sleep-time-routes-api
name: Oura Ring Sleep Time Routes API
description: Recommendations for the optimal bedtime window that is calculated based on sleep data.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Sleep Time Routes
properties:
- type: OpenAPI
url: openapi/oura-sleep-time-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-tag-routes-api
name: Oura Ring Tag Routes API
description: '<span className=''text-important''>**Note:** Tag is deprecated. We recommend transitioning to [Enhanced Tag](#tag/Enhanced-Tag-Routes).</span>
~~The Tags data scope includes tags that Oura users enter within the Oura mobile app. Tags are a growing list of activities,
environment factors, symptoms, emotions, and other aspects that provide broader context into what''s happening with users
beyond the objective data generated by the Oura Ring.~~
~~[More information on tag translations](https://cloud.ouraring.com/edu/tag-translations)~~'
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Tag Routes
properties:
- type: OpenAPI
url: openapi/oura-tag-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-vo2-max-routes-api
name: Oura Ring VO2 Max Routes API
description: VO2 Max is a measure of the maximum volume of oxygen that an individual can use during intense exercise. See
more details [here](https://support.ouraring.com/hc/en-us/articles/28336620578835-Cardio-Capacity-VO2-Max).
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- VO2 Max Routes
properties:
- type: OpenAPI
url: openapi/oura-vo2-max-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-webhook-subscription-routes-api
name: Oura Ring Webhook Subscription Routes API
description: "# Webhooks for Real-Time Data Updates\n\n## What are Webhooks?\nWebhooks are a way for the Oura API to notify\
\ your application when new data is available, instead of requiring your application to constantly check for updates (polling).\
\ Think of webhooks as \"reverse APIs\" - instead of your application requesting data, Oura's servers send data to your\
\ application when something changes.\n\n## Why Use Webhooks (Important!)\n- **RECOMMENDED APPROACH**: Webhooks are the\
\ preferred way to consume Oura data\n- **Avoid Rate Limits**: We have not had customers hit rate limits with webhooks\
\ properly implemented\n- **Near Real-Time Updates**: Webhook notifications come approximately 30 seconds after data syncs\
\ from the mobile app\n- **Efficient Resource Usage**: Reduces unnecessary API calls and server load\n- **Better User\
\ Experience**: Your application stays updated without constant polling\n\n## How Webhooks Work with Oura\n1. **You set\
\ up an endpoint**: Create a URL on your server that can receive POST requests\n2. **You subscribe to events**: Tell Oura\
\ what data types and events you want to be notified about\n3. **Oura verifies your endpoint**: A one-time check to ensure\
\ your endpoint is valid\n4. **Oura sends notifications**: When data changes, Oura sends a POST request to your endpoint\n\
5. **You process the event**: Your endpoint receives basic event details\n6. **You fetch complete data**: Use the provided\
\ IDs to retrieve the full data via the API\n\n## Recommended Implementation Pattern\n1. **Initial Data Load**: When a\
\ user first connects, make a single API request for historical data\n2. **Subscribe to Webhooks**: Set up webhook subscriptions\
\ for all data types you need\n3. **Process Webhook Events**: As users sync their rings, you'll receive notifications\
\ about new data\n4. **Fetch Updated Data**: Use the object_id from webhook events to fetch the specific updated data\n\
\nThis pattern minimizes API calls while ensuring your application always has the latest data.\n\n## Setup Guide\n\n###\
\ Step 1: Create Your Webhook Endpoint\nSet up an HTTP endpoint on your server that can:\n- Handle both GET requests (for\
\ verification) and POST requests (for events)\n- Respond to verification challenges during subscription setup\n- Process\
\ incoming webhook events quickly (under 10 seconds)\n\nExample endpoint implementation (Node.js):\n```javascript\n//\
\ Express.js route handlers for your webhook endpoint\napp.get('/oura-webhook', (req, res) => {\n // Verification handler\
\ - required during subscription setup\n const { verification_token, challenge } = req.query;\n\n // Verify the token\
\ matches your expected token\n if (verification_token === YOUR_VERIFICATION_TOKEN) {\n // Return the challenge in\
\ the required format\n return res.json({ challenge });\n }\n\n // If verification fails\n return res.status(401).send('Invalid\
\ verification token');\n});\n\napp.post('/oura-webhook', (req, res) => {\n // Event handler - processes incoming webhook\
\ events\n\n // Always respond quickly (under 10 seconds)\n // Process the event asynchronously if needed\n res.status(200).send('OK');\n\
\n // Then process the event data\n const { event_type, data_type, object_id, user_id } = req.body;\n processEventAsync(event_type,\
\ data_type, object_id, user_id);\n});\n```\n\n### Step 2: Create a Webhook Subscription\nCall the `POST /v2/webhook/subscription`\
\ endpoint to register your webhook:\n\n```\nPOST /v2/webhook/subscription\nHeaders:\n x-client-id: YOUR_CLIENT_ID\n\
\ x-client-secret: YOUR_CLIENT_SECRET\n Content-Type: application/json\n\nBody:\n{\n \"callback_url\": \"https://your-server.com/oura-webhook\"\
,\n \"verification_token\": \"your-secret-verification-token\",\n \"event_type\": \"update\",\n \"data_type\": \"sleep\"\
\n}\n```\n\nYou need to create separate subscriptions for each combination of:\n- **event_type**: The type of event (create,\
\ update, delete)\n- **data_type**: The type of data you're interested in (sleep, activity, etc.)\n\n### Step 3: Verification\
\ Process\nWhen you create a subscription, Oura verifies your endpoint:\n\n1. Oura sends a GET request to your callback\
\ URL with query parameters:\n ```\n GET https://your-server.com/oura-webhook?verification_token=your-token&challenge=random-string\n\
\ ```\n\n2. Your endpoint must verify the token and respond with the challenge:\n ```json\n {\n \"challenge\"\
: \"random-string\"\n }\n ```\n\n3. If verification succeeds, your subscription is activated\n\n\n\
\n### Step 4: Receiving and Processing Events\nWhen an event occurs (e.g., user syncs new sleep data):\n\n1. Oura sends\
\ a POST request to your callback URL:\n ```\n POST https://your-server.com/oura-webhook\n Headers:\n x-oura-signature:\
\ HMAC_SIGNATURE\n x-oura-timestamp: 1234567890\n\n Body:\n {\n \"event_type\": \"update\",\n \"data_type\"\
: \"sleep\",\n \"object_id\": \"12345abc\",\n \"event_time\": \"2023-01-01T08:00:00+00:00\",\n \"user_id\"\
: \"user123\"\n }\n ```\n\n2. Your endpoint should:\n - Verify the signature for security (see below)\n - Respond\
\ quickly (under 10 seconds) with a 2xx status\n - Process the event asynchronously if needed\n - Use the object_id\
\ to fetch the complete data via the API\n\n## Security Best Practices\n\n### Verify Webhook Signatures\nAlways verify\
\ that webhook requests are actually from Oura by checking the HMAC signature:\n\n```javascript\nconst crypto = require('crypto');\n\
\nfunction verifySignature(headers, body, clientSecret) {\n const signature = headers['x-oura-signature'];\n const timestamp\
\ = headers['x-oura-timestamp'];\n\n // Create HMAC using your client secret\n const hmac = crypto.createHmac('sha256',\
\ clientSecret);\n hmac.update(timestamp + JSON.stringify(body));\n const calculatedSignature = hmac.digest('hex').toUpperCase();\n\
\n // Compare calculated signature with received signature\n return calculatedSignature === signature;\n}\n\n// In your\
\ webhook handler\napp.post('/oura-webhook', (req, res) => {\n // Verify signature\n if (!verifySignature(req.headers,\
\ req.body, CLIENT_SECRET)) {\n return res.status(401).send('Invalid signature');\n }\n\n // Process valid webhook\n\
\ res.status(200).send('OK');\n // ...\n});\n```\n\n### Use HTTPS\nAlways use HTTPS for your webhook endpoint to ensure\
\ data is encrypted in transit.\n\n### Keep Your Verification Token Secret\nChoose a strong, random verification token\
\ and don't share it.\n\n## Handling Webhook Failures\n\n### Retry Mechanism\nOura will retry failed webhook deliveries:\n\
- For 4xx responses: 10 retries\n- For 5xx responses: 10 retries\n- For timeouts: 10 retries\n\n### Canceling Subscriptions\n\
If you want to cancel a subscription, you can:\n- Use the DELETE endpoint: `DELETE /v2/webhook/subscription/{id}`\n- Or\
\ respond with a 410 status code to automatically cancel\n\n## Common Questions\n\n### How quickly will I receive webhooks?\n\
Webhook notifications arrive approximately 30 seconds after data syncs from the mobile app. The timing depends on the\
\ data type:\n- **Sleep, Readiness, and other user-initiated sync data**: These only sync when the user opens the Oura\
\ app and actively syncs their ring\n- **Daily Activity, Daily Stress, and other background data**: These may update periodically\
\ in the background without user action\n\n### What if my server goes down?\nOura will retry webhook deliveries for about\
\ an hour if your server doesn't respond properly. However, if your server is down for an extended period, you might miss\
\ some events. It's a good practice to implement a reconciliation process that can fetch data for periods when your webhook\
\ might have been unavailable.\n\n### How can I test webhooks locally?\nUse a tool like [ngrok](https://ngrok.com/) to\
\ expose your local development server to the internet with a public URL.\n\n### Can I use the same callback URL for different\
\ subscriptions?\nYes, you can use the same URL for multiple subscriptions. Your handler can differentiate between events\
\ using the `event_type` and `data_type` fields in the webhook payload.\n\n### Will I hit rate limits using webhooks?\n\
We have not had customers hit rate limits with webhooks properly implemented. The recommended pattern is:\n1. Make a single\
\ request for historical data when a user first connects\n2. Use webhooks for all ongoing data updates\n3. Only fetch\
\ the specific data that has changed based on webhook notifications\n\nThis approach minimizes API calls while ensuring\
\ your application always has the latest data."
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Webhook Subscription Routes
properties:
- type: OpenAPI
url: openapi/oura-webhook-subscription-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
- aid: oura:oura-workout-routes-api
name: Oura Ring Workout Routes API
description: The Workout data scope includes information about user workouts. This is a diverse, growing list of workouts
that help inform how the user is training and exercising.
humanURL: https://cloud.ouraring.com/docs/
baseURL: https://api.ouraring.com/v2
tags:
- Workout Routes
properties:
- type: OpenAPI
url: openapi/oura-workout-routes-api-openapi.yml
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: Authentication
url: https://cloud.ouraring.com/docs/authentication
- type: Webhooks
url: https://cloud.ouraring.com/docs/webhooks
- type: JSONSchema
url: json-schema/
- type: Examples
url: examples/
- type: Vocabulary
url: vocabulary/oura-vocabulary.yml
- type: JSONLDContext
url: json-ld/oura-context.jsonld
- type: GraphQL
url: graphql/oura-graphql.md
common:
- type: AgenticAccess
url: agentic-access/oura-agentic-access.yml
- type: TrustCenter
url: security/oura-trust-center.yml
- type: VulnerabilityDisclosure
url: security/oura-vulnerability-disclosure.yml
- type: DomainSecurity
url: security/oura-domain-security.yml
- type: Authentication
url: authentication/oura-authentication.yml
- type: OAuthScopes
url: scopes/oura-scopes.yml
- type: Website
url: https://ouraring.com
- type: Developer
url: https://ouraring.com/developer
- type: Documentation
url: https://cloud.ouraring.com/docs/
- type: GitHubOrg
url: https://github.com/oura-health
- type: LinkedIn
url: https://www.linkedin.com/company/oura
- type: Blog
url: https://ouraring.com/blog
- type: Pricing
url: https://ouraring.com/product
- type: StatusPage
url: https://status.ouraring.com
- type: X
url: https://twitter.com/ouraring
- type: Plans
url: plans/oura-plans-pricing.yml
- type: RateLimits
url: rate-limits/oura-rate-limits.yml
- type: FinOps
url: finops/oura-finops.yml
- type: BlogFeed
url: blogs/blogs.json
maintainers:
- FN: Kin Lane
email: kin@apievangelist.com