Workouts
List normalized activity sessions and retrieve detailed workout metrics and heart-rate data.
List Workouts
/v1/users/{id}/workoutsReturns workout sessions newest first with an opaque cursor.
| Query parameter | Default | Rules |
|---|---|---|
from_date | 29 days before to_date | Inclusive YYYY-MM-DD |
to_date | current date in the user’s timezone | Inclusive YYYY-MM-DD |
limit | 50 | Integer from 1 to 100 |
cursor | — | Opaque next_cursor from the prior page |
The maximum inclusive range is 366 days.
The date range and every start_time or heart-rate sample timestamp use the timezone saved on the user’s profile. Clock values have no offset suffix; do not interpret them as UTC. If the profile has no timezone, Sonar uses UTC.
{
"from_date": "2026-09-01",
"to_date": "2026-09-03",
"data": [
{
"id": "b203a7ff-9ace-5825-9414-f5c81dcc1a93",
"type": "running",
"start_time": "2026-09-03T07:35:00",
"duration_minutes": 52,
"calories": 612,
"distance_km": 10.2,
"source": "garmin",
"avg_heart_rate": 151,
"max_heart_rate": 174,
"strain": 63
}
],
"next_cursor": null
}Copy a non-null next_cursor unchanged into the next request’s cursor. Keep from_date, to_date, and limit unchanged between pages. Measurements not supplied by the source are null.
Retrieve a Workout
/v1/users/{id}/workouts/{workout_id}Returns the session summary plus detail metrics and heart-rate data.
{
"id": "b203a7ff-9ace-5825-9414-f5c81dcc1a93",
"type": "running",
"start_time": "2026-09-03T07:35:00",
"duration_minutes": 52,
"calories": 612,
"distance_km": 10.2,
"source": "garmin",
"avg_heart_rate": 151,
"max_heart_rate": 174,
"strain": 63,
"name": "Morning run",
"metrics": {
"elevation_meters": 104,
"steps": 8921,
"avg_speed_kmh": 11.8,
"avg_pace_seconds_per_km": 306,
"avg_mets": null,
"weather_temperature_c": 18,
"weather_humidity_pct": 71,
"swimming_stroke_count": null,
"swimming_lap_length_m": null
},
"heart_rate": {
"avg_bpm": 151,
"max_bpm": 174,
"zones": [],
"samples": [
{ "timestamp": "2026-09-03T07:35:00", "bpm": 112 },
{ "timestamp": "2026-09-03T07:35:15", "bpm": 118 }
]
}
}heart_rate.samples is the workout trace averaged into 15, 30, or 60 second buckets depending on workout length. heart_rate is null when the provider supplied no trace. A missing workout, or one belonging to another user, returns 404 workout_not_found.
Sonar