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.1.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.1.0
File Size Uploaded
orion_sleep_api-0.1.0.tar.gz 77.8 kB Details

Built distribution (wheel)

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

Total release size: 121.7 kB

Release files / orion_sleep_api-0.1.0.tar.gz

Download URL orion_sleep_api-0.1.0.tar.gz
Size 77.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3b8f423505a7d70715bf33da70e3660f8408d13cec66a21cb76b22b64c8bf920
BLAKE2b-256 checksum
How to use checksums
a3d414cf2c33e7a9d0feeb8f26c8a9910e275275a879189b96a6b7675fa092dc
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 29, 2026.

Transparency log

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

Download URL orion_sleep_api-0.1.0-py3-none-any.whl
Size 44.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab8c5a9f429742b5c4f0a94997bf737433b4f830f0b64775cef92c34680f6a69
BLAKE2b-256 checksum
How to use checksums
da4ec81317866965b1191546cdc74d7f97c9d06f7183d3f3d87cebd97263f726
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 29, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

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