Program Collection Spec v1.6

Build comprehensive workout programs for Intrvl. Create single workouts or multi-week training plans, distribute via simple file sharing, and let athletes import them directly into the app.

Overview

The Intrvl Program Collection Spec v1.6 enables coaches and developers to create structured workout programs in JSON format. Programs can contain:

This spec is for structured workout programs (collections of workouts with exercises and prescribed sets). For standalone exercise import/export, see the Exercise Spec. For exported training history data (sessions, sets, analytics), see the History Export Spec.

Version 1.6 is fully backward compatible with versions 1.0, 1.1, 1.2, 1.3, and 1.5. All existing program files remain valid without modification.

Two Ways to Use Programs:

  • Quick Start: Athletes pick a workout and it instantly drops into today's session
  • Schedule: Athletes assign workouts to specific dates for planned training

What's New in v1.6

Version 1.6 introduces Set Intent Markers — the ability to pre-mark sets as warm-up or failure sets directly in JSON programs:

This enables coaches to specify set intent directly in programs, improving workout analytics accuracy out of the box.

App UI Behavior: When a program with v1.6 set intent markers is imported:

  • Planned warm-up sets display an orange "W" badge and use orange-tinted styling
  • Planned failure sets display a bolt (⚡) icon
  • When logging a planned set, the warm-up and failure toggles are pre-filled from the program
  • Users can still override these flags when actually logging the set

Migration from v1.5: No changes required! Existing programs work without modification. To take advantage of v1.6 features, add isWarmUp: true to warm-up sets and toFailure: true to failure sets, then update the version to 1.6.

Previous: v1.5 Features

Version 1.5 introduced powerful features for exercise definition and tracking:

Program Structure

A program file is a JSON object with the following top-level structure:

{
  "collectionName": "String",
  "version": 1.6,
  "author": "String (optional)",
  "authorLogoUrl": "String (optional)",
  "description": "String (optional)",
  "tags": ["String"] (optional),
  "workouts": [
    { /* Workout objects */ }
  ]
}

Required Fields

Optional Fields

Important: The version field must be a number (Double), not a string. Use "version": 1.5, NOT "version": "1.5". This is a strict requirement for the JSON parser.

Workout Schema

Each workout object in the workouts array has this structure:

{
  "id": "unique-string-id (optional)",
  "workoutName": "String",
  "description": "String (optional)",
  "restDefault": Number (optional),
  "exercises": [
    { /* Exercise objects */ }
  ]
}

Workout Fields

Important: The id field (added in v1.2) should be unique across all workouts in the program file if you plan to use scheduling features. If omitted, the system will auto-generate a unique ID.

Exercise Schema

Each exercise object defines a movement with its parameters:

{
  "name": "String (required)",
  "muscleGroups": "String, Array, or Object (optional)",
  "muscleGroup": "String (optional, legacy)",
  "capabilities": ["String"] (optional),
  "exerciseType": "String (optional, legacy)",
  "equipment": "String or Array (optional)",
  "defaultResistance": "String (optional)",
  "doublesVolume": Boolean (optional),
  "description": "String (optional)",
  "sets": [Set] (optional),
  "source": Object (optional)
}

Exercise Fields

Capabilities (v1.5)

The capabilities array allows exercises to support combined metric types. If both capabilities and exerciseType are provided, capabilities takes precedence.

Valid Capability Values

Common Capability Combinations

Volume Calculation Priority: When weight is present, volume is calculated using this priority:

  1. weight × distance (loaded carries) — if both weight and distance > 0
  2. (bodyweight + weight) × reps (weighted bodyweight) — if bodyweightVolume + weight + reps
  3. weight × reps (traditional) — if both weight and reps > 0
  4. bodyweight × reps (bodyweight or banded bodyweight) — if bodyweightVolume + reps only
  5. weight × duration (timed loaded) — if both weight and duration > 0
  6. 0 — (no volume for pure banded, distance-only, or timed-only)

Muscle Groups (v1.5)

Version 1.5 introduces hierarchical muscle group targeting for detailed tracking and analytics.

Format Options

Legacy (v1.0-v1.3): Single string or flat array

{
  "muscleGroup": "Legs"
}
// or
{
  "muscleGroups": ["Legs", "Core"]
}

v1.5 Hierarchical: Object with primary/secondary breakdown

{
  "muscleGroups": {
    "primary": {
      "Legs": ["Glutes", "Quads"],
      "Back": ["Lats", "Lower Back"]
    },
    "secondary": {
      "Core": ["Abs"],
      "Arms": ["Forearms"]
    }
  }
}

