New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

node-intervals-icu

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-intervals-icu

Lightweight TypeScript client library for Intervals.icu API

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

node-intervals-icu

A lightweight TypeScript client library for the Intervals.icu API. Supports all major endpoints including athletes, events, wellness, workouts, and activities.

Features

  • 🚀 Lightweight - Zero dependencies beyond axios
  • 📘 Fully Typed - Written in TypeScript with comprehensive type definitions
  • 🌳 Tree-shakeable - ESM exports for optimal bundle size
  • 🔐 Authentication - Built-in support for API key authentication
  • Rate Limiting Awareness - Tracks and exposes rate limit information
  • 🛡️ Error Handling - Robust error handling with custom error types
  • 📖 Well Documented - JSDoc comments on all public methods

Installation

npm install node-intervals-icu

Quick Start

import { IntervalsClient } from 'node-intervals-icu';

// Initialize the client
const client = new IntervalsClient({
  apiKey: 'your-api-key-here',
  athleteId: 'i12345' // optional, defaults to 'me'
});

// Get athlete information
const athlete = await client.getAthlete();
console.log(`Athlete: ${athlete.name}, FTP: ${athlete.ftp}`);

// Get events
const events = await client.getEvents({
  oldest: '2024-01-01',
  newest: '2024-12-31'
});

// Create a wellness entry
await client.createWellness({
  date: '2024-01-15',
  weight: 70,
  restingHR: 50,
  sleepSecs: 28800
});

API Reference

Client Configuration

interface IntervalsConfig {
  apiKey: string;        // Required: Your Intervals.icu API key
  athleteId?: string;    // Optional: Athlete ID (defaults to 'me')
  baseURL?: string;      // Optional: API base URL
  timeout?: number;      // Optional: Request timeout in ms (default: 10000)
}

Athlete Methods

getAthlete(athleteId?: string): Promise<Athlete>

Get athlete information.

const athlete = await client.getAthlete();
console.log(athlete.name, athlete.ftp, athlete.weight);

updateAthlete(data: Partial<Athlete>, athleteId?: string): Promise<Athlete>

Update athlete information.

const updated = await client.updateAthlete({
  ftp: 250,
  weight: 70
});

Event Methods

getEvents(options?: PaginationOptions, athleteId?: string): Promise<Event[]>

Get calendar events.

const events = await client.getEvents({
  oldest: '2024-01-01',
  newest: '2024-12-31'
});

getEvent(eventId: number, athleteId?: string): Promise<Event>

Get a specific event by ID.

const event = await client.getEvent(12345);

createEvent(data: EventInput, athleteId?: string): Promise<Event>

Create a new calendar event.

const event = await client.createEvent({
  start_date_local: '2024-01-15',
  name: 'Race Day',
  category: 'RACE',
  description: 'Important race'
});

updateEvent(eventId: number, data: Partial<EventInput>, athleteId?: string): Promise<Event>

Update an existing event.

await client.updateEvent(12345, {
  name: 'Updated Race Day'
});

deleteEvent(eventId: number, athleteId?: string): Promise<void>

Delete an event.

await client.deleteEvent(12345);

Wellness Methods

getWellness(options?: PaginationOptions, athleteId?: string): Promise<Wellness[]>

Get wellness data.

const wellness = await client.getWellness({
  oldest: '2024-01-01',
  newest: '2024-01-31'
});

createWellness(data: WellnessInput, athleteId?: string): Promise<Wellness>

Create a new wellness entry.

const wellness = await client.createWellness({
  date: '2024-01-15',
  weight: 70,
  restingHR: 50,
  hrv: 65,
  sleepSecs: 28800,
  sleepQuality: 8
});

updateWellness(date: string, data: Partial<WellnessInput>, athleteId?: string): Promise<Wellness>

Update a wellness entry for a specific date.

await client.updateWellness('2024-01-15', {
  weight: 69.5,
  mood: 8
});

