Skip to content

Structured Workout Format is a JSON format for structured endurance workouts. Define a workout once, export to SweatStack, Garmin, Intervals.icu, or other platforms.

Training platforms all have their own workout formats. SWF sits in the middle as an interchange format, so you can build tools that work across platforms without dealing with each one individually.

{
  "sport": "cycling",
  "title": "Sweet Spot 2x20",
  "content": [
    {
      "type": "repeat",
      "count": 2,
      "content": [
        {
          "type": "step",
          "volume": { "type": "constant", "quantity": "duration", "value": 1200 },
          "intensity": {
            "type": "range", "quantity": "power",
            "min": { "percent": 88, "of": "ftp" },
            "max": { "percent": 93, "of": "ftp" }
          }
        },
        {
          "type": "step",
          "effort": "rest",
          "volume": { "type": "constant", "quantity": "duration", "value": 300 }
        }
      ]
    }
  ]
}

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.

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.
  • Three intensity shapes. Constant targets, ranges, and ramps. Covers steady state, zones, 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.

Get started

SWF is just JSON. Write a document by hand, validate it with the online validator or the JSON Schema, and you're done.

The Python reference implementation adds a CLI, export, and introspection:

pip install structured-workouts
swf validate workout.json
swf export garmin workout.json --render '{"ftp": 250}'
swf export intervals-icu workout.json

Validation

Use the online validator to check SWF documents in your browser. Paste JSON, pick a conformance example, and see errors 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:

{
  "valid": false,
  "errors": [{"path": "", "message": "must have required property 'sport'"}]
}

CORS is enabled. Content-Type must be application/json.


SWF is developed by SweatStack as a general-purpose format, not tied to any specific platform.