Skip to content

Tempisto JSON format

Tempisto stores workouts as session files and schedules as plan files. Both are JSON and can be written by hand or generated by an AI assistant.

Use with AI

Copy the prompt for Tempisto into an AI assistant. It contains the complete format specification and works without internet access.

Contains the task, the format reference and the examples โ€“ for pasting into an AI assistant.

Format

  • All durations are ISO 8601 strings of the form P[nD][T[nH][nM][nS]]. Years and months are not allowed.
  • Composed announcement fields follow [scope_][aggregate_]metric with scope total/step/split/lap, aggregate avg/max/min/remaining and metric time/distance/pace/speed/power/cadence/heart_rate/elevation. Standalone fields are step_name, step_target, target_deviation, countdown, distance_source, step_duration, next_step, go, average_speed.
  • session file โ€” .session.json
    • format โ€” "tempisto.session/1" ( required )
    • name โ€” string ( required )
    • sport โ€” string ( optional ) โ€” optional, default "running"
    • notes โ€” string ( optional )
    • steps โ€” array ( required ) โ€” at least one step or repeat block
      • step โ€” object โ€” one step
        • type โ€” string ( required ) โ€” one of "warmup", "work", "recovery", "cooldown", "rest"
        • name โ€” string ( optional )
        • duration โ€” object ( required )
          • time โ€” string โ€” ISO 8601 duration string, e.g. "PT15M", "PT2M30S", "PT10S"
          • distance โ€” object
            • value โ€” number ( required )
            • unit โ€” "m" | "km" | "mi" ( required )
          • until โ€” object โ€” the cap "maxTime" (ISO duration) or "maxDistance" (distance object) is required
            • metric โ€” string ( required ) โ€” one of "power", "pace", "speed", "heart_rate", "cadence"
            • below | above โ€” number ( required ) โ€” use exactly one of "below" or "above"
            • for โ€” string ( optional ) โ€” ISO 8601 duration string, e.g. "PT15M", "PT2M30S", "PT10S"
            • maxTime | maxDistance โ€” string | object ( required ) โ€” the cap "maxTime" (ISO duration) or "maxDistance" (distance object) is required
          • lap โ€” boolean โ€” constant: {"lap": true}
        • target โ€” object ( optional ) โ€” one metric as key, e.g. {"power": {"relative": [0.65, 0.75]}}
          • power | pace | speed | heart_rate | cadence โ€” relative: [lower, upper]
        • announce โ€” object ( optional )
          • rules โ€” array โ€” same rule shape as announcements.rules
      • repeat block โ€” object โ€” repeats the inner steps; blocks nest
        • repeat โ€” number ( required ) โ€” number of repetitions, at least 1
        • steps โ€” array ( required ) โ€” list of step objects or repeat blocks
    • announcements โ€” object ( optional )
      • voice โ€” object
        • enabled โ€” boolean
        • rate โ€” number โ€” number between 0.35 and 0.75, 0.5 is the system default
        • duckOtherAudio โ€” boolean
        • voiceIdentifier โ€” string ( optional )
        • languageCode โ€” string ( optional ) โ€” BCP-47 tag
      • haptics โ€” boolean
      • rules โ€” array โ€” same rule shape as announcements.rules
        • trigger โ€” object ( required ) โ€” exactly one trigger: "every" (distance or time), "on": "step_start" | "step_end" | "target_violation", or "on": "last_seconds" with "at"
        • say โ€” array of string ( required ) โ€” announcement fields; the list must not be empty
        • minInterval โ€” string ( optional ) โ€” ISO 8601 duration string, e.g. "PT15M", "PT2M30S", "PT10S"
    • modifiedEpochMillis โ€” number ( optional ) โ€” epoch milliseconds, written by the editors, optional for hand-written files
    • archived โ€” boolean ( optional ) โ€” keeps the file on disk and referenced by plans, only removes it from the pickers
  • plan file โ€” .plan.json
    • format โ€” "tempisto.plan/1" ( required )
    • name โ€” string ( required )
    • starts โ€” string ( required ) โ€” date as YYYY-MM-DD
    • entries โ€” array ( required )
      • session โ€” string ( required ) โ€” file name of a session file
      • rrule | date โ€” string ( required ) โ€” exactly one of rrule (iCal recurrence rule, e.g. "FREQ=WEEKLY;BYDAY=MO,WE;COUNT=16") or date

Examples

5x1000.session.json
                  {
  "format": "tempisto.session/1",
  "name": "5 ร— 1000 m @ CP",
  "sport": "running",
  "notes": "Keep the recoveries honest.",
  "steps": [
    {
      "type": "warmup",
      "duration": { "time": "PT15M" },
      "target": { "power": { "relative": [0.65, 0.75] } }
    },
    {
      "repeat": 5,
      "steps": [
        {
          "type": "work",
          "name": "1000 m",
          "duration": { "distance": { "value": 1000, "unit": "m" } },
          "target": { "power": { "relative": [0.98, 1.02] } },
          "announce": { "rules": [
            { "on": "step_start", "say": ["step_name", "step_target"] },
            { "on": "last_seconds", "at": "PT10S", "say": ["countdown"] },
            { "on": "step_end", "say": ["step_avg_power", "step_time"] }
          ] }
        },
        {
          "type": "recovery",
          "duration": { "until": { "metric": "heart_rate", "below": 130,
                                   "for": "PT10S" },
                        "maxTime": "PT3M" }
        }
      ]
    },
    { "type": "cooldown", "duration": { "time": "PT10M" } }
  ],
  "announcements": {
    "voice": { "enabled": true, "rate": 0.5, "duckOtherAudio": true },
    "haptics": true,
    "rules": [
      { "every": { "distance": { "value": 500, "unit": "m" } },
        "say": ["split_avg_pace", "total_distance"] },
      { "every": { "time": "PT5M" }, "say": ["total_avg_power", "total_time"] },
      { "on": "target_violation", "say": ["target_deviation"],
        "minInterval": "PT20S" }
    ]
  }
}
                
base-build.plan.json
                  {
  "format": "tempisto.plan/1",
  "name": "Base build, 8 weeks",
  "starts": "2026-08-10",
  "entries": [
    { "session": "easy-45.session.json",
      "rrule": "FREQ=WEEKLY;BYDAY=MO,WE;COUNT=16" },
    { "session": "5x1000.session.json",
      "rrule": "FREQ=WEEKLY;BYDAY=TU;COUNT=8" },
    { "session": "long-run.session.json",
      "rrule": "FREQ=WEEKLY;BYDAY=SU;COUNT=8" },
    { "session": "benchmark.session.json", "date": "2026-10-04" }
  ]
}