@0x3639/intervals-icu
    Preparing search index...

    Events

    client.events manages the athlete's calendar: creating, updating and deleting planned workouts, notes, races and other calendar entries, individually or across a bulk date range. It also applies training plans to the calendar and downloads planned workouts as files.

    Method What it does
    EventService.listEvents List events for a date range
    EventService.getEvent Get a specific event by ID
    EventService.createEvent Create a new event (workout, note, race, etc.)
    EventService.createEventsBulk Create multiple events at once
    EventService.updateEvent Update an existing event
    EventService.updateEventsRange Update events in a date range (move, shift, etc.)
    EventService.deleteEvent Delete an event
    EventService.deleteEventsBulk Delete events by ID list
    EventService.deleteEventsRange Delete events in a date range by category
    EventService.markEventAsDone Mark an event as done
    EventService.applyPlan Apply a training plan to the calendar
    EventService.duplicateEvents Duplicate events
    EventService.downloadWorkout Download a planned workout from the calendar in zwo, mrc, erg or fit format
    EventService.listEventTags Every tag that has been applied to events on the athlete's calendar
    EventService.listFitnessModelEvents Events that influence the fitness (CTL/ATL) calculation, in ascending date order
    EventService.downloadWorkoutsZip Calendar workouts in a date range as a zip of files in the requested format

    List planned workouts and races in the next 7 days, then list every tag that has been applied to a calendar event.

    const client = new IntervalsClient({ apiKey });

    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 weekAhead = new Date(now);
    weekAhead.setDate(weekAhead.getDate() + 6);
    const oldest = localDate(now);
    const newest = localDate(weekAhead);

    const events = await client.events.listEvents({ oldest, newest, category: ['WORKOUT', 'RACE'] });
    if (events.length === 0) {
    console.log('No workouts or races in the next 7 days');
    } else {
    for (const event of events) {
    console.log(`${event.start_date_local ?? ''} ${event.category ?? ''} ${event.name ?? ''}`);
    }
    }

    const tags = await client.events.listEventTags();
    console.log(tags.length > 0 ? `Event tags: ${tags.join(', ')}` : 'No event tags');

    Create a NOTE event for today, update its description, then delete it.

    CI never runs this example; running it by hand changes the authenticated account. If the create call itself fails after the server committed it, nothing is cleaned up: search the account for Created by the SDK example (or Uploaded by the SDK example) and delete it by hand.

    // maxRetries: 0 — a create that committed before a 5xx would be repeated by a retry, and only the last response's id would be cleaned up.
    const client = new IntervalsClient({ apiKey, maxRetries: 0 });

    // The API keys calendar events by the athlete's local date, not the machine's. A machine
    // in a different time zone (or a CI runner on UTC) would otherwise create the event on the
    // wrong day, so the date is formatted in the athlete's zone (see
    // examples/_shared/local-date.ts).

    const me = await client.athletes.getAthlete();
    const today = localDateIn(new Date(), me.timezone);

    // A unique marker in the name: if the create fails after the server committed it, this
    // is what to search the account for.
    const marker = `Created by the SDK example ${Date.now()}`;

    const event = await client.events.createEvent({
    category: 'NOTE',
    start_date_local: today,
    name: marker,
    });
    if (typeof event.id !== 'number') {
    console.error('The API did not return an id for the created event; it may need deleting by hand.');
    process.exit(1);
    }
    const eventId = event.id;
    console.log(`Created event id=${eventId}`);

    try {
    const updated = await client.events.updateEvent(eventId, { description: 'Edited by the SDK example' });
    console.log(`Updated description: ${updated.description}`);
    } finally {
    await client.events.deleteEvent(eventId);
    console.log(`Deleted event ${eventId}`);
    }

    List the events that influence the fitness (CTL/ATL) calculation, then download the next 30 days of planned workouts as a zip of files.

    const client = new IntervalsClient({ apiKey });

    const events = await client.events.listFitnessModelEvents();
    console.log(`${events.length} fitness-model event(s)`);
    for (const event of events.slice(0, 3)) {
    console.log(`${event.start_date_local ?? ''} ${event.name ?? ''}`);
    }

    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 monthAhead = new Date(now);
    monthAhead.setDate(monthAhead.getDate() + 29);
    const oldest = localDate(now);
    const newest = localDate(monthAhead);

    const upcomingWorkouts = await client.events.listEvents({ oldest, newest, category: ['WORKOUT'] });
    if (upcomingWorkouts.length === 0) {
    console.log('No workout events to zip up in the next 30 days');
    } else {
    const zip = await client.events.downloadWorkoutsZip({ ext: '.zwo', oldest, newest });
    console.log(`Workouts zip: ${zip.length} bytes`);
    }