A workout schema built for developers.¶
Structured Workout Format (SWF) is a JSON format for structured workouts. One schema, four content types, clear field names. Define a workout once, export to Garmin, SweatStack, Intervals.icu, or any platform you integrate next.
Norwegian 6x6: 6x6min at 90-100% of threshold, 1min recovery:
{
"sport": "cycling",
"title": "Norwegian 6x6",
"content": [
{
"type": "repeat",
"count": 6,
"content": [
{
"type": "step",
"volume": { "type": "constant", "quantity": "duration", "value": 360 },
"intensity": {
"type": "range", "quantity": "power",
"min": { "percent": 90, "of": "threshold" },
"max": { "percent": 100, "of": "threshold" }
}
},
{
"type": "step",
"effort": "rest",
"volume": { "type": "constant", "quantity": "duration", "value": 60 }
}
]
}
]
}
Features¶
-
Four content types
Steps, repeats, sections, and notes. Enough to describe any structured workout, simple enough to implement in an afternoon.
-
Parameterized
Workouts reference athlete parameters like FTP or max heart rate. One template works for any athlete.
-
Four intensity shapes
Constant targets, ranges, ramps, and zones. Covers steady state, target bands, and progressive efforts.
-
Multiple intensity quantities
Power, speed, heart rate, RPE (CR-10 and Borg scales).
-
Export to Garmin and Intervals.icu
With a Python library and CLI.
-
JSON Schema
Validate documents without the Python library. Use any language.
-
AI-ready
The format is simple enough that LLMs can read and write it without special training. An agent skill is included for coding assistants that support it.
Design principles¶
-
Simple and opinionated
Small enums, few fields, clear semantics. If a concept needs a paragraph to explain, it probably doesn't belong in the format.
-
+ Endurance-focused
Built for cycling and running. Other sports may follow, but sport-specific concepts like swim strokes or strength exercises are not in scope today.
-
Prescriptive, not reactive
SWF describes what a coach prescribes, not what a device records or executes. It's a plan, not a log.
-
One-way by design
SWF is a source format. You author in SWF and export to platforms. Importing from platform formats back into SWF is not a goal.
-
Self-documenting
Field names and JSON structure should be readable without documentation.
Python library¶
Install the Python reference implementation:
pip install structured-workout-format
swf validate workout.json
swf export garmin workout.json --render '{"ftp": 250}'
swf export intervals-icu workout.json
Validation¶
Use the playground to try SWF in your browser. Paste JSON, pick a conformance example, and see validation results instantly.
For programmatic validation, POST SWF JSON to /api/validate:
curl -s -X POST https://structuredworkoutformat.dev/api/validate \
-H "Content-Type: application/json" \
-d '{"sport": "cycling", "content": []}'
Returns {"valid": true} or:
CORS is enabled. Content-Type must be application/json.
Links¶
SWF is maintained by SweatStack. We built it because every endurance app ends up rebuilding the same workout plumbing: authoring, validation, export to devices. SWF is the format we wished existed. We publish it openly because interchange formats only work when they're shared.