Your app can read and write granular sleep data.
This includes light sleep, deep sleep, REM, and awake sleep stages from the
[`SleepStages`](https://developers.google.com/android/reference/com/google/android/gms/fitness/data/SleepStages)
enumerated type. To write sleep data you must create a session of type
[`FitnessActivities.SLEEP`](https://developers.google.com/android/reference/com/google/android/gms/fitness/FitnessActivities#SLEEP).
Sleep data must be encapsulated in a session if it is to appear in the user's
Journal in the
[Google Fit App](https://play.google.com/store/apps/details?id=com.google.android.apps.fitness).

Optionally, insert segments of type `SleepStages` within the session:

- [`SleepStages.SLEEP_LIGHT`](https://developers.google.com/android/reference/com/google/android/gms/fitness/SleepStages#SLEEP_LIGHT)
- [`SleepStages.SLEEP_DEEP`](https://developers.google.com/android/reference/com/google/android/gms/fitness/SleepStages#SLEEP_DEEP)
- [`SleepStages.SLEEP_REM`](https://developers.google.com/android/reference/com/google/android/gms/fitness/SleepStages#SLEEP_REM)
- [`SleepStages.AWAKE`](https://developers.google.com/android/reference/com/google/android/gms/fitness/SleepStages#AWAKE)
- [`SleepStages.OUT_OF_BED`](https://developers.google.com/android/reference/com/google/android/gms/fitness/SleepStages#OUT_OF_BED)

## No-granularity example

To write a night of sleep with no stage granularity, follow the example below.
Create a session with start and end time, and the `activity` SLEEP.

### Android

```kotlin
val fitnessOptions = FitnessOptions.builder()
    .accessSleepSessions(FitnessOptions.ACCESS_WRITE)
    .build()

// Create the sleep session
val session= Session.Builder()
    .setName(sessionName)
    .setIdentifier(identifier)
    .setDescription(description)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .setEndTime(endTime, TimeUnit.MILLISECONDS)
    .setActivity(FitnessActivities.SLEEP)
    .build()

// Build the request to insert the session.
val request = SessionInsertRequest.Builder()
    .setSession(session)
    .build()

// Insert the session into Fit platform
Log.i(TAG, "Inserting the session with the SessionsClient")
Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .insertSession(request)
    .addOnSuccessListener {
        Log.i(TAG,"Session insert was successful!")
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was a problem inserting the session", e)
    }
```

Read more details about
[sessions in Android](https://developers.google.com/android/reference/com/google/android/gms/fitness/data/Session).

### REST

**HTTP method**

    PUT

**Request URL**

    https://www.googleapis.com/fitness/v1/users/me/sessions/identifier

**Request body**

    {
        "id": identifier,
        "name": sessionName,
        "description": description,
        "startTimeMillis": startTime,
        "endTimeMillis": endTime,
        "version": 1,
        "lastModifiedToken": "exampleToken",
        "application": {
            "detailsUrl": "http://example.com",
            "name": "Foo Example App",
            "version": "1.0"
        },
        "activityType": 72 // Sleep
    }

## Sleep stages granularity example

To write sleep with stages granularity, write **both** the top-level sleep
session and segments for the different stages of sleep.

### Write sleep segments

In this example we will write several segments to represent the several sleep
stages over one night of sleep.

### Android

```kotlin
val dataSource = DataSource.Builder()
    .setType(DataSource.TYPE_RAW)
    .setDataType(DataType.TYPE_SLEEP_SEGMENT)
    .setAppPackageName(context)
    // Optional but recommended for identifying the stream if you have multiple streams with the same dataType.
    .setStreamName(streamName)
    .build()

val dataPoints = listOf(
    DataPoint.builder(dataSource)
        .setTimeInterval(startTime1, endTime1, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.SLEEP_LIGHT)
        .build(),
    DataPoint.builder(dataSource)
        .setTimeInterval(startTime2, endTime2, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.SLEEP_DEEP)
        .build(),
    DataPoint.builder(dataSource)
        .setTimeInterval(startTime3, endTime3, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.SLEEP_LIGHT)
        .build(),
    DataPoint.builder(dataSource)
        .setTimeInterval(startTime4, endTime4, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.SLEEP_REM)
        .build(),
    DataPoint.builder(dataSource)
        .setTimeInterval(startTime5, endTime5, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.AWAKE)
        .build(),
    DataPoint.builder(dataSource)
        .setTimeInterval(startTime6, endTime6, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.SLEEP_LIGHT)
        .build()
)

val dataSet = DataSet.builder(dataSource)
    .addAll(dataPoints)
    .build()
```

### REST

1. First create the `dataSource`:

   **HTTP method**

       POST

   **Request URL**

       https://www.googleapis.com/fitness/v1/users/me/dataSources

   **Request body**

       {
         "dataStreamName": streamName,
         "type": "raw",
         "application": {
           "detailsUrl": "http://example.com",
           "name": "Foo Example App",
           "version": "1"
         },
         "dataType": {
           "name": "com.google.sleep.segment"
         }
       }

2. Then populate the `dataSet`:

   **HTTP method**

       PATCH

   **Request URL**

       https://www.googleapis.com/fitness/v1/users/userId/dataSources/dataSourceId/datasets/datasetId

   **Request body**

       {
           "dataSourceId": dataSourceId,
           "point": [
               {
                   "dataTypeName": "com.google.sleep.segment",
                   "startTimeNanos": startTime1,
                   "endTimeNanos": endTime1,
                   "value": [
                       {
                           intVal: 4 // Light sleep
                       }
                   ]
               },
               {
                   "dataTypeName": "com.google.sleep.segment",
                   "startTimeNanos": startTime2,
                   "endTimeNanos": endTime2,
                   "value": [
                       {
                           intVal: 5 // Deep sleep
                       }
                   ]
               },
               {
                   "dataTypeName": "com.google.sleep.segment",
                   "startTimeNanos": startTime3,
                   "endTimeNanos": endTime3,
                   "value": [
                       {
                           intVal: 4 // Light sleep
                       }
                   ]
               },
               {
                   "dataTypeName": "com.google.sleep.segment",
                   "startTimeNanos": startTime4,
                   "endTimeNanos": endTime4,
                   "value": [
                       {
                           intVal: 6 // REM sleep
                       }
                   ]
               },
               {
                   "dataTypeName": "com.google.sleep.segment",
                   "startTimeNanos": startTime5,
                   "endTimeNanos": endTime5,
                   "value": [
                       {
                           intVal: 1 // Awake
                       }
                   ]
               },
               {
                   "dataTypeName": "com.google.sleep.segment",
                   "startTimeNanos": startTime6,
                   "endTimeNanos": endTime6,
                   "value": [
                       {
                           intVal: 4 // Light sleep
                       }
                   ]
               }
            ]
        }

### Write sleep session

Finally, group the segments above by inserting a sleep session. Set the start
time for this session to the start time of the first segment, and the end time
to the end time of the last segment.

### Android

```kotlin
val fitnessOptions = FitnessOptions.builder()
    .accessSleepSessions(FitnessOptions.ACCESS_WRITE)
    .addDataType(DataType.TYPE_SLEEP_SEGMENT, FitnessOptions.ACCESS_WRITE)
    .build()

val session = Session.Builder()
    .setName(sessionName)
    .setIdentifier(identifier)
    .setDescription(description)
    .setStartTime(startTime1, TimeUnit.MILLISECONDS) // From first segment
    .setEndTime(endTime6, TimeUnit.MILLISECONDS) // From last segment
    .setActivity(FitnessActivities.SLEEP)
    .build()

// Build the request to insert the session.
val request = SessionInsertRequest.Builder()
    .setSession(session)
    .addDataSet(dataset)
    .build()

// Insert the session into Fit platform
Log.i(TAG, "Inserting the session in the Sessions API")
Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .insertSession(request)
    .addOnSuccessListener {
        Log.i(TAG,"Session insert was successful!")
    }
    .addOnFailureListener { e ->
        Log.i(TAG, "There was a problem inserting the session", e)
    }
```

### REST

**HTTP method**

    PUT

**Request URL**

    https://www.googleapis.com/fitness/v1/users/me/sessions/identifier

**Request body**

    {
        "id": identifier,
        "name": sessionName,
        "description": description,
        "startTimeMillis": startTime1,
        "endTimeMillis": endTime6,
        "version": 1,
        "lastModifiedToken": "exampleToken",
        "application": {
            "detailsUrl": "http://example.com",
            "name": "Foo Example App",
            "version": "1.0"
        },
        "activityType": 72 // Sleep
    }