deleteWellness(date: string, athleteId?: string): Promise<void>

Delete a wellness entry.

await client.deleteWellness('2024-01-15');

Workout Methods

getWorkouts(options?: PaginationOptions, athleteId?: string): Promise<Workout[]>

Get planned workouts.

const workouts = await client.getWorkouts({
  oldest: '2024-01-01',
  newest: '2024-01-31'
});

getWorkout(workoutId: number, athleteId?: string): Promise<Workout>

Get a specific workout by ID.

const workout = await client.getWorkout(12345);

createWorkout(data: WorkoutInput, athleteId?: string): Promise<Workout>

Create a new workout.

const workout = await client.createWorkout({
  start_date_local: '2024-01-15',
  name: 'Tempo Run',
  description: '45 min tempo at threshold',
  duration_secs: 2700,
  tss: 65
});

updateWorkout(workoutId: number, data: Partial<WorkoutInput>, athleteId?: string): Promise<Workout>

Update an existing workout.

await client.updateWorkout(12345, {
  name: 'Updated Tempo Run',
  tss: 70
});

deleteWorkout(workoutId: number, athleteId?: string): Promise<void>

Delete a workout.

await client.deleteWorkout(12345);

Activity Methods

getActivities(options?: PaginationOptions, athleteId?: string): Promise<Activity[]>

Get recorded activities.

const activities = await client.getActivities({
  oldest: '2024-01-01',
  newest: '2024-01-31'
});

getActivity(activityId: number, athleteId?: string): Promise<Activity>

Get a specific activity by ID.

const activity = await client.getActivity(12345);

updateActivity(activityId: number, data: ActivityInput, athleteId?: string): Promise<Activity>

Update an existing activity.

await client.updateActivity(12345, {
  name: 'Morning Run',
  description: 'Easy recovery run',
  feel: 8
});

deleteActivity(activityId: number, athleteId?: string): Promise<void>

Delete an activity.

await client.deleteActivity(12345);

Rate Limiting

The client automatically tracks rate limit information from the API responses:

// Make some API calls
await client.getAthlete();

// Check rate limit status
const remaining = client.getRateLimitRemaining();
const resetTime = client.getRateLimitReset();

console.log(`Remaining: ${remaining}, Resets at: ${resetTime}`);

Error Handling

The client throws IntervalsAPIError for all API-related errors:

import { IntervalsClient, IntervalsAPIError } from 'node-intervals-icu';

try {
  const athlete = await client.getAthlete();
} catch (error) {
  if (error instanceof IntervalsAPIError) {
    console.error(`API Error: ${error.message}`);
    console.error(`Status: ${error.status}`);
    console.error(`Code: ${error.code}`);
    
    // Handle specific error types
    if (error.code === 'RATE_LIMIT_EXCEEDED') {
      console.error('Rate limit exceeded, try again later');
    } else if (error.code === 'AUTH_FAILED') {
      console.error('Invalid API key');
    }
  }
}

TypeScript Support

All methods and responses are fully typed. Import types as needed:

import type {
  Athlete,
  Event,
  Wellness,
  Workout,
  Activity,
  PaginationOptions,
  IntervalsConfig
} from 'node-intervals-icu';

Authentication

To get your API key:

  • Log in to Intervals.icu
  • Go to Settings → API Key
  • Copy your API key

Your athlete ID can be found in the URL when viewing your profile (e.g., i12345), or you can use 'me' to refer to the authenticated athlete.

License

MIT License - Copyright (c) 2025 Fernando Paladini

See the LICENSE file for details.

Acknowledgments

Special thanks to Filipe Ronzani for the inspiration and the initial idea that led to the creation of this library. Your project was the spark that made this happen! 🙏

Contributing

Contributions are welcome! Please read our Contributing Guide to learn how you can help make this project better.

Publishing

For maintainers: See the Publishing Guide for detailed instructions on publishing this library to NPM.

Keywords

intervals.icu

FAQs

Package last updated on 11 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts