Sleep

Read normalized sleep sessions, stages, duration, and efficiency.

5 min read Updated Sep 16, 2026
GET /v1/users/{id}/sleep

Returns sleep sessions newest first with an opaque cursor.

Query parameterDefaultRules
from_date29 days before to_dateInclusive YYYY-MM-DD
to_datecurrent date in the user’s timezoneInclusive YYYY-MM-DD
limit50Integer from 1 to 100
cursorOpaque next_cursor from the prior page

The maximum inclusive range is 366 days. The range selects by date, the calendar day a session counts toward. A night beginning on the 2nd and ending on the morning of the 3rd belongs to the 3rd.

date, start_time, and end_time use the timezone saved on the user’s profile. Session clock values do not include an offset and must not be interpreted as UTC. If the profile has no timezone, Sonar uses UTC.

http
GET /v1/users/7e4e91a5-1e4f-4fc2-903c-251046d2a4d3/sleep?from_date=2026-09-01&to_date=2026-09-03&limit=50
json
{
  "from_date": "2026-09-01",
  "to_date": "2026-09-03",
  "data": [
    {
      "id": "sleep-3-1788478440000",
      "date": "2026-09-03",
      "start_time": "2026-09-02T23:34:00",
      "end_time": "2026-09-03T07:12:00",
      "duration_minutes": 458,
      "is_main_sleep": true,
      "source": "garmin",
      "asleep_minutes": 412,
      "deep_minutes": 88,
      "light_minutes": 231,
      "rem_minutes": 93,
      "awake_minutes": 31,
      "in_bed_minutes": 458,
      "efficiency_pct": 89.9
    }
  ],
  "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.

is_main_sleep identifies the principal sleep session for the night; naps and short fragments are false. Stage or in-bed values the provider did not report are null. efficiency_pct is asleep time divided by in-bed time.

Sleep sessions do not include a stage-by-stage hypnogram. For daily sleep totals and sleep-period vital averages, use GET /daily.