Eight Sleep Base API
UNOFFICIAL community app-API endpoints for the adjustable Base - read state (GET /v1/users/{userId}/base) and set head/feet angles or presets (POST /v1/users/{userId}/base/angle). Reverse-engineered, not officially supported.
UNOFFICIAL community app-API endpoints for the adjustable Base - read state (GET /v1/users/{userId}/base) and set head/feet angles or presets (POST /v1/users/{userId}/base/angle). Reverse-engineered, not officially supported.
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