Skip to content
AF
Integration Guides

WHOOP API Developer Integration Guide (2026)

Last verified October 17, 2026 · 8 min read

Sources checked (12) · October 17, 2026
The WHOOP API exposes a member's cycles (Strain), recovery, sleep, workouts, profile and body measurements through OAuth 2.0, at v2 endpoints under the base URL https://api.prod.whoop.com/developer. You need a WHOOP membership to build, you register an app in the WHOOP Developer Dashboard, request scopes such as read:recovery plus offline for a refresh token, and call the API with a Bearer token. A new app starts on the Sandbox tier with up to 10 members and climbs one tier at a time through Build, Growth and Scale to unlimited Production, with each step reviewed by WHOOP.

Covered here:WHOOP

Access and approval: membership, then member tiers#

Two access facts come before any code.

  • You need a WHOOP membership to build. WHOOP's developer overview says "You must have a WHOOP membership to develop an app on the Developer Platform", and your WHOOP account doubles as your developer login. Your users connect their own WHOOP accounts, so your audience is limited to people who already wear WHOOP.
  • Apps grow through member tiers. Every new app starts on the Sandbox tier, which allows up to 10 WHOOP members to connect, and you can build and test there without asking. Beyond that you request the next tier from the Developer Dashboard.
TierMember limit
Sandbox10
Build100
Growth1,000
Scale5,000
ProductionUnlimited

Tiers are earned one at a time: you can only request the tier directly above your current one, and from Build onward, moving up requires at least 50% of your current tier's member limit to be connected. Requests are reviewed manually, in the order received, and WHOOP rejects requests without specific, detailed answers. Before you request, WHOOP asks that you have tested with at least one member, filled in your app name, contact emails and privacy policy URL, and followed its design and brand guidelines. It also warns that contacting WHOOP employees about a request outside the Dashboard may get your app disabled.

None of this is a knock on WHOOP; they are access requirements, and the WHOOP API overview tracks them alongside every page on this site that covers WHOOP. If you want an aggregator that fronts WHOOP alongside others, see wearable data APIs. WHOOP's OAuth flow is close to Oura's, so if you have integrated one the other will feel familiar.

What you'll need#

  • A WHOOP account with an active membership, and an app created in the WHOOP Developer Dashboard, which asks you to create a team first. You can create up to five apps, and request more from the Dashboard.
  • The app's client ID and client secret. WHOOP says the secret "should only be used server side"; it also keys webhook signatures.
  • At least one redirect URI, matched exactly at authorization time, and at least one scope, since an app cannot be created without one.
  • A backend for the token exchange, refresh and webhook endpoint.

Auth and scopes#

WHOOP uses the OAuth 2.0 authorization-code flow. The API reference lists the authorization URL https://api.prod.whoop.com/oauth/oauth2/auth, the token URL https://api.prod.whoop.com/oauth/oauth2/token, and six data scopes:

ScopeWhat WHOOP's reference says it reads
read:recoveryRecovery data, including score, heart rate variability and resting heart rate
read:cyclesCycles data, including day Strain and average heart rate during a physiological cycle
read:workoutWorkout data, including activity Strain and average heart rate
read:sleepSleep data, including performance % and duration per sleep stage
read:profileProfile data, including name and email
read:body_measurementBody measurements, including height, weight and max heart rate

Add offline to the request if you need a refresh token: WHOOP's OAuth guide says you must request it to receive one. Generate a state value for CSRF protection; WHOOP says it must be eight characters long if you generate it yourself.

GET https://api.prod.whoop.com/oauth/oauth2/auth
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_REDIRECT_URI
  &response_type=code
  &scope=read:recovery%20read:sleep%20read:workout%20offline
  &state=8CHARSTR

The member signs in, sees the scopes you asked for and must authorize them before WHOOP issues a token. Exchange the returned code from your backend:

curl -X POST "https://api.prod.whoop.com/oauth/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=THE_AUTH_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=YOUR_REDIRECT_URI"

Refresh rotates both tokens#

Access tokens are short-lived: WHOOP reports the lifetime in expires_in (its sample response shows 3600 seconds) and answers an expired token with 401. Refresh at the same token URL; WHOOP's sample payload includes scope=offline:

curl -X POST "https://api.prod.whoop.com/oauth/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=THE_REFRESH_TOKEN" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "scope=offline"

WHOOP invalidates the existing access token once a refresh token is used, and the refresh token in the response replaces the one you sent. Two simultaneous refreshes for one member fail, because the first one invalidates the refresh token the second is carrying; WHOOP suggests refreshing on a schedule, for example a background job, to avoid that race. When a member disables your integration, revoke their access with the revokeUserOAuthAccess endpoint, which also stops their webhooks.

Data: the v2 endpoints#

The data API's base URL is https://api.prod.whoop.com/developer, and every data path sits under it. Earlier versions of this guide left out the /developer segment; the paths below are relative to the full base URL.

EndpointScopeWhat it returns
GET /v2/cycle and /v2/cycle/{cycleId}read:cyclesPhysiological cycles (Strain); since September 23, 2026 each cycle includes step_count
GET /v2/recovery and /v2/cycle/{cycleId}/recoveryread:recoveryRecoveries
GET /v2/activity/sleep and /v2/activity/sleep/{sleepId}read:sleepSleeps, identified by UUID
GET /v2/activity/workout and /v2/activity/workout/{workoutId}read:workoutWorkouts, identified by UUID
GET /v2/user/profile/basicread:profileName and email
GET /v2/user/measurement/bodyread:body_measurementHeight, weight, max heart rate
# The 10 most recent sleeps (WHOOP's default page size; the maximum is 25)
curl -X GET "https://api.prod.whoop.com/developer/v2/activity/sleep?limit=10" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Collections are paginated: send the next_token from each response as nextToken on the next request, with the same start and end, until next_token comes back empty. WHOOP thinks in physiological cycles rather than calendar days, so a member's current cycle has a start time and no end yet. Sleep and workout IDs are UUIDs in v2; if you stored v1 integer IDs, the one-time GET /v1/activity-mapping/{activityV1Id} lookup returns the v2 UUID, and WHOOP says to use it for migration only.

Webhooks#

Add an HTTPS URL in your app's Webhook URL setting and WHOOP POSTs whenever a connected member's data changes; with several apps you need a separate endpoint per app. The default model version is v2, which uses UUIDs, and v1 webhooks are no longer published. Each body carries user_id, id, type and trace_id. The event types are workout.updated, workout.deleted, sleep.updated, sleep.deleted, recovery.updated and recovery.deleted; creates arrive as updates, and a v2 recovery event carries the UUID of the sleep the recovery belongs to, not a cycle ID. There are no webhooks for day Strain, cycles or body measurements.

Verify every request before trusting it. WHOOP sends X-WHOOP-Signature and X-WHOOP-Signature-Timestamp; compute base64(HMAC-SHA256(timestamp_header + raw_http_request_body, client_secret)) and drop the request if it does not match the signature header.

Delivery is not guaranteed. WHOOP retries a failed delivery five times over about an hour, counting anything but a 2XX, or no response before the timeout, as a failure, and recommends returning 2XX within a second and doing the work on a queue. Duplicates happen (deduplicate on trace_id), events can be missed, and WHOOP recommends a reconciliation job that occasionally fetches the data types you care about.

Rate limits#

By default every client may send 100 requests per minute and 10,000 requests per day. Responses carry X-RateLimit-Limit (for example 100, 100;window=60, 10000;window=86400), X-RateLimit-Remaining and X-RateLimit-Reset, and an over-limit request returns 429. WHOOP can raise the limits on request: open your app in the Developer Dashboard, choose Open Request, then Rate limit increase.

Terms that shape the product#

