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 Examples 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.

    Curl the examples page

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.