Skip to content

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.

Getting Started Playground


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.

    Getting started

  • Parameterized

    Workouts reference athlete parameters like FTP or max heart rate. One template works for any athlete.

    Parameter references

  • Four intensity shapes

    Constant targets, ranges, ramps, and zones. Covers steady state, target bands, and progressive efforts.

    Intensity shapes

  • Multiple intensity quantities

    Power, speed, heart rate, RPE (CR-10 and Borg scales).

    Adding intensity

  • Export to Garmin and Intervals.icu

    With a Python library and CLI.

  • JSON Schema

    Validate documents without the Python library. Use any language.

    JSON Schema

  • 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:

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

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


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.