Skip to main content

WhoopClient

The WhoopClient class provides programmatic access to the WHOOP API with automatic token management and data normalization.

Constructor​

import { WhoopClient } from '@wellpipe/whoop';

const client = new WhoopClient(tokenProvider: TokenProvider, options?: WhoopClientOptions);

Parameters​

ParameterTypeRequiredDescription
tokenProviderTokenProviderYesToken management implementation
optionsWhoopClientOptionsNoClient configuration

Options​

interface WhoopClientOptions {
/** Base URL for WHOOP API (default: https://api.prod.whoop.com) */
baseUrl?: string;

/** Request timeout in milliseconds (default: 30000) */
timeout?: number;

/** Maximum retry attempts (default: 3) */
maxRetries?: number;

/** Enable debug logging (default: false) */
debug?: boolean;
}

HealthProvider Methods​

These methods implement the HealthProvider interface from @wellpipe/core.

getSleep​

Get normalized sleep data for a date range.

async getSleep(startDate: string, endDate: string): Promise<SleepData[]>

Parameters:

  • startDate - Start date (YYYY-MM-DD or ISO 8601)
  • endDate - End date (YYYY-MM-DD or ISO 8601)

Returns: Array of SleepData objects

Example:

const sleepData = await client.getSleep('2024-01-01', '2024-01-07');

for (const sleep of sleepData) {
console.log(`${sleep.start}: Score ${sleep.score}, Duration ${sleep.durationMs / 3600000}h`);
}

getRecovery​

Get normalized recovery data for a date range.

async getRecovery(startDate: string, endDate: string): Promise<RecoveryData[]>

Parameters:

  • startDate - Start date (YYYY-MM-DD)
  • endDate - End date (YYYY-MM-DD)

Returns: Array of RecoveryData objects

Example:

const recoveryData = await client.getRecovery('2024-01-01', '2024-01-07');

for (const recovery of recoveryData) {
console.log(`${recovery.date}: Score ${recovery.score}, HRV ${recovery.metrics?.hrv}ms`);
}

getWorkouts​

Get normalized workout data for a date range.

async getWorkouts(startDate: string, endDate: string): Promise<WorkoutData[]>

Parameters:

  • startDate - Start date (YYYY-MM-DD or ISO 8601)
  • endDate - End date (YYYY-MM-DD or ISO 8601)

Returns: Array of WorkoutData objects

Example:

const workouts = await client.getWorkouts('2024-01-01', '2024-01-07');

for (const workout of workouts) {
console.log(`${workout.sportType}: Strain ${workout.strain}, Duration ${workout.durationMs / 60000}min`);
}

Extended Methods​

These methods provide additional functionality beyond the core interface.

getCycles​

Get physiological cycle data (the daily period from wake to wake).

async getCycles(startDate: string, endDate: string): Promise<CycleData[]>

Returns:

interface CycleData {
id: string;
start: string;
end: string;
strain: number;
kilojoules: number;
averageHeartRate: number;
maxHeartRate: number;
}

getProfile​

Get user profile information.

async getProfile(): Promise<UserProfile>

Returns:

interface UserProfile {
userId: string;
email: string;
firstName: string;
lastName: string;
}

getBodyMeasurement​

Get body measurement data.

async getBodyMeasurement(): Promise<BodyMeasurement>

Returns:

interface BodyMeasurement {
heightMeter: number;
weightKilogram: number;
maxHeartRate: number;
}

Raw API Access​

For advanced use cases, you can access the raw WHOOP API responses.

getRawSleep​

async getRawSleep(params: {
start?: string;
end?: string;
limit?: number;
nextToken?: string;
}): Promise<WhoopSleepResponse>

getRawRecovery​

async getRawRecovery(params: {
start?: string;
end?: string;
limit?: number;
nextToken?: string;
}): Promise<WhoopRecoveryResponse>

getRawWorkouts​

async getRawWorkouts(params: {
start?: string;
end?: string;
limit?: number;
nextToken?: string;
}): Promise<WhoopWorkoutResponse>

Error Handling​

The client throws typed errors for different failure scenarios:

import { WhoopApiError, WhoopAuthError, WhoopRateLimitError } from '@wellpipe/whoop';

try {
const data = await client.getSleep('2024-01-01', '2024-01-07');
} catch (error) {
if (error instanceof WhoopAuthError) {
// Token expired or invalid - need to re-authenticate
console.error('Authentication failed:', error.message);
} else if (error instanceof WhoopRateLimitError) {
// Rate limit exceeded - wait and retry
console.error('Rate limited, retry after:', error.retryAfter);
} else if (error instanceof WhoopApiError) {
// Other API error
console.error('API error:', error.statusCode, error.message);
} else {
throw error;
}
}

Error Types​

ErrorDescription
WhoopAuthErrorToken invalid or expired (401)
WhoopRateLimitErrorRate limit exceeded (429)
WhoopApiErrorOther API errors

Pagination​

WHOOP API responses are paginated. The client handles pagination automatically, but you can control it for large datasets:

// Get all data (automatic pagination)
const allSleep = await client.getSleep('2024-01-01', '2024-12-31');

// Or paginate manually for memory efficiency
async function* getSleepPaginated(client: WhoopClient, start: string, end: string) {
let nextToken: string | undefined;

do {
const response = await client.getRawSleep({ start, end, limit: 25, nextToken });
yield* response.records;
nextToken = response.next_token;
} while (nextToken);
}

for await (const sleep of getSleepPaginated(client, '2024-01-01', '2024-12-31')) {
console.log(sleep);
}

Testing​

Use the mock client for testing:

import { MockWhoopClient } from '@wellpipe/whoop/testing';

const mockClient = new MockWhoopClient();

// Set up mock data
mockClient.setSleepData([
{
id: 'test-1',
providerId: '1',
start: '2024-01-15T23:00:00.000Z',
end: '2024-01-16T07:00:00.000Z',
durationMs: 28800000,
isNap: false,
score: 85,
},
]);

// Use in tests
const sleep = await mockClient.getSleep('2024-01-15', '2024-01-16');
expect(sleep).toHaveLength(1);
expect(sleep[0].score).toBe(85);