Skip to main content

orion-sleep-api

Async Python client for the Orion Sleep smart mattress topper.

Orion publishes no API documentation. This contract was rebuilt from captured traffic and a decompile of the Android app, then verified against a real bed one endpoint at a time.

Every endpoint says how much it is trusted

That verification is the point of this library, so it is written into the code rather than a wiki nobody reads.

Label Meaning
Measured A real request went to a real bed and the result was recorded.
App-derived Read out of the decompiled Android client. Plausible, never executed.
Speculative Guessed. Nothing speculative ships here.

Every method's docstring carries one, along with what the label rests on: a dated request and its response, or the part of the app the contract was read out of.

The labels exist because a reverse-engineered contract has no other way to tell a route that was proven from one that was only inferred. Both look equally confident in code, and only one of them will work.

Install

pip install orion-sleep-api

Quick start

import aiohttp
from orion_sleep_api import OrionApiClient

async with aiohttp.ClientSession() as session:
    client = OrionApiClient(session)

    # Passwordless, same as the app. A code arrives by SMS or email.
    await client.request_auth_code(phone="15555550100")
    tokens = await client.verify_auth_code(code="123456", phone="15555550100")

    client = OrionApiClient(session, **tokens)
    devices = await client.list_devices()

Tokens refresh themselves. Register a callback to persist the new ones:

client.set_token_refresh_callback(
    lambda access, refresh, expires_at: save_somewhere(access, refresh, expires_at)
)

Two identifiers, and they are not interchangeable

This is the single easiest way to get a confusing 403 or 404 out of this API.

Routes Identifier
/live, /live/zones/{id}, /action, /activate, /deactivate, /update, the WebSocket serial_number
PUT /v1/devices/{id}, the only metadata write (name, orientation, timezone) device UUID

Sending the wrong one fails with no useful message. Three of these routes were originally wired up with the UUID and returned an error on every call, which is how the rule was found.

Nearly everything takes the serial. Reach for the UUID only on that one metadata write, and when a route is undocumented, guess serial.

What it covers

Devices and live state, per-zone temperature and power, LED brightness and quiet mode, rapid cooling, per-user sleep schedules including single-day overrides, sleep insights with stages and apnea, session management, user access and invitations, and the live WebSocket.

Full endpoint list with confidence labels: read the docstrings. The evidence behind every "measured" label is under "What is known about the API" in AGENTS.md, organised by route family, recording what was sent and what came back. There is also an openapi.yaml in the Home Assistant integration repository.

Live data

from orion_sleep_api import OrionWebSocketManager

def on_message(serial, event_type, payload):
    print(serial, event_type, payload.get("zones"))

manager = OrionWebSocketManager(session, client, on_message=on_message)
manager.sync_to_serials(["ABCDEF123456"])

The socket pushes roughly every two seconds. It needs ALPN forced to http/1.1 and an okhttp user agent, both of which this library handles. Thirty seconds of silence means the stream is dead even though the socket is still open, so the client reconnects with backoff.

Home Assistant

The Orion Sleep integration is built on this library and is the reason it exists. If you want a bed in Home Assistant, install that. If you want to write your own tooling, this is the piece you want.

Contributing

One rule: do not add a method for a route you have not verified. If you cannot demonstrate a request against a live bed, label it app-derived and say so in the docstring. A confident wrapper around a guessed endpoint is worse than no wrapper.

AGENTS.md has the rest: how to verify a write against a bed somebody may be asleep on, what is known about each route family, the traps that have cost people hours, the layout, and the release process.

License

MIT.

Not affiliated with or endorsed by Orion Longevity Inc.

Metadata

Release files for orion-sleep-api 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for orion-sleep-api 0.2.0
File Size Uploaded
orion_sleep_api-0.2.0.tar.gz 82.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for orion-sleep-api 0.2.0
File Interpreter ABI Platform
orion_sleep_api-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 128.5 kB

Release files / orion_sleep_api-0.2.0.tar.gz

Download URL orion_sleep_api-0.2.0.tar.gz
Size 82.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0c271f2f5f1a0520d06878bf536ff8362adbb7db908d5e79e0cd4b9f687ab726
BLAKE2b-256 checksum
How to use checksums
7aadf6f49d3f59cf50a3998c42f1925befa0f4cdefed800b9a257bf54b3efa9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Release files / orion_sleep_api-0.2.0-py3-none-any.whl

Download URL orion_sleep_api-0.2.0-py3-none-any.whl
Size 46.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0587faf8c5eaccda0c61c4880cef4dbdf498ae99292a70e180dedb6b2f375ed7
BLAKE2b-256 checksum
How to use checksums
baaf843f8debbf38aaf08715a26020f62f5f6e96f6ac1d1f5ed307d1ad6f7cf0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page