Downloading planned workouts from the API

You can download planned workouts from an athlete’s calendar in zwo (Zwift), fit, mrc and erg format (CALENDAR:READ scope required):

$ curl 'https://intervals.icu/api/v1/athlete/0/events?category=WORKOUT&ext=zwo&resolve=true' \
    -H 'Authorization: Bearer d842c1fc25f241e5ae440d09756448a9'

The optional category parameter specifies what sort of events to return (planned workouts in this case). The ext parameter the format (leave out if you don’t need the file). The resolve=true parameter converts power (and heart rate etc.) from units like % of FTP into watts. The default date range is a week from today (use oldest and newest parameters in ISO-8601 format to change).

Example abridged response:

[
  {
    "id": 46696127,
    "start_date_local": "2024-11-21T07:00:00",
    "type": "Ride",
    "category": "WORKOUT",
    "name": "Big Gear Grinds",
    "description": "...",
    ...
    "workout_doc": {
      "description": "A great session for building cycling specific strength both in and out of the saddle.",
      "target": "POWER",
      "steps": [
        {
          "text": "Welcome to the ...",
          "duration": 180,
          "warmup": true,
          "ramp": true,
          "power": { "start": 35.0,  "end": 55.0, "units": "%ftp" },
          "cadence": { "value": 85.0,  "units": "rpm" },
          "_power": { "value": 126.0,  "start": 98.0, "end": 154.0 }
        },
      ],
      ...
    },
    ...
    "workout_filename": "Big_Gear_Grinds.zwo",
    "workout_file_base64": "PD94bWwgdmVy..."
  }
]

The workout_file_base64 field contains the file in the specified format (zwo in this case) encoded as base 64 text.

The workout_doc field contains the workout in native Intervals.icu format. If you don’t already have a parser for one of the other formats then this might be easier to work with.

This is how the workout_doc field is mapped in Intervals.icu:

public class WorkoutDoc {

    public String description;
    public Map<String, String> description_locale;
    public Integer duration;
    public Float distance;
    public Integer ftp;
    public Integer lthr;
    public Float threshold_pace;    // meters/sec
    public String pace_units;       // SECS_100M, SECS_100Y, MINS_KM, MINS_MILE, SECS_500M
    public SportSettings sportSettings;
    public String category;
    public WorkoutTarget target;
    public List<Step> steps;
    public List<Object> zoneTimes;        // sometimes array of ints otherwise array of objects
    public Map<String, String> options;
    public List<String> locales;

    public enum Option {
        category, pool_length, power
    }

    public static class Step {
        public String text;
        public Map<String, String> text_locale;
        public Integer duration;
        public Float distance;
        public Boolean until_lap_press;
        public Integer reps;
        public Boolean warmup;
        public Boolean cooldown;
        public String intensity;    // "active", "rest", "warmup", "cooldown", "recovery", "interval", "other"
        public List<Step> steps;
        public Boolean ramp;
        public Boolean freeride;
        public Boolean maxeffort;
        public Value power;
        public Value hr;
        public Value pace;
        public Value cadence;
        public Boolean hidepower;

        // these are filled in with actual watts, bpm etc. when resolve=true parameter is supplied to the endpoint
        public Value _power;
        public Value _hr;
        public Value _pace;
        public Float _distance;
    }

    public static class Value {
        public Double value;
        public Double start;
        public Double end;
        public String units;
        public String target;
        public Integer mmp_duration;
    }
}

/** How should workouts be performed? Target power, HR or pace? */
public enum WorkoutTarget {
    AUTO("A"), POWER("W"), HR("H"), PACE("P");
}