Zwift Workout Editor can build a workout from plain text, one block per line, like this:
warmup 45%-70% 10m
steady 88% 20m 90rpm
interval 5x 3m-2m 105%-55%
message "Last one!" 52m
cooldown 65%-45% 5m
You can type it in the editor's text editor (the pencil button), or put it in a link that opens the workout in the editor, ready to edit, save and download as a .zwo file for Zwift.
Open a workout with a link
https://www.zwiftworkout.com/editor/new?text=WORKOUT_TEXT
text: the workout, URL-encoded. Lines are separated by newlines (%0A).sport=run: a running workout. Leave it out for cycling.duration=time: a running workout measured in time rather than distance. Running workouts are distance-based unless you add it; cycling workouts are always time-based.
The link opens a new, unsaved workout with the text shown in the text editor, so any line that wasn't understood can be fixed. Up to 4,000 characters.
Examples
- 45 minute sweet spot ride
- Time-based run with 90-second recoveries
- Distance-based run with 400 m repeats
Encoding the text
Encode the text the way encodeURIComponent does: a space is %20, a newline %0A, % is %25 and " is %22. For example steady 88% 20m becomes steady%2088%25%2020m.
Cycling workouts
One block per line:
steady <power> <duration>, e.g.steady 65% 10mwarmup <start>-<end> <duration>, e.g.warmup 45%-70% 10mcooldown <start>-<end> <duration>, e.g.cooldown 65%-45% 5mramp <start>-<end> <duration>, e.g.ramp 70%-90% 6minterval <N>x <on>-<off> <on power>-<off power>, e.g.interval 5x 180s-120s 105%-55%freeride <duration>, e.g.freeride 10mmessage "<text>" <time from the start of the workout>, e.g.message "Last one!" 40m
Power is a whole percentage of FTP, e.g. 75% (watts like 200w and 2.5wkg also work, using the FTP and weight set in the editor). Zones: Z1 below 55%, Z2 56–75%, Z3 76–90%, Z4 91–105%, Z5 106–120%, Z6 above 120%.
Duration is seconds (30s), whole minutes (10m) or minutes and seconds (1:30m). There are no hours: write 60m, not 1h.
Intervals: give both durations in the same unit, e.g. 30s-30s or 3m-2m. Mixed units can be misread: 120s-3m is read as 3 minutes on, 3 minutes off.
Cadence is optional: 90rpm on a steady block or ramp, 100rpm-85rpm (work-recovery) on intervals.
Running workouts
The same blocks, with freerun instead of freeride. Instead of FTP, intensity is a whole percentage of a reference pace, followed by the reference:
1M(one mile),5K,10K,HM(half marathon) orM(marathon), e.g.85%HM.- On ramps and intervals the reference follows the second value only:
60%-80%HM,interval 6x 60s-90s 105%-70%5K. - Easy running is roughly 75–85%HM, threshold about 100%HM and VO2max 105–115%5K.
Time-based runs (duration=time) use durations as for cycling, e.g. steady 80%HM 20m.
Distance-based runs (the default) use distances: kilometres (2km, 0.4km) or metres (400m), e.g. steady 80%HM 5km, interval 6x 0.4km-0.4km 105%-70%5K. Both interval distances must use the same unit. Messages are placed by distance from the start: message "Halfway!" 5km. Kilometres are safest: a distance in metres can be mistaken for the 1M pace.
The editor's pace for each reference comes from the runner's target times, which they enter in the editor.
Messages
message "<text>" <position> shows a text message in Zwift at that time (or distance) from the start of the workout. A + or - before the position makes it relative to the block above: +30s from its start, -10s before its end.