Whoop logo

Whoop

Overview

The Ingest Whoop connector reads from the Whoop v2 Developer API using OAuth2 authorization_code flow — the standard "Sign in with Whoop" pattern that requires a one-time browser consent. Once you authorize the Ingest app on your Whoop account, refresh tokens keep the connection alive without further interaction.

Whoop's developer program is open to any account holder; there's no separate paid tier for API access. The data you can read is whatever the authorized user has on their own profile — there's no shared-team or org-level Whoop data model.

Setup guide

Register an app on Whoop's developer dashboard

  1. Open developer-dashboard.whoop.com and sign in with your Whoop account.
  2. Click Create New App, give it a name (e.g. ingest), and select the read scopes for the data Ingest should pull: read:profile, read:body_measurement, read:cycles, read:recovery, read:sleep, read:workout.
  3. Set the Redirect URI to the Ingest callback URL your Ingest contact provides.
  4. Save. Copy the Client ID and Client Secret shown on the next screen.

Authorize the app on a Whoop account

Whoop OAuth requires a one-time browser consent to mint the initial access_token + refresh_token. Your Ingest contact will run a short one-shot exchange script:

  1. Open the authorization URL the script prints in a browser.
  2. Sign in to Whoop and click Authorize to grant the scopes from step 2 above.
  3. The script catches the redirect, exchanges the code for an access_token + refresh_token, and prints both values.

Paste all four values (client_id, client_secret, access_token, refresh_token) into the Ingest UI under Connectors → Whoop. Ingest stores them in AWS Secrets Manager. From there the runtime auto-refreshes access_token when it expires.

Mind the limits

Whoop doesn't publish a per-second rate cap in their public docs. The Ingest runtime dispatches conservatively at 2 req/sec and uses AIMD backoff on 429 responses. Errors with status 401 (bad/expired token, or scope missing) and 403 (revoked authorization) are treated as fatal — re-authorize via the developer dashboard before retrying.

Pagination is cursor-based via nextToken, and Whoop caps page size at 25 records.

Pick endpoints

Whoop's data model is rooted at the user's profile and branches into four parallel feeds — cycles (one per "day", the Whoop unit of measurement), recovery, sleep, and workouts. Each feed has both a collection endpoint (list) and a per-cycle / per-id variant for drilldowns.

  • Identity: profile, body_measurement — name, email, height/weight/max-HR
  • Daily rhythm: cycles (the Whoop day boundaries), recovery (per-day recovery score)
  • Sleep: sleep (one row per night), sleep_for_cycle (sleep tied to a specific cycle), sleep_by_id (single sleep drill-down)
  • Workouts: workout (one row per workout), workout_by_id (single workout drill-down)
  • Drilldowns: cycle_by_id, recovery_for_cycle — for joining specific cycles to their detail

Supported streams

11 endpoints are available out of the box. Each endpoint syncs into its own Iceberg table in Snowflake.

EndpointDescriptionReference
body_measurement
body_measurement
Get user body measurements (height, weight, max HR)
cycle_by_id
cycle_by_id
Get a single cycle by ID
cycles
cycles
Get all physiological cycles for a user, paginated. Results sorted by start time descending.
profile
profile
Get basic user profile (name, email)
recovery
recovery
Get all recoveries for a user, paginated. Results sorted by sleep start time descending.
recovery_for_cycle
recovery_for_cycle
Get the recovery associated with a specific cycle
sleep
sleep
Get all sleep activities for a user, paginated. Results sorted by start time descending.
sleep_by_id
sleep_by_id
Get a single sleep activity by ID
sleep_for_cycle
sleep_for_cycle
Get the sleep associated with a specific cycle
workout
workout
Get all workout activities for a user, paginated. Results sorted by start time descending.
workout_by_id
workout_by_id
Get a single workout by ID

Authentication

Auth type
OAuth 2.0

Performance & limits

Rate limit
Whoop's public API documentation does not publish a specific per-second cap. Ingest dispatches at 2 req/sec by default and uses AIMD backoff on 429s. Cursor-paginated at 25 records per page (the API's hard maximum).
Automatic backoff
Ingest throttles requests to the published rate limit and retries with exponential backoff on transient errors. You don't need to handle 429s, retries, or pagination yourself.

Resources