Eight Sleep Temperature API

UNOFFICIAL community app-API endpoints to read and set a user's heating level (GET/PUT /v1/users/{userId}/temperature) on a unit-less -100..100 scale and toggle away mode (PUT /v1/users/{userId}/away-mode). Reverse-engineered, not officially supported.

OpenAPI Specification

eight-sleep-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: Eight Sleep Unofficial Community API
  description: >-
    UNOFFICIAL, community-reverse-engineered specification of the Eight Sleep
    client API that powers the Eight Sleep mobile app. Eight Sleep does NOT
    publish an official public developer API. The endpoints documented here
    were derived from open-source projects - notably pyEight
    (https://github.com/mezz64/pyEight and https://github.com/lukas-clarke/pyEight)
    and the Home Assistant Eight Sleep integration
    (https://github.com/lukas-clarke/eight_sleep). They span three hosts:
    auth-api.8slp.net (OAuth2 token issuance), client-api.8slp.net (user,
    device, and trends reads), and app-api.8slp.net (temperature, away mode,
    base, alarms, and routines control). These endpoints are undocumented,
    unsupported, and may change or break without notice. Use only with your
    own Eight Sleep account and credentials.
  contact:
    name: Eight Sleep
    url: https://www.eightsleep.com
  version: 'unofficial-v1'
servers:
  - url: https://auth-api.8slp.net
    description: Authentication host (OAuth2 token issuance)
  - url: https://client-api.8slp.net
    description: Client API host (user, device, trends reads)
  - url: https://app-api.8slp.net
    description: App API host (temperature, away mode, base, alarms, routines)
tags:
  - name: Authentication
    description: OAuth2 password-grant token issuance (unofficial).
  - name: User
    description: Current and individual user profile reads (unofficial).
  - name: Device
    description: Pod device state and side assignment reads (unofficial).
  - name: Temperature
    description: Heating level and away-mode control (unofficial).
  - name: Trends
    description: Per-night sleep and biometric trend reads (unofficial).
  - name: Base
    description: Adjustable Base position control (unofficial).
  - name: Alarms
    description: Alarm and routine reads and control (unofficial).
paths:
  /v1/tokens:
    post:
      operationId: createToken
      tags:
        - Authentication
      summary: Issue an OAuth2 access token (unofficial)
      description: >-
        UNOFFICIAL OAuth2 password-grant request against auth-api.8slp.net.
        Exchanges an account email and password (plus a client_id and
        client_secret captured from the mobile app) for a bearer access token
        and refresh token. Not an official, supported, or documented endpoint.
      servers:
        - url: https://auth-api.8slp.net
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenRequest'
      responses:
        '200':
          description: Access and refresh tokens issued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '401':
          description: Invalid credentials.
  /v1/users/me:
    get:
      operationId: getCurrentUser
      tags:
        - User
      summary: Get the current user (unofficial)
      description: >-
        UNOFFICIAL read against client-api.8slp.net returning the authenticated
        user's profile, current device id, and bed-side assignment.
      servers:
        - url: https://client-api.8slp.net
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Current user object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}:
    get:
      operationId: getUser
      tags:
        - User
      summary: Get a user by id (unofficial)
      description: >-
        UNOFFICIAL read against client-api.8slp.net returning a single user's
        profile by id (e.g. the left or right sleeper on a Pod).
      servers:
        - url: https://client-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      responses:
        '200':
          description: User object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
        '401':
          description: Missing or expired token.
        '404':
          description: User not found.
  /v1/devices/{deviceId}:
    get:
      operationId: getDevice
      tags:
        - Device
      summary: Get device state (unofficial)
      description: >-
        UNOFFICIAL read against client-api.8slp.net returning Pod device state,
        online status, firmware, and side assignment. Community clients commonly
        request a filtered view via the `filter` query parameter (for example
        `leftUserId,rightUserId,awaySides`).
      servers:
        - url: https://client-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/DeviceId'
        - name: filter
          in: query
          required: false
          description: Comma-separated list of device fields to return.
          schema:
            type: string
            example: leftUserId,rightUserId,awaySides
      responses:
        '200':
          description: Device object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceResponse'
        '401':
          description: Missing or expired token.
        '404':
          description: Device not found.
  /v1/users/{userId}/temperature:
    get:
      operationId: getTemperature
      tags:
        - Temperature
      summary: Get current heating level (unofficial)
      description: >-
        UNOFFICIAL read against app-api.8slp.net returning the user's current
        heating/cooling level. The level is unit-less on a -100..100 scale where
        negative cools and positive warms.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      responses:
        '200':
          description: Current temperature state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemperatureState'
        '401':
          description: Missing or expired token.
    put:
      operationId: setTemperature
      tags:
        - Temperature
      summary: Set heating level (unofficial)
      description: >-
        UNOFFICIAL write against app-api.8slp.net that sets the user's
        heating/cooling level and on/off state. Level is unit-less on a
        -100..100 scale.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemperatureUpdate'
      responses:
        '200':
          description: Updated temperature state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemperatureState'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/away-mode:
    put:
      operationId: setAwayMode
      tags:
        - Temperature
      summary: Set away mode (unofficial)
      description: >-
        UNOFFICIAL write against app-api.8slp.net that starts or ends away mode
        for a user's side of the Pod.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AwayModeUpdate'
      responses:
        '200':
          description: Updated away-mode state.
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/trends:
    get:
      operationId: getTrends
      tags:
        - Trends
      summary: Get sleep trends (unofficial)
      description: >-
        UNOFFICIAL read against client-api.8slp.net returning per-night sleep
        trend data - sleep score, sleep-stage breakdown, heart rate, HRV,
        respiratory rate, and toss-and-turn metrics - over a date range.
      servers:
        - url: https://client-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
        - name: tz
          in: query
          required: false
          description: IANA timezone used to bucket nights (e.g. America/New_York).
          schema:
            type: string
        - name: from
          in: query
          required: false
          description: Start date (YYYY-MM-DD).
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: false
          description: End date (YYYY-MM-DD).
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Trends payload.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrendsResponse'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/base:
    get:
      operationId: getBase
      tags:
        - Base
      summary: Get adjustable Base state (unofficial)
      description: >-
        UNOFFICIAL read against app-api.8slp.net returning the current head and
        feet angles and preset of the adjustable Base.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      responses:
        '200':
          description: Base state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaseState'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/base/angle:
    post:
      operationId: setBaseAngle
      tags:
        - Base
      summary: Set adjustable Base angles or preset (unofficial)
      description: >-
        UNOFFICIAL write against app-api.8slp.net that sets the head and feet
        angles of the adjustable Base, or applies a named preset such as flat,
        relax, sleep, or reading.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BaseAngleUpdate'
      responses:
        '200':
          description: Updated Base state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaseState'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/alarms:
    get:
      operationId: getAlarms
      tags:
        - Alarms
      summary: List alarms (unofficial)
      description: >-
        UNOFFICIAL read against app-api.8slp.net returning the user's configured
        thermal/vibration wake-up alarms.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      responses:
        '200':
          description: Alarm list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AlarmsResponse'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/alarms/{alarmId}:
    put:
      operationId: updateAlarm
      tags:
        - Alarms
      summary: Update an alarm (unofficial)
      description: >-
        UNOFFICIAL write against app-api.8slp.net that enables, disables, or
        modifies a single alarm.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
        - name: alarmId
          in: path
          required: true
          description: Alarm identifier.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Alarm'
      responses:
        '200':
          description: Updated alarm.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Alarm'
        '401':
          description: Missing or expired token.
  /v1/users/{userId}/routines:
    get:
      operationId: getRoutines
      tags:
        - Alarms
      summary: Get routines (unofficial)
      description: >-
        UNOFFICIAL read against app-api.8slp.net returning the user's routines,
        which contain alarm and bedtime/wake configuration in newer app builds.
      servers:
        - url: https://app-api.8slp.net
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/UserId'
      responses:
        '200':
          description: Routines payload.
        '401':
          description: Missing or expired token.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Bearer access token issued by POST /v1/tokens on auth-api.8slp.net.
        Unofficial.
  parameters:
    UserId:
      name: userId
      in: path
      required: true
      description: Eight Sleep user identifier.
      schema:
        type: string
    DeviceId:
      name: deviceId
      in: path
      required: true
      description: Eight Sleep Pod device identifier.
      schema:
        type: string
  schemas:
    TokenRequest:
      type: object
      required:
        - client_id
        - client_secret
        - grant_type
        - username
        - password
      properties:
        client_id:
          type: string
          description: App client id captured from the Eight Sleep mobile app.
        client_secret:
          type: string
          description: App client secret captured from the Eight Sleep mobile app.
        grant_type:
          type: string
          example: password
        username:
          type: string
          description: Account email address.
        password:
          type: string
          format: password
    TokenResponse:
      type: object
      properties:
        access_token:
          type: string
        refresh_token:
          type: string
        token_type:
          type: string
          example: Bearer
        expires_in:
          type: integer
          description: Token lifetime in seconds.
        userId:
          type: string
    UserResponse:
      type: object
      properties:
        user:
          type: object
          properties:
            userId:
              type: string
            email:
              type: string
            firstName:
              type: string
            lastName:
              type: string
            currentDevice:
              type: object
              properties:
                id:
                  type: string
                side:
                  type: string
                  enum:
                    - left
                    - right
                    - solo
    DeviceResponse:
      type: object
      properties:
        result:
          type: object
          properties:
            deviceId:
              type: string
            online:
              type: boolean
            firmwareVersion:
              type: string
            leftUserId:
              type: string
            rightUserId:
              type: string
            awaySides:
              type: object
              additionalProperties:
                type: boolean
    TemperatureState:
      type: object
      properties:
        currentLevel:
          type: integer
          minimum: -100
          maximum: 100
          description: Unit-less heating/cooling level (-100 cool .. 100 warm).
        currentState:
          type: object
          properties:
            type:
              type: string
              enum:
                - smart
                - off
        smart:
          type: object
          description: Smart (Autopilot) heating levels by sleep stage.
          properties:
            bedTimeLevel:
              type: integer
            initialSleepLevel:
              type: integer
            finalSleepLevel:
              type: integer
    TemperatureUpdate:
      type: object
      properties:
        currentLevel:
          type: integer
          minimum: -100
          maximum: 100
        currentState:
          type: object
          properties:
            type:
              type: string
              enum:
                - smart
                - off
    AwayModeUpdate:
      type: object
      required:
        - awayPeriod
      properties:
        awayPeriod:
          type: object
          properties:
            action:
              type: string
              enum:
                - start
                - end
    TrendsResponse:
      type: object
      properties:
        days:
          type: array
          items:
            type: object
            properties:
              day:
                type: string
                format: date
              score:
                type: integer
                description: Sleep fitness score.
              sleepDuration:
                type: integer
                description: Total sleep in seconds.
              presenceDuration:
                type: integer
              sleepStages:
                type: array
                items:
                  type: object
                  properties:
                    stage:
                      type: string
                      enum:
                        - awake
                        - light
                        - deep
                        - rem
                        - out
                    duration:
                      type: integer
              heartRate:
                type: number
              hrv:
                type: number
              respiratoryRate:
                type: number
              tnt:
                type: integer
                description: Toss-and-turn count.
    BaseState:
      type: object
      properties:
        currentState:
          type: object
          properties:
            type:
              type: string
        leg:
          type: integer
          description: Feet (leg) angle in degrees.
        torso:
          type: integer
          description: Head (torso) angle in degrees.
        preset:
          type: string
    BaseAngleUpdate:
      type: object
      properties:
        torso:
          type: integer
          description: Head (torso) angle in degrees.
        leg:
          type: integer
          description: Feet (leg) angle in degrees.
        preset:
          type: string
          enum:
            - flat
            - sleep
            - relax
            - reading
    AlarmsResponse:
      type: object
      properties:
        alarms:
          type: array
          items:
            $ref: '#/components/schemas/Alarm'
    Alarm:
      type: object
      properties:
        id:
          type: string
        enabled:
          type: boolean
        time:
          type: string
          description: Local alarm time (HH:MM).
        days:
          type: array
          items:
            type: string
        vibrationEnabled:
          type: boolean
        thermalEnabled:
          type: boolean
        snoozeDuration:
          type: integer