For the complete documentation index, see llms.txt. This page is also available as Markdown.

Core Concepts

Workout Structure

A workout template is a hierarchy of blocks and steps:

WorkoutTemplate
├── name: "FTP Intervals"
├── sport: "cycling"
├── environment: "outdoor" (optional: indoor, outdoor, pool)
├── description: "Build threshold power"
├── pool_length_meters: null (only for swimming)
├── estimated_duration_seconds: 1800 (optional)
├── estimated_distance_meters: null (optional)
├── estimated_calories: null (optional)
├── estimated_tss: null (optional, 0-9999)
├── estimated_intensity_factor: null (optional, 0-5)
│
└── step_blocks: [
      StepBlock {
        completion_condition: { type: "reps", value: 4 }  ← Repeat 4 times
        steps: [
          WorkoutStep { ... },  ← Do this
          WorkoutStep { ... }   ← Then this
        ]
      }
    ]

Step Blocks

A step block groups one or more steps that execute together. The block's completion_condition controls repetition:

Block Completion
Behavior

{ "type": "reps", "value": 4 }

Repeat all steps 4 times

{ "type": "time", "value": 1200 }

Repeat until 20 minutes total

{ "type": "distance", "value": 5000 }

Repeat until 5km total

{ "type": "open" } or omitted

Execute once (no repeat)

Example: 4x400m Intervals

This creates: 400m fast → 200m easy → 400m fast → 200m easy → 400m fast → 200m easy → 400m fast → 200m easy

Workout Steps

Each step defines:

Field
Required
Description

completion_condition

Yes

When this step ends

intensity_type

Yes

How hard (warmup/active/rest/recovery/cooldown)

intensity_targets

No

Target metrics (HR, power, pace, etc.)

notes

No

Text shown to athlete

controls

No

Equipment settings held during the step: grade or resistance

strength

No

Exercise details for strength training

swimming

No

Stroke/equipment for swimming

Completion Conditions

How a step (or block) ends:

Type
Value
Description

time

Seconds

End after duration (e.g., 300 = 5 minutes)

distance

Meters

End after distance (e.g., 1000 = 1km)

reps

Count

End after N repetitions

calories

kcal

End after calories burned

open

—

Manual end (lap button)

hr_less_than

BPM

End when HR drops below

hr_greater_than

BPM

End when HR rises above

power_less_than

Watts

End when power drops below

power_greater_than

Watts

End when power rises above

Example: Recovery Until HR Drops

Intensity Types

Type
Display
Use For

warmup

Warmup

Gradual start

active

Work / Interval

Main effort

rest

Rest

Full stop between intervals

recovery

Recovery

Easy effort between intervals

cooldown

Cooldown

Gradual end

Intensity Targets

Targets define the goal metric for a step. You can have multiple targets per step (provider-dependent).

Target Types

Absolute Targets:

Target Type
Value Unit
Example
Provider Support

heart_rate

BPM

150-160 BPM

All except Hevy

power

Watts

250-280W

All except Huawei and Hevy

speed

m/s

4.0-4.5 m/s

All except Hevy

pace

sec/km

270-300 sec/km (4:30-5:00/km)

All except Hevy

cadence

rpm or spm

170-180 spm

All except Hevy (Zepp: secondary only)

rpe

1-10

7-8 RPE

Wahoo, TrainingPeaks only

Percentage Targets (require athlete parameters at scheduling):

Target Type
Requires
Example

heart_rate_max_percentage

max_heart_rate

80-85% of max HR

heart_rate_threshold_percentage

threshold_heart_rate

95-100% of threshold

power_percentage

ftp

90-95% of FTP

speed_percentage

threshold_speed

85-90% of threshold pace

Zone Targets (device-configured zones):

Target Type
Value
Provider Support

heart_rate_zone

1-5

All except Hevy (Garmin native, others convert to BPM or %). Uses threshold HR (COROS, Zepp) or max HR (others) as baseline

power_zone

1-7

All except Huawei and Hevy (Garmin native, others convert to % FTP or watts)

Target Value Formats

Targets support single values or ranges. Percentage targets (heart_rate_max_percentage, heart_rate_threshold_percentage, power_percentage, speed_percentage) must use value_low and/or value_high: an exact value is rejected with a 400. Expanding a single value into a range also returns a coercion warning.

Sport Types

Sport
Description
Provider Support

running

Running

All except Hevy

cycling

Cycling

All except Huawei and Hevy

swimming

