fix: update API calls for current Eight Sleep endpoints#31
fix: update API calls for current Eight Sleep endpoints#31omarshahine merged 3 commits intosteipete:mainfrom
Conversation
- metrics summary/aggregate: add required metrics=all param (steipete#18) - metrics trends: read --from/--to from cmd flags, add tz param (steipete#20) - device owner: fallback to device info when /owner returns 404 (steipete#19) - schedule list: add specialization param, fallback to household endpoint (steipete#17) Closes steipete#17, steipete#18, steipete#19, steipete#20 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verification against live API (and cross-check with lukas-clarke/eight_sleep
reference implementation) showed that the previous fixes added query params
to endpoints that no longer exist rather than reaching working paths:
- metrics summary/aggregate: /users/:id/metrics/{summary,aggregate} return
404 "Cannot GET" regardless of params. The modern API has no equivalent;
all sleep metrics flow through /users/:id/trends. Remove the commands.
- schedule CRUD: /users/:id/temperature/schedules and the household
fallback both 404. Eight Sleep retired the routines/schedules API; the
Autopilot schedule now lives as the `smart` subfield of
app-api.8slp.net/v1/users/:id/temperature. Retarget `schedule list` to
that endpoint and remove create/update/delete/next.
- metrics trends: endpoint is correct and --from/--to flag plumbing works,
but the default --timezone "local" was sent verbatim as tz=local, which
the API rejects (wants an IANA zone). Resolve "local" to time.Local
before querying.
- device owner: fallback to /devices/:id ownerId already works; unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Self-review (automated agents)Three specialized reviewers ran against commit 82fa5b6. Consolidated findings below — two are real, worth addressing before merge. Important1. Landmine: same
|
- Move resolveTZ to internal/client/eightsleep.go so GetSleepDay also normalizes tz. Fixes the same `tz=local`/`tz=Local` rejection in `sleep day` and `sleep range` that the prior commit only fixed for `metrics trends`. CLI call sites in cmd/sleep.go and cmd/sleep_range.go now pass the raw timezone through. - When resolveTZ falls back to UTC (system zoneinfo unavailable), emit a log.Warn so users see off-by-hours data flagged instead of silently trusting it. - GetSmartSchedule returns ErrNoSmartSchedule when the server omits or nulls the `smart` field, so an unconfigured Autopilot surfaces as a clear CLI message instead of an empty-row success. - Trim GetSmartSchedule doc comment to a single line stating the invariant, not PR history. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aligns README with the command surface after steipete#31: - schedule list is now the only schedule subcommand (CRUD + next retired) - metrics summary / aggregate removed (endpoints gone upstream) - Documents the tz=local/Local rejection and UTC fallback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aligns README with the command surface after steipete#31: - schedule list is now the only schedule subcommand (CRUD + next retired) - metrics summary / aggregate removed (endpoints gone upstream) - Documents the tz=local/Local rejection and UTC fallback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aligns README with the command surface after #31: - schedule list is now the only schedule subcommand (CRUD + next retired) - metrics summary / aggregate removed (endpoints gone upstream) - Documents the tz=local/Local rejection and UTC fallback Co-authored-by: Lobster <lobster@shahine.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Initial diagnosis attached query params (
metrics=all,specialization=all) to endpoints that no longer exist; live testing plus cross-check with thelukas-clarke/eight_sleepreference integration showed the modern Eight Sleep API has removed those endpoints entirely. Revised fixes below.What changed
schedule listspecialization=all, fall back to/household/users/:id/schedulesmartsubfield ofapp-api.8slp.net/v1/users/:id/temperatureschedule listto the smart-schedule endpoint; drop CRUD +nextsubcommands (API is gone)metrics summary/aggregatemetrics=all/users/:id/trendsdevice owner/devices/:idownerId/devices/:id/ownerdoesn't exist; fallback matches referencemetrics trends --from/--totz--timezone localwas sent verbatim; API requires a real IANA zone"local"→time.Local.String()before queryingCloses #17, #18, #19, #20.
Files
internal/client/metrics.goSummary/Aggregate; addresolveTZhelper; Trends now always sends a real IANA zoneinternal/cmd/metrics.gosummary/aggregatesubcommandsinternal/client/schedules.goGetSmartScheduletargetingapp-api.8slp.net/v1/users/:id/temperatureinternal/cmd/schedule.goschedule list(Autopilot schedule); removecreate/update/delete/nextNet: +29 / −294.
Test plan (verified against a live pod)
eightctl metrics trends --from 2026-04-10 --to 2026-04-15returns trend data with default--timezoneeightctl schedule listreturns{bedTimeLevel, initialSleepLevel, finalSleepLevel}eightctl device ownerreturnsownerIdeightctl metrics summary/aggregateno longer exist (removed rather than left broken)go test ./...passesNotes
This is a breaking change for anyone who scripted against
metrics summary,metrics aggregate, orschedule create/update/delete/next— but those commands have been returning 404 since the API migration, so nothing that depends on them is actually working today.🤖 Generated with Claude Code