Primary/Secondary Assignment Rule: In the v1.5 implementation, the primary/secondary designation is applied at the parent category level, not individual child muscles. If a parent category (e.g., "Legs") is designated as primary, ALL selected children under that parent are treated as primary.

Parent Categories and Child Muscles

Import Behavior: Legacy format (string or array) automatically assigns all children of specified parents. v1.5 hierarchical format uses specified children only. Unknown children are created as custom muscle groups under the parent.

Set Schema

Each set object within an exercise defines the parameters for that set. v1.5 Change: Sets can now have multiple metrics (e.g., reps AND distance for shuttle runs, or weight AND distance for loaded carries).

{
  "reps": Number (optional),
  "duration": Number (optional),
  "durationUnit": "String (optional)",
  "distance": Number (optional),
  "distanceUnit": "String (optional)",
  "suggestedWeight": Number (optional),
  "resistance": "String (optional)",
  "bandWeight": Number (optional),
  "bandWeightUnit": "String (optional)",
  "isWarmUp": Boolean (optional, v1.6),
  "toFailure": Boolean (optional, v1.6)
}

Set Fields

Important: reps and duration are mutually exclusive. However, sets can now have multiple metrics (e.g., reps + distance for shuttle runs, or weight + distance for loaded carries).

v1.6 Set Intent Markers: Use isWarmUp: true to mark warm-up sets (excluded from effective volume) and toFailure: true to mark failure sets (1.5x volume multiplier). These flags improve analytics accuracy when the program is imported.

Workout Identification

In v1.2, each workout can have a unique id field for scheduling and tracking purposes:

Using Workout IDs

Example: Workout with ID for Scheduling

{
  "id": "week1-upper",
  "workoutName": "Week 1 - Upper Body",
  "description": "Push and pull movements",
  "restDefault": 90,
  "exercises": [...]
}

Example: Workout without ID (Auto-Generated)

{
  "workoutName": "Upper Body Power",
  "description": "Heavy compound movements",
  "exercises": [...]
}

Complete Examples

Example 1: Simple Strength Program (V1.0)

{
  "collectionName": "StrongLifts 5×5 — Sample Pack",
  "version": 1.0,
  "author": "Open Source Example",
  "description": "The classic 5×5 strength program",
  "tags": ["5x5", "full body", "strength", "beginner"],
  "workouts": [
    {
      "workoutName": "Workout A",
      "description": "Squat, Bench Press, Barbell Row",
      "restDefault": 180,
      "exercises": [
        {
          "name": "Squat",
          "muscleGroup": "Legs",
          "equipment": "Barbell",
          "sets": [
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 }
          ]
        },
        {
          "name": "Bench Press",
          "muscleGroup": "Chest",
          "equipment": "Barbell",
          "sets": [
            { "reps": 5, "suggestedWeight": 40 },
            { "reps": 5, "suggestedWeight": 40 },
            { "reps": 5, "suggestedWeight": 40 },
            { "reps": 5, "suggestedWeight": 40 },
            { "reps": 5, "suggestedWeight": 40 }
          ]
        },
        {
          "name": "Barbell Row",
          "muscleGroup": "Back",
          "equipment": "Barbell",
          "sets": [
            { "reps": 5, "suggestedWeight": 50 },
            { "reps": 5, "suggestedWeight": 50 },
            { "reps": 5, "suggestedWeight": 50 },
            { "reps": 5, "suggestedWeight": 50 },
            { "reps": 5, "suggestedWeight": 50 }
          ]
        }
      ]
    },
    {
      "workoutName": "Workout B",
      "description": "Squat, Overhead Press, Deadlift",
      "restDefault": 180,
      "exercises": [
        {
          "name": "Squat",
          "muscleGroup": "Legs",
          "equipment": "Barbell",
          "sets": [
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 },
            { "reps": 5, "suggestedWeight": 60 }
          ]
        },
        {
          "name": "Overhead Press",
          "muscleGroup": "Shoulders",
          "equipment": "Barbell",
          "sets": [
            { "reps": 5, "suggestedWeight": 30 },
            { "reps": 5, "suggestedWeight": 30 },
            { "reps": 5, "suggestedWeight": 30 },
            { "reps": 5, "suggestedWeight": 30 },
            { "reps": 5, "suggestedWeight": 30 }
          ]
        },
        {
          "name": "Deadlift",
          "muscleGroup": "Legs",
          "equipment": "Barbell",
          "sets": [
            { "reps": 5, "suggestedWeight": 80 }
          ]
        }
      ]
    }
  ]
}

Example 2: Bodyweight & Core Program (V1.1)

