Sleep is represented by [sessions](https://developers.google.com/fit/rest/v1/using-sessions)
of type [`sleep`](https://developers.google.com/fit/rest/v1/reference/activity-types).
Sessions can optionally contain sleep stages, which have more granular details
about sleep data. For example, if it was light, deep or REM
sleep:

##### Sleep stage values

| Sleep stage type | Value |
|---|---|
| Awake (during sleep cycle) | 1 |
| Sleep | 2 |
| Out-of-bed | 3 |
| Light sleep | 4 |
| Deep sleep | 5 |
| REM | 6 |

The [write sleep data](https://developers.google.com/fit/scenarios/write-sleep-data) guide shows how both
granular and non-granular sleep data is represented in Fit.

### Android

The follow samples uses a [SessionClient](https://developers.google.com/android/reference/com/google/android/gms/fitness/SessionsClient.html)
to retrieve data from Fit, for both cases.

```kotlin
val SLEEP_STAGE_NAMES = arrayOf(
    "Unused",
    "Awake (during sleep)",
    "Sleep",
    "Out-of-bed",
    "Light sleep",
    "Deep sleep",
    "REM sleep"
)

val request = SessionReadRequest.Builder()
    .readSessionsFromAllApps()
    // By default, only activity sessions are included, so it is necessary to explicitly
    // request sleep sessions. This will cause activity sessions to be *excluded*.
    .includeSleepSessions()
    // Sleep segment data is required for details of the fine-granularity sleep, if it is present.
    .read(DataType.TYPE_SLEEP_SEGMENT)
    .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
    .build()

sessionsClient.readSession(request)
    .addOnSuccessListener { response ->
        for (session in response.sessions) {
            val sessionStart = session.getStartTime(TimeUnit.MILLISECONDS)
            val sessionEnd = session.getEndTime(TimeUnit.MILLISECONDS)
            Log.i(TAG, "Sleep between $sessionStart and $sessionEnd")

            // If the sleep session has finer granularity sub-components, extract them:
            val dataSets = response.getDataSet(session)
            for (dataSet in dataSets) {
                for (point in dataSet.dataPoints) {
                    val sleepStageVal = point.getValue(Field.FIELD_SLEEP_SEGMENT_TYPE).asInt()
                    val sleepStage = SLEEP_STAGE_NAMES[sleepStageVal]
                    val segmentStart = point.getStartTime(TimeUnit.MILLISECONDS)
                    val segmentEnd = point.getEndTime(TimeUnit.MILLISECONDS)
                    Log.i(TAG, "\t* Type $sleepStage between $segmentStart and $segmentEnd")
                }
            }
        }
    }
```

### REST

Retrieving sleep sessions using the REST API is a two stage process:

1. [Retrieve a list of sessions](https://developers.google.com/fit/rest/v1/using-sessions#list_existing_sessions)
   setting the [`activityType`](https://developers.google.com/fit/rest/v1/reference/activity-types) parameter to `72` (`SLEEP`).
   Note: You can use a `startTime` and `endTime`, or use a [pageToken](https://developers.google.com/fit/rest/v1/reference/users/sessions/list#parameters)
   to retrieve new sessions since the previous request.

   **HTTP method**

       GET

   **Request URL**

       https://www.googleapis.com/fitness/v1/users/me/sessions?startTime=2019-12-05T00:00.000Z&endTime=2019-12-17T23:59:59.999Z&activityType=72

   **Response**

   An example [Session](https://developers.google.com/fit/rest/v1/reference/users/sessions/list#response_1)
   response might be:

       {
        "session": [
           {
            "id": "Sleep1575505620000",
            "name": "Sleep",
            "description": "",
            "startTimeMillis": "1575505620000",
            "endTimeMillis": "1575526800000",
            "modifiedTimeMillis": "1575590432413",
            "application": {
             "packageName": "com.example.sleep_tracker"
            },
            "activityType": 72  // Sleep
           },
           {
            "id": "Run2939075083",
            "name": "Mud",
            "description": "",
            "startTimeMillis": "1576594403000",
            "endTimeMillis": "1576598754000",
            "modifiedTimeMillis": "1576616010143",
            "application": {
             "packageName": "com.example.run_tracker"
            },
            "activityType": 8  // Running
           }
         ],
        "deletedSession": [],
        "nextPageToken": "1576598754001"
       }

2. To obtain details of sleep stages for each session (if present), use the
   following request for each session in the filtered list:

   **HTTP method**

       POST

   **Request URL**

       https://www.googleapis.com/fitness/v1/users/userId/dataset:aggregate

   **Request body**

       {
         "aggregateBy": [
           {
             "dataTypeName": "com.google.sleep.segment"
           }
         ],
         "endTimeMillis": 1575609060000,
         "startTimeMillis": 1575591360000
       }

   **Response**

   If your request was successful, you'll get a `200 OK` HTTP response status
   code. The response body contains a JSON representation of activity
   segments that comprise the sleep session. Each `intVal` represents the
   sleep [activity type](https://developers.google.com/fit/scenarios/read-sleep-data#sleep_activity_values)

       {
        "bucket": [
         {
          "startTimeMillis": "1575591360000",
          "endTimeMillis": "1575609060000",
          "dataset": [
           {
            "point": [
             {
              "startTimeNanos": "1575591360000000000",
              "endTimeNanos": "1575595020000000000",
              "dataTypeName": "com.google.sleep.segment",
              "originDataSourceId": "...",
              "value": [
               {
                "intVal": 4, // Light sleep
                "mapVal": []
               }
              ]
             },
             {
              "startTimeNanos": "1575595020000000000",
              "endTimeNanos": "1575596220000000000",
              "dataTypeName": "com.google.sleep.segment",
              "originDataSourceId": "...",
              "value": [
               {
                "intVal": 1, // Sleep
                "mapVal": []
               }
              ]
             },

             // .... more datapoints

             {
              "startTimeNanos": "1575605940000000000",
              "endTimeNanos": "1575609060000000000",
              "dataTypeName": "com.google.sleep.segment",
              "originDataSourceId": "...",
              "value": [
               {
                "intVal": 4, // Light sleep
                "mapVal": []
               }
              ]
             }
            ]
           }
          ]
         }
        ]
       }