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": ["whoop-mcp"]
    }
  }
}

Cursor

Add to your Cursor MCP config (.cursor/mcp.json):

{
  "mcpServers": {
    "whoop": {
      "command": "uvx",
      "args": ["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.0.tar.gz (25.1 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.0-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file whoop_sdk-0.3.0.tar.gz.

File metadata

  • Download URL: whoop_sdk-0.3.0.tar.gz
  • Upload date:
  • Size: 25.1 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.0.tar.gz
Algorithm Hash digest
SHA256 a2eade587bf4a31e94f047c51f911d7a19669455d4f882cdd23d60481127f348
MD5 4e0f3c16e159668e2394badd16632145
BLAKE2b-256 c3f9e10be7f5a4142c902cdb5bbe6ad3e2ab035645321a52bf57d523cce0b358

See more details on using hashes here.

File details

Details for the file whoop_sdk-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: whoop_sdk-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 17.5 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a15a359f09a12204450b1e82d1001c924bf2d5862e8f91cdd5fb9a43a29d302b
MD5 743bfa69204b91786858c73460c33d66
BLAKE2b-256 7266e0f8b1cb6d9a62a5602f8e36f0e37159773180a5db4e65b6f5b4f5a6df41

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