{
  "collectionName": "Bodyweight & Core Essentials",
  "version": 1.1,
  "author": "Intrvl Team",
  "description": "Bodyweight and core program with timed holds",
  "tags": ["bodyweight", "core", "home", "no-equipment"],
  "workouts": [
    {
      "workoutName": "Core Foundations",
      "description": "Core stability and strength with timed holds",
      "restDefault": 60,
      "exercises": [
        {
          "name": "Plank",
          "muscleGroup": "Core",
          "equipment": null,
          "sets": [
            { "duration": 30, "durationUnit": "seconds", "resistance": "bodyweight" },
            { "duration": 45, "durationUnit": "seconds", "resistance": "bodyweight" },
            { "duration": 60, "durationUnit": "seconds", "resistance": "bodyweight" }
          ]
        },
        {
          "name": "Push-ups",
          "muscleGroup": "Chest",
          "equipment": null,
          "sets": [
            { "reps": 20, "resistance": "bodyweight" },
            { "reps": 15, "resistance": "bodyweight" },
            { "reps": 12, "resistance": "bodyweight" }
          ]
        },
        {
          "name": "Band Pull-Aparts",
          "muscleGroup": "Back",
          "equipment": "Resistance Band",
          "sets": [
            { "reps": 15, "resistance": "light" },
            { "reps": 15, "resistance": "medium" },
            { "reps": 12, "resistance": "heavy" }
          ]
        }
      ]
    }
  ]
}

Example 3: Scheduled Program with IDs (V1.2)

This example uses v1.2 features. See Example 4 for v1.5 capabilities.

{
  "collectionName": "4-Week Upper/Lower Split",
  "version": 1.2,
  "author": "Intrvl Coach",
  "description": "Structured 4-week program with unique workout IDs for scheduling",
  "tags": ["upper-lower", "intermediate", "hypertrophy"],
  "workouts": [
    {
      "id": "week1-upper-a",
      "workoutName": "Week 1 - Upper Body A",
      "description": "Push and pull movements",
      "restDefault": 90,
      "exercises": [
        {
          "name": "Bench Press",
          "muscleGroup": "Chest",
          "equipment": "Barbell",
          "sets": [
            { "reps": 8, "suggestedWeight": 70 },
            { "reps": 8, "suggestedWeight": 70 },
            { "reps": 8, "suggestedWeight": 70 },
            { "reps": 8, "suggestedWeight": 70 }
          ]
        },
        {
          "name": "Cable Row",
          "muscleGroup": "Back",
          "equipment": "Cable",
          "sets": [
            { "reps": 10, "suggestedWeight": 50 },
            { "reps": 10, "suggestedWeight": 50 },
            { "reps": 10, "suggestedWeight": 50 },
            { "reps": 10, "suggestedWeight": 50 }
          ]
        }
      ]
    },
    {
      "id": "week1-lower-a",
      "workoutName": "Week 1 - Lower Body A",
      "description": "Squat and hinge patterns",
      "restDefault": 120,
      "exercises": [
        {
          "name": "Back Squat",
          "muscleGroup": "Legs",
          "equipment": "Barbell",
          "sets": [
            { "reps": 8, "suggestedWeight": 100 },
            { "reps": 8, "suggestedWeight": 100 },
            { "reps": 8, "suggestedWeight": 100 },
            { "reps": 8, "suggestedWeight": 100 }
          ]
        },
        {
          "name": "Romanian Deadlift",
          "muscleGroup": "Legs",
          "equipment": "Barbell",
          "sets": [
            { "reps": 10, "suggestedWeight": 80 },
            { "reps": 10, "suggestedWeight": 80 },
            { "reps": 10, "suggestedWeight": 80 }
          ]
        }
      ]
    }
  ]
}

Example 4: v1.6 Program with Set Intent Markers

{
  "collectionName": "Strength Program with Intent Markers",
  "version": 1.6,
  "author": "Intrvl Team",
  "description": "Demonstrates v1.6 warm-up and failure set markers",
  "tags": ["example", "v1.6", "strength"],
  "workouts": [
    {
      "id": "squat-day",
      "workoutName": "Squat Day",
      "description": "2 warm-up sets, 3 working sets, final set to failure",
      "restDefault": 180,
      "exercises": [
        {
          "name": "Barbell Back Squat",
          "capabilities": ["weight", "reps"],
          "muscleGroups": {
            "primary": { "Legs": ["Quads", "Glutes", "Hamstrings"] },
            "secondary": { "Core": ["Abs"] }
          },
          "equipment": ["Barbell", "Squat Rack"],
          "sets": [
            { "reps": 10, "suggestedWeight": 20, "isWarmUp": true },
            { "reps": 8, "suggestedWeight": 40, "isWarmUp": true },
            { "reps": 5, "suggestedWeight": 80 },
            { "reps": 5, "suggestedWeight": 80 },
            { "reps": 5, "suggestedWeight": 80, "toFailure": true }
          ]
        }
      ]
    }
  ]
}

