Once users have connected their wearables, you can access their health data through Open Wearables APIs. Data is organized into three main categories: events (workouts, sleep), summaries (daily aggregates), and time-series records.
Data Categories
Events Discrete activities with start/end times: workouts, sleep sessions
Summaries Daily aggregated metrics: activity, sleep, body, recovery
Records Time-series data: heart rate, steps, calories (coming soon)
Workouts
Retrieve workout sessions (running, cycling, swimming, strength training, etc.):
curl -X GET "https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/events/workouts?start_date=2026-03-01&end_date=2026-03-07&limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"
Query Parameters:
Start date in ISO 8601 format (e.g., 2026-03-01 or 2026-03-01T00:00:00Z)
End date in ISO 8601 format
Filter by workout type (e.g., running, cycling, swimming)
Pagination cursor from previous response
Number of results (1-100)
Response:
{
"data" : [
{
"id" : "evt_123" ,
"user_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"type" : "workout" ,
"subtype" : "running" ,
"start_time" : "2026-03-07T06:30:00Z" ,
"end_time" : "2026-03-07T07:15:00Z" ,
"duration_seconds" : 2700 ,
"distance_meters" : 8047 ,
"calories" : 456 ,
"average_heart_rate" : 152 ,
"max_heart_rate" : 178 ,
"provider" : "garmin" ,
"provider_id" : "21047282990" ,
"metadata" : {
"device_name" : "Forerunner 965" ,
"activity_name" : "Morning Run"
}
}
],
"next_cursor" : "eyJpZCI6ImV2dF8xMjMifQ==" ,
"has_more" : false
}
Workout Fields
Event type (always workout for workouts)
Specific workout type: running, cycling, swimming, strength_training, yoga, walking, etc.
Workout start time (ISO 8601 with timezone)
Workout end time (ISO 8601 with timezone)
Total duration in seconds
Distance covered in meters (null for non-distance activities)
Estimated calories burned
Average heart rate in BPM
Maximum heart rate in BPM
Source provider: garmin, whoop, strava, etc.
Sleep Sessions
Retrieve sleep sessions including naps:
curl -X GET "https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/events/sleep?start_date=2026-03-01&end_date=2026-03-07&limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"data" : [
{
"id" : "evt_456" ,
"user_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"type" : "sleep" ,
"start_time" : "2026-03-06T22:30:00Z" ,
"end_time" : "2026-03-07T06:15:00Z" ,
"duration_seconds" : 27900 ,
"sleep_stages" : {
"deep_sleep_seconds" : 7200 ,
"light_sleep_seconds" : 14400 ,
"rem_sleep_seconds" : 5400 ,
"awake_seconds" : 900
},
"sleep_score" : 85 ,
"provider" : "garmin" ,
"metadata" : {
"is_nap" : false
}
}
],
"next_cursor" : null ,
"has_more" : false
}
Sleep Fields
Breakdown of sleep stages in seconds:
deep_sleep_seconds: Deep/slow-wave sleep
light_sleep_seconds: Light sleep
rem_sleep_seconds: REM sleep
awake_seconds: Time awake during sleep period
Sleep quality score (0-100) from provider if available
Daily Activity Summaries
Get aggregated daily activity metrics (steps, calories, active minutes, heart rate):
curl -X GET "https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/summaries/activity?start_date=2026-03-01&end_date=2026-03-07&limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"
Query Parameters:
Pagination cursor from previous response
Response:
{
"data" : [
{
"user_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"date" : "2026-03-07" ,
"steps" : 12543 ,
"calories_total" : 2345 ,
"calories_active" : 845 ,
"distance_meters" : 9876 ,
"active_minutes" : 87 ,
"floors_climbed" : 12 ,
"heart_rate" : {
"resting" : 58 ,
"average" : 72 ,
"max" : 178 ,
"min" : 52
},
"providers" : [ "garmin" ]
}
],
"next_cursor" : null ,
"has_more" : false
}
Activity summaries aggregate data from all connected providers for each day. The providers array shows which sources contributed data.
Daily Sleep Summaries
Get aggregated daily sleep metrics:
curl -X GET "https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/summaries/sleep?start_date=2026-03-01&end_date=2026-03-07" \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"data" : [
{
"user_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"date" : "2026-03-07" ,
"total_sleep_seconds" : 27000 ,
"deep_sleep_seconds" : 7200 ,
"light_sleep_seconds" : 14400 ,
"rem_sleep_seconds" : 5400 ,
"awake_seconds" : 900 ,
"sleep_efficiency" : 0.93 ,
"sleep_score" : 85 ,
"providers" : [ "garmin" ]
}
],
"next_cursor" : null ,
"has_more" : false
}
Body Metrics
Get comprehensive body metrics with semantic grouping:
curl -X GET "https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/summaries/body?average_period=7&latest_window_hours=4" \
-H "Authorization: Bearer YOUR_API_KEY"
Query Parameters:
Days to average vitals over (1-7)
Hours for latest readings to be considered valid (1-24)
Response:
{
"static" : {
"weight_kg" : 72.5 ,
"height_cm" : 175 ,
"body_fat_percentage" : 18.5 ,
"muscle_mass_kg" : 59.1 ,
"bmi" : 23.7 ,
"age" : 32
},
"averaged" : {
"resting_heart_rate" : 58 ,
"hrv_ms" : 65
},
"latest" : {
"body_temperature_celsius" : 36.8 ,
"blood_pressure_systolic" : 118 ,
"blood_pressure_diastolic" : 75 ,
"measured_at" : "2026-03-07T08:30:00Z"
}
}
Body metrics are organized into three categories:
static : Slow-changing values (most recent reading)
averaged : Vitals averaged over average_period days
latest : Point-in-time readings within latest_window_hours
All list endpoints support cursor-based pagination for efficient data retrieval:
Make initial request
Set limit parameter to control page size (default: 50)
Check for more pages
Look at has_more field in response
Fetch next page
Use next_cursor value as cursor parameter in next request
Repeat until complete
Continue until has_more is false
Example pagination loop:
import requests
url = "https://api.openwearables.com/api/v1/users/ {user_id} /events/workouts"
params = {
"start_date" : "2026-01-01" ,
"end_date" : "2026-03-07" ,
"limit" : 100
}
headers = { "Authorization" : "Bearer YOUR_API_KEY" }
all_workouts = []
while True :
response = requests.get(url, params = params, headers = headers)
data = response.json()
all_workouts.extend(data[ "data" ])
if not data[ "has_more" ]:
break
params[ "cursor" ] = data[ "next_cursor" ]
print ( f "Retrieved { len (all_workouts) } workouts" )
Date Range Guidelines
Larger date ranges require more processing time and may return paginated results. For best performance:
Query 7-30 days at a time for events
Query up to 90 days for daily summaries
Use pagination for large datasets
Data Freshness
Webhook-enabled providers (Garmin, Strava): Data appears within seconds to minutes
Polling-based sync : Data syncs every 4-6 hours by default
Manual sync : Trigger on-demand sync via SDK (coming soon)
Filtering and Querying
Filter workouts by type
curl -X GET "https://api.openwearables.com/api/v1/users/{user_id}/events/workouts?start_date=2026-03-01&end_date=2026-03-07&record_type=running" \
-H "Authorization: Bearer YOUR_API_KEY"
Sort activity summaries
# Descending order (newest first)
curl -X GET "https://api.openwearables.com/api/v1/users/{user_id}/summaries/activity?start_date=2026-03-01&end_date=2026-03-07&sort_order=desc" \
-H "Authorization: Bearer YOUR_API_KEY"
Error Handling
404 Not Found
400 Bad Request
401 Unauthorized
{
"detail" : "User not found"
}
Next Steps
Webhooks Receive real-time data updates via webhooks
API Reference Complete API endpoint documentation