Skip to main content

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 TypeDescription
runningRunning, jogging
cyclingCycling, biking
swimmingSwimming
strengthWeight training, resistance
yogaYoga, stretching
hiitHigh-intensity interval training
walkingWalking, hiking
otherUnclassified 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';