eightctl is an unofficial CLI for controlling Eight Sleep Pods and exporting sleep data. It is for people who want pod controls and metrics from a terminal or script.
Important
Eight Sleep does not publish a stable public API. eightctl uses the company's cloud endpoints, so provider changes and rate limits can interrupt commands; it does not provide local or Bluetooth control.
With Homebrew:
brew install steipete/tap/eightctlPrebuilt archives for macOS, Linux, and Windows on amd64 and arm64 are available from the latest GitHub release.
Check the installed version with eightctl --version or eightctl version.
To build and install from source, use Go 1.26.7 or newer:
go install github.com/steipete/eightctl/cmd/eightctl@latestSet your Eight Sleep account credentials, then inspect and control the pod:
export EIGHTCTL_EMAIL="you@example.com"
export EIGHTCTL_PASSWORD="your-password"
eightctl status
eightctl temp 20
eightctl temp -40 --side rightstatus, on, off, and temp act on all discovered household sides unless you select one with --side left|right|solo or --target-user-id <id>.
| Area | Commands |
|---|---|
| Pod control | status, on, off, temp, away |
| Sleep data | sleep, presence, metrics |
| Pod features | alarm, audio, base, device, schedule, tempmode |
| Account and travel | household, autopilot, travel |
Run eightctl <command> --help for flags and subcommands. The command specification covers the complete surface and current provider constraints.
Use eightctl away on --both before a trip and eightctl away off --both to resume all household members, including when everyone is already away. If household user IDs cannot be resolved, the command reports an error.
eightctl away status reads the cloud-reported state for all discovered household sides; use --side or --target-user-id to select one person. In contrast, away on|off without targeting flags changes only the authenticated user's side. The cloud is eventually consistent: readback may show the previous state after a write and does not immediately confirm that a change took effect.
Flags take precedence over EIGHTCTL_* environment variables, which take precedence over ~/.config/eightctl/config.yaml:
email: "you@example.com"
password: "your-password"
timezone: "America/New_York"
output: "table"
schedule:
- time: "22:30"
action: "temp"
temperature: "-20"Keep the file readable only by your account with chmod 600 ~/.config/eightctl/config.yaml. The optional user_id is resolved after authentication, and the public app OAuth client is used unless client_id and client_secret are set.
Schedule times and dates use the configured timezone, even when it differs from the host timezone.
Preview scheduled actions without changing the pod, then remove --dry-run when the schedule is ready:
eightctl daemon --config ~/.config/eightctl/config.yaml --dry-runCommands that return rows support table, JSON, and CSV output. Use --fields to select columns:
eightctl status --output json
eightctl sleep day --date 2026-08-01 --output csv
eightctl status --fields side,name,mode,leveleightctl authenticates against Eight Sleep's OAuth service and caches tokens in the operating system keyring, with a file-backed fallback. Reusing cached tokens reduces login traffic, but the provider can still return rate-limit errors.
eightctl logout removes the selected account's local cached token from reachable stores. It returns an error if a reachable store refuses deletion, even when another store clears successfully. An unavailable store remains tolerated if another opens. Logout does not revoke tokens at Eight Sleep; an already-issued token remains valid at the service until it expires.
The API is undocumented and cloud-only. The project specification records the current contract, while CHANGELOG.md tracks endpoint removals and compatibility changes.
The preferred build toolchain is Go 1.26.8, selected by go.mod; Go 1.26.7 remains the supported minimum and is tested in CI. The optional package scripts use pnpm 12.3.4 with Node.js 24 or newer.
make build
go test ./...
make coverage
make lintmake build writes ./eightctl. To install a local development build, run
make install; it creates ~/.local/bin if needed. Add that directory to your
PATH, or select another binary directory with
make install PREFIX=/usr/local/bin.
On macOS, installation ad-hoc signs and verifies the installed executable to avoid stale-signature launch failures after replacement. A rebuilt executable can still trigger a Keychain authorization prompt when accessing cached tokens; this install helper does not make authenticated commands prompt-free on unattended hosts. Published releases use the separate signed release pipeline.
CI runs formatting, lint, tests, the core-package coverage gate, and a release-artifact smoke test.
MIT. See LICENSE.