Skip to main content

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:

  1. Visit the WHOOP Developer Portal
  2. Sign up or log in to your WHOOP account
  3. Create a new application
  4. Note down your Client ID and Client Secret
  5. 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 access
  • read:profile - Read user profile information
  • read:recovery - Read recovery data
  • read:sleep - Read sleep data
  • read:workout - Read workout data
  • read:cycles - Read cycle data
  • read: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:

  1. The SDK starts a localhost server on port 8080 to capture the OAuth callback
  2. Your browser automatically opens to the WHOOP authorization page
  3. After you approve access, the authorization completes automatically
  4. 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, use None for 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 (run which uvx to 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

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

whoop_sdk-0.3.1.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

whoop_sdk-0.3.1-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

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

Hashes for whoop_sdk-0.3.1.tar.gz
Algorithm Hash digest
SHA256 430c755bba56f9c14b4df125621a156cb33919b53a8fb59ce9386c834f067f1b
MD5 82fd9cf2d7344e0632a4ce44935c9b1b
BLAKE2b-256 fc792deee5335ae065908fcbc9510cddf18527d262658453974863745c93b50b

See more details on using hashes here.

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

Hashes for whoop_sdk-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 da033e776aea42b9487362254d7b4ded7bc0856194ac214c0c23c38423492d8e
MD5 ea6fd9a25bcbab18e51c553419389760
BLAKE2b-256 f557efd10e75a08a4c9eaa8408872295c11479ccd618525be8060f2f2922d4f3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page