Swimming

Garmin, COROS, Suunto, TrainingPeaks, Zepp, Apple

strength

Weight training

Garmin, COROS, Suunto, TrainingPeaks, Apple, Hevy

rowing

Rowing

TrainingPeaks, Apple

yoga

Yoga

Garmin, Apple

pilates

Pilates

Garmin only

cardio

General cardio

Garmin only

trail_running

Trail running

Garmin, COROS, Wahoo, Suunto, Zepp

mountain_biking

Mountain biking

Garmin, Wahoo, Suunto, TrainingPeaks

backcountry_skiing

Backcountry / ski touring

Garmin, Suunto

hiking

Hiking

Garmin, Suunto

walking

Walking

Garmin, Suunto, TrainingPeaks

elliptical

Elliptical

Garmin

stair_climbing

Stair climbing

None native, coerced with a warning

Unsupported sport types are coerced to the provider's closest equivalent with a coercion warning. See Provider Compatibility for details.

Environment (Optional)

Use the environment field to distinguish indoor/outdoor variants:

Environment
Description

indoor

Indoor (treadmill, stationary bike, etc.)

outdoor

Outdoor

pool

Pool swimming

If omitted, the provider uses its default. Examples:

Workout Estimates (Optional)

Estimates describe the workout as a whole, not a single step. All five are optional.

Field
Unit
Notes

estimated_duration_seconds

Seconds

Planned total time

estimated_distance_meters

Meters

Planned total distance

estimated_calories

kcal

Planned energy

estimated_tss

0-9999

Planned Training Stress Score

estimated_intensity_factor

0-5

Planned Intensity Factor

Terra forwards all five to TrainingPeaks when the workout is scheduled or rescheduled, and returns them on workouts read back from any provider that exposes them.

TrainingPeaks derives TSS, Intensity Factor and duration from the athlete's own thresholds whenever any step target is not RPE. Your values are ignored in that case, and Terra returns coercion warnings on workout.estimated_tss, workout.estimated_intensity_factor and workout.estimated_duration_seconds. Distance and calories are always forwarded.

An estimated_tss outside 0-9999, or an estimated_intensity_factor outside 0-5, is rejected when the template is created.

Complete Example

A 30-minute cycling workout with warmup, FTP intervals, and cooldown:

Reading Workouts Back

GET /plannedWorkouts?user_id=X returns this same structure. Every item carries the workout body under workout: name, sport, step_blocks and estimates, whether you scheduled it through Terra or the athlete created it on the provider.

Provider-created workouts are marked is_external: true, have no workout_id, and are listed for Garmin, Wahoo, Suunto, TrainingPeaks and Intervals.icu. Their sport is unspecified when the provider's sport has no Terra equivalent. warnings lists anything that could not be represented exactly when the provider's workout was read into this structure. Repeat blocks are preserved.

Intervals.icu is read-only for planned workouts: workouts created there are listed, but Terra cannot push workouts to it.

Without start_date and end_date, provider-created workouts default to the trailing 30 days. Pass an explicit window to list upcoming workouts. When the provider cannot be read the response is still a 200 carrying the workouts Terra scheduled, with X-Terra-Provider-Data-Truncated: true and X-Terra-Provider-Fetch giving the reason.

Validation Rules

Templates are validated when created. Key rules:

Field
Requirement

name

Required, non-empty

sport

Required, must be a valid sport type

step_blocks

At least one block required

Each block

At least one step required

Each step

intensity_type required (warmup, active, rest, recovery, cooldown)

Each step

completion_condition defaults to open if omitted

pool_length_meters

Only allowed for swimming workouts

value_low / value_high

Cannot use both value and value_low/value_high on the same target

Range targets

value_low must be strictly less than value_high

Athlete metrics

All values must be positive if provided (ftp, max_heart_rate, threshold_heart_rate, threshold_speed, pool_length_meters)

planned_date

Format: YYYY-MM-DD

estimated_tss

Between 0 and 9999 if provided

estimated_intensity_factor

Between 0 and 5 if provided

Percentage targets

Must use value_low and/or value_high, not value

Target value sanity checks. A value outside these ranges is rejected with a 400 when the template is created:

Target Type
Valid Range

Heart rate (BPM)

30–250

Power (watts)

1–2000

Speed (m/s)

0–15

Pace (sec/km)

1–7200

Cadence (rpm/spm)

1–300

RPE

1–10

Percentage targets

0–200%

Last updated

Was this helpful?