---
url: /docs/api/core/variables/workoutSchema.md
---
[**@kaiord/core**](../README.md)

***

[@kaiord/core](../README.md) / workoutSchema

# Variable: workoutSchema

> `const` **workoutSchema**: `ZodObject`<{ `extensions`: `ZodOptional`<`ZodRecord`<`ZodString`, `ZodUnknown`>>; `name`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `poolLength`: `ZodOptional`<`ZodNumber`>; `poolLengthUnit`: `ZodOptional`<`ZodLiteral`<`"meters"`>>; `sport`: `ZodEnum`<{ `alpine_skiing`: `"alpine_skiing"`; `american_football`: `"american_football"`; `archery`: `"archery"`; `baseball`: `"baseball"`; `basketball`: `"basketball"`; `boating`: `"boating"`; `boxing`: `"boxing"`; `canoeing`: `"canoeing"`; `cricket`: `"cricket"`; `cross_country_skiing`: `"cross_country_skiing"`; `cycling`: `"cycling"`; `dance`: `"dance"`; `disc_golf`: `"disc_golf"`; `diving`: `"diving"`; `driving`: `"driving"`; `e_biking`: `"e_biking"`; `fishing`: `"fishing"`; `fitness_equipment`: `"fitness_equipment"`; `floor_climbing`: `"floor_climbing"`; `flying`: `"flying"`; `generic`: `"generic"`; `geocaching`: `"geocaching"`; `golf`: `"golf"`; `grinding`: `"grinding"`; `hang_gliding`: `"hang_gliding"`; `hiit`: `"hiit"`; `hiking`: `"hiking"`; `hockey`: `"hockey"`; `horseback_riding`: `"horseback_riding"`; `hunting`: `"hunting"`; `ice_skating`: `"ice_skating"`; `inline_skating`: `"inline_skating"`; `jump_rope`: `"jump_rope"`; `jumpmaster`: `"jumpmaster"`; `kayaking`: `"kayaking"`; `kitesurfing`: `"kitesurfing"`; `lacrosse`: `"lacrosse"`; `meditation`: `"meditation"`; `mixed_martial_arts`: `"mixed_martial_arts"`; `mobility`: `"mobility"`; `motor_sports`: `"motor_sports"`; `motorcycling`: `"motorcycling"`; `mountaineering`: `"mountaineering"`; `multisport`: `"multisport"`; `paddling`: `"paddling"`; `para_sport`: `"para_sport"`; `pool_apnea`: `"pool_apnea"`; `racket`: `"racket"`; `rafting`: `"rafting"`; `rock_climbing`: `"rock_climbing"`; `rowing`: `"rowing"`; `rugby`: `"rugby"`; `running`: `"running"`; `sailing`: `"sailing"`; `shooting`: `"shooting"`; `sky_diving`: `"sky_diving"`; `snorkeling`: `"snorkeling"`; `snowboarding`: `"snowboarding"`; `snowmobiling`: `"snowmobiling"`; `snowshoeing`: `"snowshoeing"`; `soccer`: `"soccer"`; `stand_up_paddleboarding`: `"stand_up_paddleboarding"`; `surfing`: `"surfing"`; `swimming`: `"swimming"`; `tactical`: `"tactical"`; `team_sport`: `"team_sport"`; `tennis`: `"tennis"`; `training`: `"training"`; `transition`: `"transition"`; `video_gaming`: `"video_gaming"`; `volleyball`: `"volleyball"`; `wakeboarding`: `"wakeboarding"`; `wakesurfing`: `"wakesurfing"`; `walking`: `"walking"`; `water_skiing`: `"water_skiing"`; `water_sport`: `"water_sport"`; `water_tubing`: `"water_tubing"`; `wheelchair_push_run`: `"wheelchair_push_run"`; `wheelchair_push_walk`: `"wheelchair_push_walk"`; `windsurfing`: `"windsurfing"`; `winter_sport`: `"winter_sport"`; }>; `steps`: `ZodArray`<`ZodUnion`\<readonly \[`ZodObject`<{ `duration`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `seconds`: ...; `type`: ...; }, `$strip`>, `ZodObject`<{ `meters`: ...; `type`: ...; }, `$strip`>, `ZodObject`<{ `bpm`: ...; `type`: ...; }, `$strip`>, `ZodObject`<{ `bpm`: ...; `repeatFrom`: ...; `type`: ...; }, `$strip`>], `"type"`>; `durationType`: `ZodEnum`<{ `calories`: `"calories"`; `distance`: `"distance"`; `heart_rate_less_than`: `"heart_rate_less_than"`; `open`: `"open"`; `power_greater_than`: `"power_greater_than"`; `power_less_than`: `"power_less_than"`; `repeat_until_calories`: `"repeat_until_calories"`; `repeat_until_distance`: `"repeat_until_distance"`; `repeat_until_heart_rate_greater_than`: `"repeat_until_heart_rate_greater_than"`; `repeat_until_heart_rate_less_than`: `"repeat_until_heart_rate_less_than"`; `repeat_until_power_greater_than`: `"repeat_until_power_greater_than"`; `repeat_until_power_less_than`: `"repeat_until_power_less_than"`; `repeat_until_time`: `"repeat_until_time"`; `time`: `"time"`; }>; `equipment`: `ZodOptional`<`ZodEnum`<{ `none`: `"none"`; `swim_fins`: `"swim_fins"`; `swim_kickboard`: `"swim_kickboard"`; `swim_paddles`: `"swim_paddles"`; `swim_pull_buoy`: `"swim_pull_buoy"`; `swim_snorkel`: `"swim_snorkel"`; }>>; `extensions`: `ZodOptional`<`ZodRecord`<`ZodString`, `ZodUnknown`>>; `intensity`: `ZodOptional`<`ZodEnum`<{ `active`: `"active"`; `cooldown`: `"cooldown"`; `interval`: `"interval"`; `other`: `"other"`; `recovery`: `"recovery"`; `rest`: `"rest"`; `warmup`: `"warmup"`; }>>; `name`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `stepIndex`: `ZodNumber`; `target`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `type`: ...; `value`: ...; }, `$strip`>, `ZodObject`<{ `type`: ...; `value`: ...; }, `$strip`>, `ZodObject`<{ `type`: ...; `value`: ...; }, `$strip`>], `"type"`>; `targetType`: `ZodEnum`<{ `cadence`: `"cadence"`; `heart_rate`: `"heart_rate"`; `open`: `"open"`; `pace`: `"pace"`; `power`: `"power"`; `stroke_type`: `"stroke_type"`; }>; }, `$strip`>, `ZodObject`<{ `id`: `ZodOptional`<`ZodString`>; `repeatCount`: `ZodNumber`; `steps`: `ZodArray`<`ZodObject`<{ `duration`: `ZodDiscriminatedUnion`<..., ...>; `durationType`: `ZodEnum`<...>; `equipment`: `ZodOptional`<...>; `extensions`: `ZodOptional`<...>; `intensity`: `ZodOptional`<...>; `name`: `ZodOptional`<...>; `notes`: `ZodOptional`<...>; `stepIndex`: `ZodNumber`; `target`: `ZodDiscriminatedUnion`<..., ...>; `targetType`: `ZodEnum`<...>; }, `$strip`>>; }, `$strip`>]>>; `subSport`: `ZodOptional`<`ZodEnum`<{ `all`: `"all"`; `apnea_diving`: `"apnea_diving"`; `apnea_hunting`: `"apnea_hunting"`; `atv`: `"atv"`; `backcountry`: `"backcountry"`; `bike_to_run_transition`: `"bike_to_run_transition"`; `bmx`: `"bmx"`; `cardio_training`: `"cardio_training"`; `casual_walking`: `"casual_walking"`; `challenge`: `"challenge"`; `commuting`: `"commuting"`; `cyclocross`: `"cyclocross"`; `downhill`: `"downhill"`; `e_bike_fitness`: `"e_bike_fitness"`; `e_bike_mountain`: `"e_bike_mountain"`; `elliptical`: `"elliptical"`; `exercise`: `"exercise"`; `flexibility_training`: `"flexibility_training"`; `gauge_diving`: `"gauge_diving"`; `generic`: `"generic"`; `gravel_cycling`: `"gravel_cycling"`; `hand_cycling`: `"hand_cycling"`; `indoor_cycling`: `"indoor_cycling"`; `indoor_rowing`: `"indoor_rowing"`; `indoor_running`: `"indoor_running"`; `indoor_skiing`: `"indoor_skiing"`; `indoor_walking`: `"indoor_walking"`; `lap_swimming`: `"lap_swimming"`; `map`: `"map"`; `match`: `"match"`; `mixed_surface`: `"mixed_surface"`; `motocross`: `"motocross"`; `mountain`: `"mountain"`; `multi_gas_diving`: `"multi_gas_diving"`; `navigate`: `"navigate"`; `obstacle`: `"obstacle"`; `open_water`: `"open_water"`; `pilates`: `"pilates"`; `rc_drone`: `"rc_drone"`; `recumbent`: `"recumbent"`; `resort`: `"resort"`; `road`: `"road"`; `run_to_bike_transition`: `"run_to_bike_transition"`; `single_gas_diving`: `"single_gas_diving"`; `skate_skiing`: `"skate_skiing"`; `speed_walking`: `"speed_walking"`; `spin`: `"spin"`; `stair_climbing`: `"stair_climbing"`; `street`: `"street"`; `strength_training`: `"strength_training"`; `swim_to_bike_transition`: `"swim_to_bike_transition"`; `track`: `"track"`; `track_cycling`: `"track_cycling"`; `track_me`: `"track_me"`; `trail`: `"trail"`; `treadmill`: `"treadmill"`; `virtual_activity`: `"virtual_activity"`; `warm_up`: `"warm_up"`; `whitewater`: `"whitewater"`; `wingsuit`: `"wingsuit"`; `yoga`: `"yoga"`; }>>; }, `$strip`>

Defined in: [packages/core/src/domain/schemas/workout.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/3eacbe62ef72342d970523967cc5155b5935bb85/packages/core/src/domain/schemas/workout.ts#L41)

Zod schema for a complete workout definition.

Validates a structured workout with metadata and a sequence of steps
or repetition blocks.

`stepIndex` values on steps are advisory ordering metadata: producers
SHOULD emit 0-based contiguous indices, but the schema deliberately
does not enforce contiguity or uniqueness — adapters renumber steps
when flattening repetition blocks (see the garmin adapter's
flatten-segments converter) and consumers MUST rely on array order,
not on index arithmetic.

`poolLength` is bounded to \[1, 655] meters — generous enough for
endless pools (~5 m) and the FIT protocol envelope, while rejecting
nonsense values like 0.0001 or 99999. KRD always stores pool length
normalized to meters; adapters that accept yard-based pools convert on
ingest (see `length-unit.converter`), so `poolLengthUnit` is fixed to
`"meters"` here rather than carrying the source unit.
