npm install @0x3639/intervals-icu
Requires Node.js 18 or later.
The package ships both ESM and CommonJS builds, with types for both.
ESM:
import { IntervalsClient } from '@0x3639/intervals-icu';
CommonJS:
const { IntervalsClient } = require('@0x3639/intervals-icu');
// athleteId defaults to '0', which the API resolves to the authenticated athlete.
const client = new IntervalsClient({ apiKey });
A method's optional trailing athleteId argument falls back to the athleteId the client was configured with, which itself defaults to '0' — resolved by the API to the athlete that owns the API key — so most calls need no athlete id at all. The API key itself comes from Intervals.icu under Settings → Developer.
const me = await client.athletes.getAthlete();
console.log(`Hello ${me.name ?? me.id}`);
const localDate = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
const now = new Date(); // one timestamp for both bounds
const weekAgo = new Date(now);
weekAgo.setDate(weekAgo.getDate() - 6);
const newest = localDate(now);
const oldest = localDate(weekAgo);
const activities = await client.activities.listActivities({ oldest, newest });
console.log(`${activities.length} activities in the last 7 days`);
for (const a of activities.slice(0, 5)) {
console.log(` ${a.start_date_local} ${a.type ?? '?'} ${a.name ?? ''}`);
}
const wellness = await client.wellness.listWellness({ oldest, newest });
const latest = wellness.at(-1);
if (latest) console.log(`Latest wellness: ${latest.date} weight=${latest.weight ?? '-'} hrv=${latest.hrv ?? '-'}`);
else console.log('No wellness records this week');
AthleteService.getAthlete returns the authenticated athlete's profile. ActivityService.listActivities lists activities in a date range. WellnessService.listWellness lists wellness records over the same range.