Core Types
These types represent normalized health data structures. All providers transform their API responses into these common formats.
SleepData
Represents a single sleep session (overnight sleep or nap).
interface SleepData {
/** Unique identifier (prefixed with provider name) */
id: string;
/** Original ID from the provider's API */
providerId: string;
/** Sleep start time (ISO 8601 datetime) */
start: string;
/** Sleep end time (ISO 8601 datetime) */
end: string;
/** Total time in bed in milliseconds */
durationMs: number;
/** Whether this was a nap (vs overnight sleep) */
isNap: boolean;
/** Sleep performance score (0-100) */
score?: number;
/** Sleep stage breakdown */
stages?: SleepStages;
/** Additional sleep metrics */
metrics?: {
/** Sleep efficiency percentage (time asleep / time in bed) */
efficiency?: number;
/** Average respiratory rate (breaths per minute) */
respiratoryRate?: number;
};
}
SleepStages
Breakdown of time spent in each sleep stage.
interface SleepStages {
/** Light sleep duration in milliseconds */
lightMs: number;
/** Deep/slow-wave sleep duration in milliseconds */
deepMs: number;
/** REM sleep duration in milliseconds */
remMs: number;
/** Awake time during sleep period in milliseconds */
awakeMs: number;
}
Example
{
"id": "whoop-12345",
"providerId": "12345",
"start": "2024-01-15T23:30:00.000Z",
"end": "2024-01-16T07:15:00.000Z",
"durationMs": 27900000,
"isNap": false,
"score": 85,
"stages": {
"lightMs": 12600000,
"deepMs": 7200000,
"remMs": 6300000,
"awakeMs": 1800000
},
"metrics": {
"efficiency": 93.5,
"respiratoryRate": 14.2
}
}
RecoveryData
Represents daily recovery/readiness data.
interface RecoveryData {
/** Unique identifier (prefixed with provider name) */
id: string;
/** Original ID from the provider's API */
providerId: string;
/** Date of the recovery measurement (YYYY-MM-DD) */
date: string;
/** Recovery score (0-100) */
score?: number;
/** Recovery metrics */
metrics?: {
/** Heart rate variability in milliseconds */
hrv?: number;
/** Resting heart rate in BPM */
restingHeartRate?: number;
/** Blood oxygen saturation percentage */
spo2?: number;
/** Skin temperature deviation in Celsius */
skinTemp?: number;
};
}
Example
{
"id": "whoop-67890",
"providerId": "67890",
"date": "2024-01-16",
"score": 72,
"metrics": {
"hrv": 45.5,
"restingHeartRate": 52,
"spo2": 97.8
}
}
WorkoutData
Represents a workout or physical activity session.
interface WorkoutData {
/** Unique identifier (prefixed with provider name) */
id: string;
/** Original ID from the provider's API */
providerId: string;
/** Workout start time (ISO 8601 datetime) */
start: string;
/** Workout end time (ISO 8601 datetime) */
end: string;
/** Workout duration in milliseconds */
durationMs: number;
/** Type of sport/activity */
sportType: string;
/** Strain/intensity score (provider-specific scale) */
strain?: number;
/** Workout metrics */
metrics?: {
/** Average heart rate in BPM */
averageHeartRate?: number;
/** Maximum heart rate in BPM */
maxHeartRate?: number;
/** Calories burned */
calories?: number;
/** Distance in meters */
distance?: number;
};
}
Sport Types
Sport types are normalized across providers when possible:
| Normalized Type | Description |
|---|---|
running | Running, jogging |
cycling | Cycling, biking |
swimming | Swimming |
strength | Weight training, resistance |
yoga | Yoga, stretching |
hiit | High-intensity interval training |
walking | Walking, hiking |
other | Unclassified activity |
Providers may return additional sport types not in this list.
Example
{
"id": "whoop-11111",
"providerId": "11111",
"start": "2024-01-16T06:00:00.000Z",
"end": "2024-01-16T07:15:00.000Z",
"durationMs": 4500000,
"sportType": "running",
"strain": 14.2,
"metrics": {
"averageHeartRate": 155,
"maxHeartRate": 178,
"calories": 650,
"distance": 8500
}
}
Zod Schemas
Each type has a corresponding Zod schema for runtime validation:
import { z } from 'zod';
export const SleepStagesSchema = z.object({
lightMs: z.number(),
deepMs: z.number(),
remMs: z.number(),
awakeMs: z.number(),
});
export const SleepDataSchema = z.object({
id: z.string(),
providerId: z.string(),
start: z.string(),
end: z.string(),
durationMs: z.number(),
isNap: z.boolean(),
score: z.number().optional(),
stages: SleepStagesSchema.optional(),
metrics: z.object({
efficiency: z.number().optional(),
respiratoryRate: z.number().optional(),
}).optional(),
});
export const RecoveryDataSchema = z.object({
id: z.string(),
providerId: z.string(),
date: z.string(),
score: z.number().optional(),
metrics: z.object({
hrv: z.number().optional(),
restingHeartRate: z.number().optional(),
spo2: z.number().optional(),
skinTemp: z.number().optional(),
}).optional(),
});
export const WorkoutDataSchema = z.object({
id: z.string(),
providerId: z.string(),
start: z.string(),
end: z.string(),
durationMs: z.number(),
sportType: z.string(),
strain: z.number().optional(),
metrics: z.object({
averageHeartRate: z.number().optional(),
maxHeartRate: z.number().optional(),
calories: z.number().optional(),
distance: z.number().optional(),
}).optional(),
});
Validation Example
import { SleepDataSchema } from '@wellpipe/core';
function validateSleepData(data: unknown): SleepData {
return SleepDataSchema.parse(data);
}
// Or for safe parsing (returns result object instead of throwing)
function safeParseSleepData(data: unknown) {
const result = SleepDataSchema.safeParse(data);
if (result.success) {
return result.data;
} else {
console.error('Validation failed:', result.error);
return null;
}
}
Type Exports
All types are exported from the package root:
import type {
SleepData,
SleepStages,
RecoveryData,
WorkoutData,
TokenProvider,
HealthProvider,
} from '@wellpipe/core';
import {
SleepDataSchema,
SleepStagesSchema,
RecoveryDataSchema,
WorkoutDataSchema,
} from '@wellpipe/core';