Need help with your Whoop integration? Pop into our Discord if you have questions or want to discover how Open Wearables can solve your problems.
Overview
Whoop provides access to workout, sleep, recovery, and body measurement data through their REST API. The integration uses OAuth 2.0 for authentication and pull-based syncing to fetch data.Supported data types
Workout field availability
Several workout fields are conditional in the Whoop API and arenull for most workouts. This is expected upstream behaviour, not a gap in Open Wearables’ mapping — the values never arrive in the payload.
distance_meter and altitude_gain_meter are present-but-null, not omitted.The Whoop OpenAPI spec describes these as “Only present if distance data sent to WHOOP”, which suggests the keys are absent. In practice Whoop includes both keys on every scored workout and sets them to null. Check for a null value rather than key presence — "distance_meter" in score is always true.Whoop is worn as a passive strap, so most users’ GPS is recorded by a separate watch or phone app rather than by Whoop itself. Distance is therefore missing even for sports where you would expect it: across all workouts stored in our reference deployment, exactly 1 of 123 runs and 0 of 49 rides carried a distance value.avg_pace_sec_per_km and name are currently hardcoded to null in the /workouts endpoint for all providers, not just Whoop. name has no corresponding column on the event record. Pace would additionally be unavailable for Whoop regardless, since it derives from distance.Sleep stage detail
Whoop reports sleep stages as aggregate durations for the whole sleep, not as a timed sequence. Thesleep_stages field on sleep records is therefore always null for Whoop, while providers whose APIs expose per-stage intervals (Apple Health, Garmin, Oura, Samsung) populate it.
This is an upstream API limitation, not a gap in Open Wearables. Whoop’s three sleep endpoints —
/v2/activity/sleep, /v2/activity/sleep/{sleepId} and /v2/cycle/{cycleId}/sleep — all return the same Sleep schema, whose score.stage_summary contains only millisecond totals (total_light_sleep_time_milli, total_slow_wave_sleep_time_milli, total_rem_sleep_time_milli, and so on). No Whoop endpoint exposes per-stage intervals, and no sleep schema in the Whoop OpenAPI spec contains an array of stage records.The only timestamps on a Whoop sleep are the overall start and end.Data delivery
What you need by the end
- App credentials: Client ID + Client Secret
- OAuth scopes configured
- Redirect URI registered in the Whoop Developer Dashboard
- Webhook URL registered in the Whoop Developer Dashboard (optional, for real-time updates)
Prerequisites
- A Whoop account with an active membership
Application walkthrough
1
Sign up for Whoop
You must have a Whoop membership to develop on the Whoop Developer Platform. Your Whoop account is also your developer login.If you don’t have one yet, join Whoop here.
2
Create a Team in the Developer Dashboard
Go to the Whoop Developer Dashboard and sign in with your Whoop account credentials.Before creating an app, you’ll be prompted to create a Team. Choose a name for your team and click Create Team.
You can invite other developers to your team later from the Team section of the Developer Dashboard. They’ll need a Whoop account to be added.
3
Create an App
In the Developer Dashboard, go to the app creation flow:
- App Name: Your application name
- Scopes: Select the scopes your app needs (see table below)
- Redirect URIs: Add your OAuth callback URL (e.g.
http://localhost:8000/api/v1/oauth/whoop/callbackfor local development)
- Client ID
- Client Secret
4
Configure credentials in Open Wearables
Add the following to your Configuration details:
.env file:5
Connect a user via OAuth
With credentials configured and your Open Wearables instance running, initiate the OAuth flow to connect a user’s Whoop account.1. Get the authorization URL:Response:2. Redirect the user to the You should see a connection with
authorization_url. They will log in to Whoop and authorize your app.3. Whoop redirects back to the callback URI configured in your .env (WHOOP_REDIRECT_URI). Open Wearables automatically exchanges the authorization code for access and refresh tokens.4. Verify the connection was created:"provider": "whoop" and "status": "active".The
redirect_uri parameter in the authorize call is where the user is sent after the flow completes (e.g., back to your app). This is separate from WHOOP_REDIRECT_URI in your .env, which is the server-side OAuth callback that Whoop sends the authorization code to.6
Set up webhooks (optional)
Webhooks give you real-time updates instead of waiting for the next polling cycle. When Whoop records a new workout, sleep session, or recovery, it immediately notifies Open Wearables, which fetches and saves the record.1. Register the webhook URL in the Whoop Developer Dashboard:Go to your app in the Whoop Developer Dashboard, navigate to Webhooks, and add your callback URL:For local development, use a tunnel such as ngrok:Select payload version v2 (uses UUID resource IDs).2. Set the webhook secret:Whoop uses your app’s Client Secret (
WHOOP_CLIENT_SECRET) to sign webhook requests — no additional secret is needed. Ensure it is set in your .env.Supported events:Webhook registration is manual — there is no API to register subscriptions programmatically. All configuration is done through the Developer Dashboard.
7
Sync data
An initial sync is triggered automatically after a successful OAuth connection. To manually sync or fetch historical data:You can also sync specific data types:
When no date range is specified, Whoop defaults to syncing the last 30 days of data.
8
Verify the integration
Once data has synced, fetch it via the Open Wearables API:If data is returned, your Whoop integration is working end-to-end.
9
Submit your app for production (when ready)
While developing, your app works in development mode. When you’re ready to launch:
- Go to the Developer Dashboard
- Submit your app for approval
Rate Limits
Whoop applies two rate limits by default:
How Open Wearables uses the quota: Each sync cycle per user makes ~4-7 API requests (workouts, sleep, recovery, and body measurements — each paginated at 25 items per page). With the default polling interval of 1 hour, that’s roughly ~120 requests per user per day. This means the default rate limits comfortably support ~60-80 connected users per app.
If you need to support more users right now, you can request increased rate limits from Whoop via the Developer Dashboard.
With webhooks enabled, most data arrives in real time and the polling cycle only acts as a fallback.
OAuth Scopes Reference
The default scope
offline read:cycles read:sleep read:recovery read:workout read:body_measurement read:profile covers all data types currently processed by Open Wearables.
Next Steps
API Reference
Explore the Open Wearables API endpoints.
Architecture
Understand the overall system architecture.
Support
Need Help?
- Join our Discord and ask a question.
- Check GitHub Discussions.
- Check the Whoop Developer Documentation.