Analytics Impact:

  • Sets 1-2 (warm-up): Excluded from effective volume calculations
  • Sets 3-4 (working): Normal volume calculation (weight × reps)
  • Set 5 (failure): 1.5x volume multiplier (80kg × 5 × 1.5 = 600 effective volume)

Example 5: Full v1.5 Program with Capabilities

{
  "collectionName": "Complete v1.5 Example",
  "version": 1.5,
  "author": "Intrvl Team",
  "description": "Demonstrates all v1.5 features including capabilities and hierarchical muscle groups",
  "tags": ["example", "v1.5", "full-featured"],
  "workouts": [
    {
      "id": "push-a",
      "workoutName": "Push Day A",
      "description": "Chest, shoulders and triceps with v1.5 features",
      "restDefault": 120,
      "exercises": [
        {
          "name": "Bench Press",
          "capabilities": ["weight", "reps"],
          "muscleGroups": {
            "primary": { "Chest": ["Middle Chest"] },
            "secondary": { "Arms": ["Triceps"], "Shoulders": ["Front Delts"] }
          },
          "equipment": ["Barbell", "Bench"],
          "sets": [
            { "reps": 8, "suggestedWeight": 60 },
            { "reps": 8, "suggestedWeight": 60 },
            { "reps": 6, "suggestedWeight": 65 }
          ]
        },
        {
          "name": "Pull-ups",
          "capabilities": ["reps", "bodyweightVolume"],
          "muscleGroups": {
            "primary": { "Back": ["Lats"] },
            "secondary": { "Arms": ["Biceps"], "Shoulders": ["Rear Delts"] }
          },
          "equipment": ["Pull-up Bar"],
          "sets": [
            { "reps": 10, "resistance": "bodyweight" },
            { "reps": 8, "resistance": "bodyweight" },
            { "reps": 6, "resistance": "bodyweight" }
          ]
        },
        {
          "name": "Farmer's Walk",
          "capabilities": ["weight", "distance"],
          "muscleGroups": {
            "primary": { "Back": ["Traps"], "Core": ["Abs", "Obliques"] },
            "secondary": { "Arms": ["Forearms"], "Legs": ["Calves"] }
          },
          "equipment": ["Dumbbells"],
          "doublesVolume": true,
          "sets": [
            { "suggestedWeight": 30, "distance": 50, "distanceUnit": "m" },
            { "suggestedWeight": 30, "distance": 50, "distanceUnit": "m" }
          ]
        }
      ]
    }
  ]
}

Distribution & Protection

Distribution Methods

Coaches can distribute programs via:

Protection Mechanisms (Future)

Intrvl is considering optional protection mechanisms for intellectual property:

Note: Protection features are under development. Currently, all programs are distributed as plain JSON files.

Validation & Testing

Required Checks

Before distributing, validate your program file:

  1. JSON syntax — Use a validator like jsonlint.com
  2. Required fields — Ensure all mandatory fields are present
  3. Unique workout IDs — No duplicate workoutId values
  4. Data types — Numbers for sets, restPeriod, etc.
  5. Version field — Must be a number: 1.0, 1.1, 1.2, 1.3, 1.5, or 1.6

Testing Workflow

  1. Create your program JSON file
  2. Validate JSON syntax
  3. Import into Intrvl via the importer
  4. Check that workouts display correctly
  5. Test scheduling (if using targetWeek/targetDay)
  6. Verify exercises, reps, and rest periods

Important: Always test your program file by importing it into Intrvl before distributing to athletes. This ensures formatting is correct and exercises display as intended.

Backward Compatibility

Version 1.6 is fully backward compatible with all previous versions (1.0, 1.1, 1.2, 1.3, 1.5). Existing programs work without modification.

Legacy exerciseType Mapping

Legacy muscleGroup Handling

Migration Guide v1.5 → v1.6: No changes required! To take advantage of v1.6 features: (1) Add isWarmUp: true to warm-up sets (excluded from effective volume), (2) Add toFailure: true to failure sets (1.5x volume multiplier), (3) Update "version" to 1.6.

Migration Guide v1.3 → v1.5: No changes required! To take advantage of v1.5 features: (1) Add "capabilities" array to exercises, (2) Convert "muscleGroup" string to hierarchical "muscleGroups" object, (3) Add "bodyweightVolume" capability for bodyweight volume tracking, (4) Update "version" to 1.5.

Need Help?

Questions about building programs or the specification? Get in touch: