A modern Python SDK for the WHOOP Developer API (v2)
Project description
Whoop SDK
A modern Python SDK for the WHOOP Developer API (v2). Easily integrate WHOOP fitness data into your Python applications with simple authentication and intuitive API calls. Includes an MCP server for AI assistant integration (Claude, Cursor, etc.).
** Disclaimer**: This is an unofficial SDK and is not affiliated with, endorsed by, or supported by WHOOP. Use at your own risk. The WHOOP team is not responsible for any issues that may arise from using this SDK.
Prerequisites
- Python 3.10 or higher
- A WHOOP developer account and application
Getting Started
1. Create a WHOOP Developer Application
Before using this SDK, you'll need to create a developer application on WHOOP's platform:
- Visit the WHOOP Developer Portal
- Sign up or log in to your WHOOP account
- Create a new application
- Note down your Client ID and Client Secret
- Add BOTH redirect URIs to your application:
http://localhost:8080(for automated OAuth flow)https://www.google.com(fallback for manual authorization)
The SDK will request the following scopes:
offline- For refresh token accessread:profile- Read user profile informationread:recovery- Read recovery dataread:sleep- Read sleep dataread:workout- Read workout dataread:cycles- Read cycle dataread:body_measurement- Read body measurements
2. Installation
Install the SDK from PyPI:
pip install whoop-sdk
3. Configuration & Authentication
The SDK supports two ways to provide your credentials:
Option 1: Environment Variables (Recommended)
export WHOOP_CLIENT_ID="your_client_id_here"
export WHOOP_CLIENT_SECRET="your_client_secret_here"
Option 2: Interactive Setup
If no environment variables are found, the SDK will prompt you for credentials on first run. Credentials are automatically saved to your home directory in .whoop_sdk/settings.json after interactive setup.
- Windows:
C:\Users\YourUsername\.whoop_sdk\- macOS:
/Users/YourUsername/.whoop_sdk/- Linux:
/home/YourUsername/.whoop_sdk/
4. OAuth Authentication Flow
When you call whoop.login(), the SDK uses an automated OAuth flow that requires no manual copy-paste:
- The SDK starts a localhost server on port 8080 to capture the OAuth callback
- Your browser automatically opens to the WHOOP authorization page
- After you approve access, the authorization completes automatically
- You can close the browser window - no need to copy any codes!
Manual Fallback: If the automated flow is unavailable (e.g., port 8080 is in use), the SDK automatically falls back to a manual method where you'll copy the authorization code from the redirect URL. This backup method uses https://www.google.com as the redirect URI.
Important: Ensure BOTH redirect URIs are whitelisted in your WHOOP app settings: http://localhost:8080 and https://www.google.com.
The SDK automatically manages token refresh, so you only need to complete the OAuth flow once. Tokens are saved to .whoop_sdk/config.json for future use and automatically rotated for you.
5. Quick Start
Here's a basic example to get you started:
from whoop_sdk import Whoop
# Initialize and authenticate
whoop = Whoop()
whoop.login()
# Your tokens are now saved and ready to use!
API Usage Examples
Get User Profile
# Get basic profile information
profile = whoop.get_profile()
print(f"Hello {profile['first_name']} {profile['last_name']}!")
print(f"User ID: {profile['user_id']}")
print(f"Email: {profile['email']}")
Get Body Measurements
# Body measurements (single object, not paginated)
body = whoop.get_body_measurements()
print(f"Height: {body.get('height_meter')} m")
print(f"Weight: {body.get('weight_kilogram')} kg")
print(f"Max Heart Rate: {body.get('max_heart_rate')} bpm")
Pagination
All list-style endpoints support pagination with the following defaults:
- Default page size: 10 records per page (WHOOP API default)
- Default max pages: 3 pages maximum (30 records total)
- Maximum page size: 25 records per page (WHOOP API limit)
Important: Even when you specify a date range, the default pagination limits still apply. For example, if you request data for more than a 30-day period, you'll only get the first 30 records (3 pages × 10 records) unless you explicitly set max_pages=None or increase the limit parameter.
Parameters:
limit: Controls page size (1-25, default: 10)max_pages: Maximum number of pages to fetch (default: 3, useNonefor unlimited)start/end: ISO8601 date range filters (optional)
Get Recovery Data
# Example with limit parameter
recovery = whoop.get_recovery(limit=25, max_pages=1) # Max page size, but only 1 page
print(f"Found {len(recovery.get('records', []))} recovery records") # Will return 25 latest recovery records
Get Sleep Data
from whoop_sdk import Whoop
whoop = Whoop()
whoop.login()
# Example with max_pages parameter
sleep_data = whoop.get_sleep(max_pages=5) # Fetch up to 5 pages
print(f"Found {len(sleep_data.get('records', []))} sleep records") # Will return up to last 50 records
Get Single Sleep by ID
sleep_id = sleep_data.get('records', [])[0].get('id')
first_sleep = whoop.get_sleep_by_id(sleep_id)
print(first_sleep)
Get Workout Data
from datetime import datetime, timedelta
# Note: Even with a date range, default pagination applies: 10 records per page, max 3 pages (30 records max total)
end_date = datetime.now()
start_date = end_date - timedelta(days=14)
workout_data = whoop.get_workouts(
start=start_date.isoformat() + "Z",
end=end_date.isoformat() + "Z"
)
print(f"Found {len(workout_data.get('records', []))} workout records")
Get Single Workout by ID
workout_id = workout_data.get('records', [])[0].get('id')
first_workout = whoop.get_workout_by_id(workout_id)
print(first_workout)
Get Cycles
# Get cycles with default settings
cycle_data = whoop.get_cycles()
print(f"Found {len(cycles.get('records', []))} cycle records") # Should return last 30 records, but not. Inquiry open with Whoop team
Get Single Cycle by ID
cycle_id = cycle_data.get('records', [])[0].get('id')
first_cycle = whoop.get_cycle_by_id(cycle_id)
print(first_cycle)
Get Sleep and Recovery by Cycle ID
Fetch the sleep or recovery associated with a given cycle:
from whoop_sdk import Whoop
whoop = Whoop()
whoop.login()
# First, get a cycle ID
cycles = whoop.get_cycles()
cycle_id = cycles['records'][0]['id'] if cycles.get('records') else None
if cycle_id:
# Sleep for a specific cycle
sleep_for_cycle = whoop.get_sleep_by_cycle_id(cycle_id)
print(f"Sleep score: {sleep_for_cycle.get('score', {}).get('sleep_performance_percentage')}")
# Recovery for a specific cycle
recovery_for_cycle = whoop.get_recovery_by_cycle_id(cycle_id)
print(f"Recovery score: {recovery_for_cycle.get('score', {}).get('recovery_score')}")
MCP Server
The SDK includes an MCP (Model Context Protocol) server that allows AI assistants like Claude and Cursor to access your WHOOP data directly.
Running the MCP Server
# Using uvx (no installation required)
uvx whoop-mcp
# Or if installed locally
uv run whoop-mcp
# Or as a Python module
python -m whoop_sdk.mcp
Configuration
The MCP server uses the same credentials as the SDK (~/.whoop_sdk/config.json). Make sure you've authenticated with the SDK first by running whoop.login().
Claude Desktop
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"whoop": {
"command": "uvx",
"args": ["--from", "whoop-sdk", "whoop-mcp"]
}
}
}
Note: If Claude Desktop can't find
uvx, use the full path (runwhich uvxto find it).
Cursor
Add to your Cursor MCP config (.cursor/mcp.json):
{
"mcpServers": {
"whoop": {
"command": "uvx",
"args": ["--from", "whoop-sdk", "whoop-mcp"]
}
}
}
Available Tools
| Tool | Description |
|---|---|
whoop_get_recovery |
Get recovery data with optional date range |
whoop_get_sleep |
Get sleep data with optional date range |
whoop_get_workouts |
Get workout data with optional date range |
whoop_get_cycles |
Get physiological cycle data with optional date range |
whoop_get_profile |
Get user profile information |
whoop_get_body_measurements |
Get body measurements (height, weight, max HR) |
All data tools support optional start_date, end_date (ISO format), and limit parameters.
Next Steps
Upcoming features we're working on:
-
Rate Limit Support: Automatic handling of API rate limits with intelligent retry logic and exponential backoff. The SDK will automatically detect rate limit responses (429) and retry requests with appropriate delays.
-
Webhook Integration: Cloud-deployable webhook receiver that listens for WHOOP events and automatically fetches new data as it becomes available. Perfect for real-time data processing and serverless deployments.
-
Enhanced Error Handling: Comprehensive error handling with custom exception classes for different error types (authentication errors, API errors, network errors, validation errors). Better error messages with context and improved handling of edge cases throughout the SDK.
Stay tuned for updates!
Open Source
This project is open source and welcomes contributions from the community!
License
This project is licensed under the MIT License - see the LICENSE file for details.
Repository
- Homepage: https://github.com/ericfflynn/whoop-sdk
Documentation
More detailed documentation and API reference coming soon. For now, check out the source code in the whoop_sdk package for available methods and functionality.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file whoop_sdk-0.3.1.tar.gz.
File metadata
- Download URL: whoop_sdk-0.3.1.tar.gz
- Upload date:
- Size: 24.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
430c755bba56f9c14b4df125621a156cb33919b53a8fb59ce9386c834f067f1b
|
|
| MD5 |
82fd9cf2d7344e0632a4ce44935c9b1b
|
|
| BLAKE2b-256 |
fc792deee5335ae065908fcbc9510cddf18527d262658453974863745c93b50b
|
File details
Details for the file whoop_sdk-0.3.1-py3-none-any.whl.
File metadata
- Download URL: whoop_sdk-0.3.1-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da033e776aea42b9487362254d7b4ded7bc0856194ac214c0c23c38423492d8e
|
|
| MD5 |
ea6fd9a25bcbab18e51c553419389760
|
|
| BLAKE2b-256 |
f557efd10e75a08a4c9eaa8408872295c11479ccd618525be8060f2f2922d4f3
|