npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dofek/eight-sleep

v0.1.4

Published

Unofficial Eight Sleep API client using reverse-engineered authentication

Readme

@dofek/eight-sleep

Unofficial TypeScript client for the private API used by Eight Sleep clients. It retrieves trend days containing sleep sessions, sleep-stage data, daily biometrics, and heart-rate samples.

This package is not affiliated with, endorsed by, or supported by Eight Sleep. It uses undocumented endpoints and an observed app authentication flow, so either may change without notice.

Requirements and installation

Requires Node.js 22.14 or newer and its built-in fetch implementation.

npm install @dofek/eight-sleep

Quick start

Save this as example.mjs, set EIGHT_SLEEP_EMAIL and EIGHT_SLEEP_PASSWORD, then run node example.mjs.

import { EightSleepClient } from "@dofek/eight-sleep";

const email = process.env.EIGHT_SLEEP_EMAIL;
const password = process.env.EIGHT_SLEEP_PASSWORD;
if (!email || !password) {
  throw new Error("Set EIGHT_SLEEP_EMAIL and EIGHT_SLEEP_PASSWORD");
}

const { accessToken, expiresIn, userId } = await EightSleepClient.signIn(
  email,
  password,
);
const client = new EightSleepClient(accessToken, userId);
const trends = await client.getTrends("UTC", "2026-07-01", "2026-07-07");

console.log({ expiresIn, days: trends.days.length });

getTrends(timezone, fromDate, toDate) expects YYYY-MM-DD dates. The current client implementation always requests all sessions with model version v2.

Public API

  • EightSleepClient.signIn(email, password, fetch?) returns accessToken, expiresIn in seconds, and userId.
  • new EightSleepClient(accessToken, userId, fetch?) creates an authenticated client. Supplying fetch is useful for custom transport instrumentation.
  • client.getTrends(timezone, fromDate, toDate) retrieves raw trend days and their nested sessions and time series.

Supported deep imports:

  • @dofek/eight-sleep/client — client and observed app credential constants.
  • @dofek/eight-sleep/parsingparseEightSleepTrendDay, parseEightSleepDailyMetrics, and parseEightSleepHeartRateSamples.
  • @dofek/eight-sleep/types — raw response interfaces.

For example:

import { parseEightSleepDailyMetrics } from "@dofek/eight-sleep/parsing";
import type { EightSleepTrendDay } from "@dofek/eight-sleep/types";

Authentication and persistence

The current implementation sends a password-grant request with client credentials observed in the Eight Sleep Android application. Those EIGHT_SLEEP_CLIENT_ID and EIGHT_SLEEP_CLIENT_SECRET values identify the upstream app; they are intentionally visible in this package and are not a substitute for the user's email and password.

Persist the returned accessToken, userId, and calculated expiry in encrypted storage. The package does not implement a refresh-token flow. Once the access token expires, call signIn again and replace the persisted credentials. Never log or commit user credentials or access tokens.

Rate limits and errors

The shared rate-limit wrapper throws ProviderRateLimitError for 429 and ProviderServiceUnavailableError for 502, 503, and 504. Both expose providerId, statusCode, responseBody, and retryAfterSeconds. The latter follows the HTTP Retry-After header when the upstream response provides it. Other unsuccessful responses throw a regular Error containing the response status and body.

If your application handles these error classes directly, declare @dofek/provider-http as a direct dependency:

npm install @dofek/provider-http
import {
  ProviderRateLimitError,
  ProviderServiceUnavailableError,
} from "@dofek/provider-http/rate-limit";

try {
  await client.getTrends("UTC", "2026-07-01", "2026-07-07");
} catch (error) {
  if (
    error instanceof ProviderRateLimitError ||
    error instanceof ProviderServiceUnavailableError
  ) {
    console.error(error.providerId, error.statusCode, error.retryAfterSeconds);
  }
  throw error;
}

Parsing behavior

The parsers convert raw duration seconds to minutes. Daily metrics come from the observed sleepQualityScore structure; parseEightSleepTrendDay derives awake time from presence time minus sleep time, and parseEightSleepHeartRateSamples reads samples nested under sessions.

Project