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.

** 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 (from get_cycles or get_cycle_by_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')}")

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.2.1.tar.gz (21.7 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.2.1-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: whoop_sdk-0.2.1.tar.gz
  • Upload date:
  • Size: 21.7 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.2.1.tar.gz
Algorithm Hash digest
SHA256 cd94f984a27ef4bc670a22ef95fa3190ffa4176d3d1605bb262ae017fbacb058
MD5 cb75fbf63ca5c2ef8bf0702f264fdac8
BLAKE2b-256 091cc560ba37277913ca69da3615e809c5e15219e73297687a4b508aa5a15766

See more details on using hashes here.

File details

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

File metadata

  • Download URL: whoop_sdk-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 13.6 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.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4a9f10bb7f0c44b58b048f7b94cafeda0f7950125a6307e3645d724a12ac7817
MD5 409b5d2281522a79774dd5cb791c446a
BLAKE2b-256 ad0f063e0d3da21a7fd894019ce6b00f610f85b47fb195b46c31ca432d57ab9e

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