WHOOP's API Terms of Use, effective October 6, 2026, say access to the APIs "is currently provided at no charge" and that WHOOP will give notice before charging. They also prohibit using the API or WHOOP data to create, train, fine-tune or improve any machine-learning or AI model or system, and keeping cached copies longer than the cache header allows. Plan for both before you design features around WHOOP data.

What changed recently#

DateChange (WHOOP's changelog and docs)
July 1, 2025v2 API launched; developers encouraged to migrate from v1
August 1, 2025Docs clarified that v2 recovery webhooks use the associated sleep's UUID
November 1, 2025v1 webhooks no longer published; v1-to-v2 activity ID mapping endpoint documented
September 23, 2026Cycles include step_count, covered by read:cycles with no re-consent
October 6, 2026Current API Terms of Use take effect

WHOOP's migration guide says the v1 API is no longer supported and new features go to v2 only. WHOOP also documents a separate Healthcare Partner API, a server-to-server integration for lab requisitions and diagnostic reports, which it says is available only to WHOOP-approved healthcare partners and not to general developers.

Gotchas and production notes#

  • Membership is mandatory on both sides. You need a WHOOP membership to develop, and your users are WHOOP members by definition.
  • Tiers are a ladder, not a switch. From Build onward you need half of your current tier's member limit connected before you can ask for the next one, and reviews are manual.
  • /developer is part of the base URL. Every data call goes to https://api.prod.whoop.com/developer/v2/....
  • offline scope for refresh. Without it there is no refresh token, and background sync stops when the first access token expires.
  • Refresh tokens rotate. Persist the new pair on every refresh and never refresh one member twice at once.
  • Webhooks are notifications, not data. Fetch the record after each event, deduplicate on trace_id, and run a reconciliation job for what you miss.

For a wider comparison of recovery and wearable providers, see wearable data APIs; what WHOOP costs you and your users is on WHOOP API pricing.

Frequently asked questions

Do I need a WHOOP membership to use the WHOOP API?
Yes. WHOOP's developer overview says you must have a WHOOP membership to develop an app on the Developer Platform, and your WHOOP account is also your developer login. The people who connect to your app are WHOOP members too, so the API only reaches users who already own WHOOP.
How many users can a WHOOP API app have?
It depends on the app's tier. WHOOP documents five: Sandbox (10 members), Build (100), Growth (1,000), Scale (5,000) and Production (unlimited). Every new app starts on Sandbox, tiers are requested one at a time from the Developer Dashboard, and from Build onward you need at least half of your current tier's limit connected before you can request the next one.
What are the WHOOP API rate limits?
By default WHOOP allows each client 100 requests per minute and 10,000 per day, reported in the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers, and answers an over-limit request with 429. You can ask for higher limits from the Developer Dashboard with an Open Request for a rate limit increase.
How do I get a refresh token from WHOOP?
Include the offline scope in the authorization request: WHOOP's OAuth guide says you must request it to receive a refresh token. Each refresh invalidates the old access token and returns a new refresh token you must use next time, and two simultaneous refreshes for the same member fail, so refresh on a schedule rather than in parallel.
Which WHOOP webhook events exist, and how do I verify them?
WHOOP sends workout.updated, workout.deleted, sleep.updated, sleep.deleted, recovery.updated and recovery.deleted, with creates delivered as updates. Verify each one by computing base64 of HMAC-SHA256 over the X-WHOOP-Signature-Timestamp value plus the raw body, keyed by your client secret, and comparing it with X-WHOOP-Signature. WHOOP retries failures five times over about an hour.

All 113 questions in Integration Guides →

Keep reading

Elsewhere on the site

Pages that share this one’s concepts and sources, from other sections.

Next steps

Was this page useful?

Independent comparison, last reviewed October 17, 2026. Pricing, rate limits, and feature availability change often — confirm current details in each provider’s official documentation before you commit. Product and company names are trademarks of their respective owners; AIFitnessAPI is not affiliated with, endorsed by, or sponsored by any product listed here.

← All integration guides · by AIFitnessAPI