IronPen

JSON Reference

JSON Reference

Technical documentation of the CustomTemplate format for IronPen. For AI generation, advanced users and developers.

Introduction

A custom template in IronPen is a JSON document describing a complete training program — exercises, sets, weights, schedule and progression. The app generates specific workouts from it based on the user's 1RM maxes.

This document describes every field, validation rules and includes complete examples. You can create the JSON manually, have it generated by AI, or export it from the in-app editor.

Import into IronPen: copy the JSON to clipboard → in the app tap 📋 Import from Clipboard. Or save as a .json file and use 📁 Import from File.

Quick Start

Minimal working template — 1 day, 1 exercise, 1 set:

{
  "version": 1,
  "meta": {
    "id": "muj-prvni-program",
    "nameCs": "Můj první program",
    "nameEn": "My First Program",
    "icon": "💪",
    "tags": ["beginner", "strength"]
  },
  "config": {
    "daysPerWeek": [3],
    "weeksPerCycle": 4,
    "maxCycles": 4,
    "trainingMaxPercent": 0.9,
    "requiredInputs": [{
      "key": "bench1RM",
      "labelCs": "Bench Press 1RM",
      "labelEn": "Bench Press 1RM",
      "type": "WEIGHT_INPUT",
      "defaultValue": 60.0,
      "linkedExerciseId": "bench-press",
      "suffix": "kg"
    }]
  },
  "schedule": {
    "type": "WEEKLY_FIXED",
    "fixedDays": [{
      "dayIndex": 0,
      "labelCs": "Trénink",
      "labelEn": "Workout",
      "exercises": [{
        "exerciseId": "bench-press",
        "exerciseName": "Bench Press",
        "orderIndex": 0,
        "exerciseType": "MAIN",
        "sets": [{
          "reps": "5",
          "setType": "MAIN",
          "weightSource": {
            "type": "PERCENT_TM",
            "value": 0.85,
            "linkedExerciseId": "bench-press"
          },
          "copies": 5
        }]
      }]
    }]
  },
  "progressionRules": []
}

AI Prompt

Copy this entire page (or its URL) into the AI context and add your request. Example prompt:

Vytvoř IronPen custom šablonu (JSON) pro tento program:

- 4 dny/týden (Upper/Lower split)
- 6 týdnů v cyklu
- Hlavní cviky: Squat, Bench, Deadlift, OHP
- Procenta z Training Max (90% z 1RM)
- Wendler-style progrese: +2.5 kg upper, +5 kg lower per cyklus
- Warmup série + 3 pracovní série + BBB 5×10

Použij formát popsaný v JSON Reference dokumentu.
Výsledek musí být validní JSON importovatelný do IronPen.
The more precise your description, the better the result. Specify: number of days, exercises, set scheme (5×5, 3×8...), percentages of 1RM or TM, and type of progression.

Root Object — CustomTemplate

FieldTypeDescription
versionIntSchema version. Always 1.
metaObjectTemplate metadata (name, icon, tags).
configObjectGeneration config (days/week, cycles, TM%).
scheduleObjectSchedule structure (1 of 5 types).
progressionRulesArrayAutomatic progression rules. Empty array = no progression.

meta — TemplateMeta

FieldTypeDescription
idStringUnique ID. Format: username_slug or any. No spaces or special characters.
nameCsStringName in Czech. At least one of nameCs/nameEn must be non-empty.
nameEnStringName in English. If empty, nameCs is used.
descriptionCsStringDescription in Czech.
descriptionEnStringDescription in English.
iconStringEmoji icon. Default: 💪
tagsArray<String>Categories: beginner, intermediate, advanced, strength, hypertrophy, endurance
createdAtLongCreation timestamp (ms). Auto-generated on import.
updatedAtLongLast update timestamp (ms).

config — TemplateGenerationConfig

FieldTypeDescription
daysPerWeekArray<Int>Supported day variants. E.g. [3, 4] = template works for 3 or 4 days/week.
weeksPerCycleIntNumber of weeks per cycle. Default: 4. Range: 1–52.
maxCyclesIntMaximum number of cycles. Default: 6.
trainingMaxPercentFloatTM = 1RM × this value. Default: 0.9 (90%). Range: 0.5–1.0.
weightIncrementFloatWeight rounding. Default: 2.5 kg.
supportsMultipleCyclesBoolAllow multiple cycles. Default: true.
requiredInputsArrayInputs required from the user during generation. See details.
deloadConfigObjectDeload week configuration. See details.
weeklyProgressionObjectIntra-cycle weight progression. See details.

requiredInputs — RequiredInput

Define what values the user enters when generating the program (1RM, KB weight, etc.).

FieldTypeDescription
keyStringUnique key. No spaces. E.g. bench1RM, kbWeight.
labelCsStringLabel in Czech displayed to the user.
labelEnStringLabel in English.
typeEnumWEIGHT_INPUT = free numeric input. WEIGHT_CHOICES = selection from predefined values.
defaultValueFloatDefault value.
choicesArray<Float>Only for WEIGHT_CHOICES. E.g. [8, 12, 16, 20, 24, 32] for KB.
linkedExerciseIdStringExercise ID for auto-fill from user's maxes. E.g. "bench-press".
suffixStringUnit. Default: "kg".

Examples

// 1RM input linked to an exercise
{ "key": "squat1RM", "labelCs": "Dřep 1RM", "labelEn": "Squat 1RM",
  "type": "WEIGHT_INPUT", "defaultValue": 80.0,
  "linkedExerciseId": "back-squat", "suffix": "kg" }

// KB selection without exercise link
{ "key": "tguWeight", "labelCs": "TGU kettlebell", "labelEn": "TGU kettlebell",
  "type": "WEIGHT_CHOICES", "defaultValue": 16.0,
  "choices": [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], "suffix": "kg" }

deloadConfig — DeloadConfig

Optional. Defines an automatic deload week within the cycle.

FieldTypeDescription
deloadWeekIntDeload week number (1-based). 0 = no deload.
deloadMultiplierFloatWeight multiplier. 0.6 = 60% of normal weight. Default: 0.6.
assistanceSetReductionIntHow many sets to reduce for assistance exercises. Default: 0.
{ "deloadWeek": 4, "deloadMultiplier": 0.6, "assistanceSetReduction": 1 }

weeklyProgression — WeeklyWeightProgression

Optional. Intra-cycle progression — weights increase within a cycle (not just between cycles).

FieldTypeDescription
typeEnumNONE | LINEAR_PER_WEEK | LINEAR_PER_N_WEEKS
incrementPerIntervalFloatWeight increment per interval (kg). Default: 2.5.
intervalWeeksIntInterval in weeks (only for LINEAR_PER_N_WEEKS). Default: 2.
// +2.5 kg every 2 weeks
{ "type": "LINEAR_PER_N_WEEKS", "incrementPerInterval": 2.5, "intervalWeeks": 2 }

ExerciseDefinition

FieldTypeDescription
exerciseIdStringExercise ID from the IronPen database. See list.
exerciseNameStringName for offline display. If empty, populated from DB.
orderIndexIntExercise order within the day (0-based).
exerciseTypeEnumMAIN | ASSISTANCE
supersetGroupIdInt?Superset group number. Exercises with the same number form a superset. null = no superset.
isUnilateralBoolUnilateral exercise (reps = per side, tonnage ×2). Default: false.
emomEnabledBoolEMOM mode. Default: false.
emomIntervalSecondsIntEMOM interval. Default: 60.
setsArrayList of set definitions. See SetDefinition.
wavePatternObject?Wave progression for this exercise. See details.
deloadRepsString?Alternative reps for the deload week. E.g. "5" instead of "max".
deloadIsAmrapBool?AMRAP override for deload. E.g. false for pull-ups on deload.

SetDefinition

FieldTypeDescription
repsStringNumber of repetitions. Formats: "5", "5+", "1+1", "8-12", "max".
setTypeStringMAIN | WARMUP | FSL. Default: "MAIN".
weightSourceObjectWhere the weight comes from. See WeightSource.
isAmrapBoolAMRAP set. Default: false.
copiesIntHow many times to repeat this set. Default: 1. Range: 1–20.
copies is a shorthand. {"reps": "5", "copies": 5} is equivalent to five separate sets with reps "5". Useful for 5×5, 3×10, etc.

WeightSourceDefinition

FieldTypeDescription
typeEnumWeight source type. See table below.
valueFloatValue. For PERCENT_TM/1RM: percentage (0.85 = 85%). For FIXED: weight in kg.
keyString?Only for CUSTOM_INPUT: key from requiredInputs.
linkedExerciseIdString?Only for PERCENT_TM/1RM: exerciseId for 1RM lookup.
fromIntensityString?Only for DERIVED: "HEAVY", "MEDIUM", "LIGHT".
multiplierFloatMultiplier. Default: 1.0.

WeightSourceType enum

TypeDescriptionRequired fields
PERCENT_TM% of Training Max (1RM × trainingMaxPercent)value, linkedExerciseId
PERCENT_1RM% directly from 1RMvalue, linkedExerciseId
PERCENT_TOP_SET% of top set (ramp sets)value
FIXEDFixed weight in kgvalue
CUSTOM_INPUTFrom user inputkey
DERIVEDDerived from another day (HLM)fromIntensity, multiplier
BODYWEIGHTBodyweightnone

Examples

// 85% of Training Max for bench press
{ "type": "PERCENT_TM", "value": 0.85, "linkedExerciseId": "bench-press" }

// Fixed 24 kg
{ "type": "FIXED", "value": 24.0 }

// Bodyweight (pull-ups, push-ups)
{ "type": "BODYWEIGHT" }

// From user input "kbWeight"
{ "type": "CUSTOM_INPUT", "key": "kbWeight" }

WavePatternDefinition

Optional on ExerciseDefinition. Gradual introduction of a new weight over N weeks.

FieldTypeDescription
startWeightKeyStringKey from requiredInputs for the starting weight.
targetWeightKeyStringKey from requiredInputs for the target weight.
spreadTypeEnumCENTER_OUT | LEFT_TO_RIGHT | RIGHT_TO_LEFT
transitionWeeksIntNumber of transition weeks. Default: 6.
// TGU: 5 sets, from 16 kg to 20 kg, center out, over 6 weeks
{ "startWeightKey": "tguStartWeight",
  "targetWeightKey": "tguTargetWeight",
  "spreadType": "CENTER_OUT",
  "transitionWeeks": 6 }

WEEKLY_FIXED

Same days every week. The simplest type.

"schedule": {
  "type": "WEEKLY_FIXED",
  "fixedDays": [
    {
      "dayIndex": 0,
      "labelCs": "Push",
      "labelEn": "Push",
      "exercises": [/* ... */]
    },
    {
      "dayIndex": 1,
      "labelCs": "Pull",
      "labelEn": "Pull",
      "exercises": [/* ... */]
    }
  ]
}

ALTERNATING

Alternating variants. The pattern defines the order.

"schedule": {
  "type": "ALTERNATING",
  "alternatingPattern": {
    "pattern": ["A", "B"],
    "templates": {
      "A": { "dayIndex": 0, "labelCs": "Trénink A", "exercises": [/* ... */] },
      "B": { "dayIndex": 1, "labelCs": "Trénink B", "exercises": [/* ... */] }
    }
  }
}
Pattern ["B", "C", "A"] = order B→C→A→B→C→A... Useful when you want the heavy day before the longest rest.

WEEKLY_VARYING

Each week is different. For periodized programs (Wendler, TB Operator).

"schedule": {
  "type": "WEEKLY_VARYING",
  "varyingWeeks": [
    {
      "weekIndex": 0,
      "labelCs": "Týden 1 (3×5)",
      "labelEn": "Week 1 (3×5)",
      "isDeload": false,
      "deloadMultiplier": 1.0,
      "days": [
        { "dayIndex": 0, "labelCs": "OHP", "exercises": [/* 65/75/85% */] },
        { "dayIndex": 1, "labelCs": "Deadlift", "exercises": [/* ... */] }
      ]
    },
    {
      "weekIndex": 3,
      "labelCs": "Deload",
      "isDeload": true,
      "deloadMultiplier": 0.6,
      "days": [/* ... */]
    }
  ]
}

HLM

Heavy/Medium/Light. You define the heavy day, medium and light are derived automatically or manually.

"schedule": {
  "type": "HLM",
  "hlmDefinition": {
    "intensityPattern": ["HEAVY", "LIGHT", "MEDIUM"],
    "heavyDay": {
      "dayIndex": 0,
      "labelCs": "Těžký",
      "exercises": [/* plné váhy */]
    },
    "mediumDayConfig": {
      "intensityMultiplier": 0.85,  // váhy = 85% heavy
      "volumeMultiplier": 0.75,     // série = 75% heavy (4 místo 5)
      "useCustomDay": false
    },
    "lightDayConfig": {
      "intensityMultiplier": 0.70,
      "volumeMultiplier": 0.50,
      "useCustomDay": false
    },
    "customMediumDay": null,  // nebo DayDefinition pokud useCustomDay=true
    "customLightDay": null
  }
}

LADDER_PROGRESSION

Ladder system with weekly progression of rungs and ladders.

"schedule": {
  "type": "LADDER_PROGRESSION",
  "ladderDefinition": {
    "exercises": [
      {
        "exerciseId": "kb-clean-press",
        "exerciseName": "KB Clean & Press",
        "useLadders": true,
        "weightSource": { "type": "CUSTOM_INPUT", "key": "kbWeight" }
      },
      {
        "exerciseId": "pull-ups",
        "useLadders": true,
        "mirrorLaddersOf": "kb-clean-press",
        "weightSource": { "type": "BODYWEIGHT" }
      },
      {
        "exerciseId": "kb-swing",
        "useLadders": false,
        "fixedSets": [{ "reps": "10", "copies": 10,
          "weightSource": { "type": "CUSTOM_INPUT", "key": "kbWeight" } }],
        "fixedSetsMatchLadderCount": false,
        "weightSource": { "type": "CUSTOM_INPUT", "key": "kbWeight" }
      }
    ],
    "weeklyProgression": [
      { "weekIndex": 0, "maxRung": 3, "ladderCount": 3 },
      { "weekIndex": 1, "maxRung": 4, "ladderCount": 4 },
      { "weekIndex": 2, "maxRung": 5, "ladderCount": 5 },
      { "weekIndex": 3, "maxRung": 5, "ladderCount": 5 }
    ],
    "dayIntensity": ["HEAVY", "LIGHT", "MEDIUM"],
    "heavyMediumLightRungOffset": { "medium": -1, "light": -2 }
  }
}
Rung offset: Heavy = full maxRung. Medium = maxRung - 1. Light = maxRung - 2. With maxRung=5: Heavy=5 reps top, Medium=4, Light=3.

progressionRules — ProgressionRuleDefinition

Field on the root object. Array of rules for automatic weight progression.

FieldTypeDescription
exerciseScopeEnumALL_MAIN = all main exercises. SPECIFIC = selected only (see exerciseIds).
exerciseIdsArray<String>Only for SPECIFIC: list of exerciseId.
evaluationTypeEnumPER_WORKOUT = after each workout. PER_CYCLE = after completing a cycle.
successConditionObject{"type": "ALL_MAIN_SETS_COMPLETED", "value": 0}
onSuccessObjectAction on success. {"type": "INCREMENT_WEIGHT", "value": 2.5}
onFailureObjectAction on failure. {"type": "REPEAT_WEIGHT", "value": 0}
onRepeatedFailureObject?Action after N failures. {"failCount": 3, "action": {"type": "DELOAD_PERCENT", "value": 10}}
// StrongLifts: +2.5 kg per workout, deload after 3 failures
{
  "exerciseScope": "SPECIFIC",
  "exerciseIds": ["bench-press", "overhead-press", "barbell-rows"],
  "evaluationType": "PER_WORKOUT",
  "successCondition": { "type": "ALL_MAIN_SETS_COMPLETED", "value": 0 },
  "onSuccess": { "type": "INCREMENT_WEIGHT", "value": 2.5 },
  "onFailure": { "type": "REPEAT_WEIGHT", "value": 0 },
  "onRepeatedFailure": { "failCount": 3, "action": { "type": "DELOAD_PERCENT", "value": 10 } }
}

ActionType enum

TypeDescriptionvalue
NO_CHANGEDo nothingignored
INCREMENT_WEIGHTAdd fixed weight (kg)kg increment (2.5, 5.0)
REPEAT_WEIGHTRepeat same weightignored
DELOAD_PERCENTReduce weight by %percentage reduction (10 = -10%)
INCREMENT_TMIncrease Training Max (per cycle)kg increment on TM
GENERATE_NEXT_CYCLEGenerate next cycleignored

SuccessCondition types

TypeDescription
ALL_MAIN_SETS_COMPLETEDAll MAIN sets completed
ALL_REPS_HITAll planned reps achieved
AMRAP_MINIMUMAMRAP set ≥ value reps

Example: StrongLifts 5×5

Complete template. ALTERNATING A/B, per-workout progression.

{
  "version": 1,
  "meta": {
    "id": "stronglifts-5x5",
    "nameCs": "StrongLifts 5×5", "nameEn": "StrongLifts 5×5",
    "descriptionCs": "Začátečnický program 3× týdně. Střídání A/B.",
    "icon": "🏋️", "tags": ["beginner", "strength"]
  },
  "config": {
    "daysPerWeek": [3], "weeksPerCycle": 4, "maxCycles": 6,
    "trainingMaxPercent": 1.0,
    "requiredInputs": [
      { "key": "squat1RM", "labelCs": "Dřep 1RM", "labelEn": "Squat 1RM",
        "type": "WEIGHT_INPUT", "defaultValue": 60, "linkedExerciseId": "back-squat" },
      { "key": "bench1RM", "labelCs": "Bench 1RM", "labelEn": "Bench 1RM",
        "type": "WEIGHT_INPUT", "defaultValue": 40, "linkedExerciseId": "bench-press" },
      { "key": "row1RM", "labelCs": "Row 1RM", "labelEn": "Row 1RM",
        "type": "WEIGHT_INPUT", "defaultValue": 40, "linkedExerciseId": "barbell-rows" },
      { "key": "ohp1RM", "labelCs": "OHP 1RM", "labelEn": "OHP 1RM",
        "type": "WEIGHT_INPUT", "defaultValue": 30, "linkedExerciseId": "overhead-press" },
      { "key": "dl1RM", "labelCs": "Deadlift 1RM", "labelEn": "Deadlift 1RM",
        "type": "WEIGHT_INPUT", "defaultValue": 80, "linkedExerciseId": "deadlift" }
    ]
  },
  "schedule": {
    "type": "ALTERNATING",
    "alternatingPattern": {
      "pattern": ["A", "B"],
      "templates": {
        "A": {
          "dayIndex": 0, "labelCs": "Trénink A", "labelEn": "Workout A",
          "exercises": [
            { "exerciseId": "back-squat", "orderIndex": 0, "exerciseType": "MAIN",
              "sets": [{ "reps": "5", "weightSource": { "type": "PERCENT_1RM", "value": 0.80, "linkedExerciseId": "back-squat" }, "copies": 5 }] },
            { "exerciseId": "bench-press", "orderIndex": 1, "exerciseType": "MAIN",
              "sets": [{ "reps": "5", "weightSource": { "type": "PERCENT_1RM", "value": 0.80, "linkedExerciseId": "bench-press" }, "copies": 5 }] },
            { "exerciseId": "barbell-rows", "orderIndex": 2, "exerciseType": "MAIN",
              "sets": [{ "reps": "5", "weightSource": { "type": "PERCENT_1RM", "value": 0.80, "linkedExerciseId": "barbell-rows" }, "copies": 5 }] }
          ]
        },
        "B": {
          "dayIndex": 1, "labelCs": "Trénink B", "labelEn": "Workout B",
          "exercises": [
            { "exerciseId": "back-squat", "orderIndex": 0, "exerciseType": "MAIN",
              "sets": [{ "reps": "5", "weightSource": { "type": "PERCENT_1RM", "value": 0.80, "linkedExerciseId": "back-squat" }, "copies": 5 }] },
            { "exerciseId": "overhead-press", "orderIndex": 1, "exerciseType": "MAIN",
              "sets": [{ "reps": "5", "weightSource": { "type": "PERCENT_1RM", "value": 0.80, "linkedExerciseId": "overhead-press" }, "copies": 5 }] },
            { "exerciseId": "deadlift", "orderIndex": 2, "exerciseType": "MAIN",
              "sets": [{ "reps": "5", "weightSource": { "type": "PERCENT_1RM", "value": 0.85, "linkedExerciseId": "deadlift" }, "copies": 1 }] }
          ]
        }
      }
    }
  },
  "progressionRules": [
    { "exerciseScope": "SPECIFIC",
      "exerciseIds": ["back-squat", "bench-press", "barbell-rows", "overhead-press"],
      "evaluationType": "PER_WORKOUT",
      "successCondition": { "type": "ALL_MAIN_SETS_COMPLETED" },
      "onSuccess": { "type": "INCREMENT_WEIGHT", "value": 2.5 },
      "onFailure": { "type": "REPEAT_WEIGHT" },
      "onRepeatedFailure": { "failCount": 3, "action": { "type": "DELOAD_PERCENT", "value": 10 } } },
    { "exerciseScope": "SPECIFIC",
      "exerciseIds": ["deadlift"],
      "evaluationType": "PER_WORKOUT",
      "successCondition": { "type": "ALL_MAIN_SETS_COMPLETED" },
      "onSuccess": { "type": "INCREMENT_WEIGHT", "value": 5.0 },
      "onFailure": { "type": "REPEAT_WEIGHT" },
      "onRepeatedFailure": { "failCount": 3, "action": { "type": "DELOAD_PERCENT", "value": 10 } } }
  ]
}

Example: Wendler 5/3/1 (abbreviated)

WEEKLY_VARYING, 4 weeks, only OHP day shown for demonstration. Other days have the same structure with different exercises.

A complete Wendler template has 4 weeks × 4 days = 16 day definitions. For clarity, only Week 1, Day 1 is shown.

Example: Texas Method (abbreviated)

Modeled as WEEKLY_VARYING (2 unique weeks × 3 days). Odd week has Bench on Volume day, even week has OHP.

Complete examples of all 17 templates are available in the app — download an official template from the Marketplace and export as JSON.

exerciseId List

Complete list of 163 exercise IDs supported in IronPen. Use the exact string in the exerciseId field.

Main compound exercises

IDName ENName CS
back-squatBack SquatDřep s činkou
bench-pressBench PressBench press
deadliftDeadliftMrtvý tah
overhead-pressOverhead PressTlak nad hlavu
power-cleanPower CleanPower Clean
front-squatFront SquatPřední dřep
barbell-rowsBarbell RowsPřítahy s činkou
hip-thrustHip ThrustHip Thrust
sumo-deadliftSumo DeadliftSumo mrtvý tah
romanian-deadliftRomanian DeadliftRumunský mrtvý tah

Bodyweight exercises

IDName EN
pull-upsPull-ups
chin-upsChin-ups
push-upsPush-ups
dipsDips
ring-rowsRing Rows
inverted-rowsInverted Rows
plankPlank
leg-raisesLeg Raises

Kettlebell exercises

IDName EN
kb-swingKB Swing
kb-clean-pressKB Clean & Press
tguTurkish Get-Up
kb-snatchKB Snatch
goblet-squatGoblet Squat
kb-front-squatKB Front Squat
The complete list of all 163 IDs can be found in the exercises.json file exportable from the app, or in the exercise database under "Exercise List".

Validation Rules

The app validates JSON on import. Most common errors:

RuleError message
At least one of nameCs/nameEn must be non-emptyTemplate name is required
meta.id non-empty, no spacesTemplate ID is required
daysPerWeek: at least 1 value, 1-7daysPerWeek must be 1-7
weeksPerCycle: 1-52weeksPerCycle must be 1-52
trainingMaxPercent: 0.5-1.0trainingMaxPercent must be 0.5-1.0
Each exercise must have at least 1 setExercise has no sets
Max 30 sets per exerciseExercise has >30 sets
Max 15 exercises per dayDay has >15 exercises
PERCENT_TM/1RM: value 0.05-1.5Weight percentage out of range
CUSTOM_INPUT: key exists in requiredInputsCUSTOM_INPUT key not in requiredInputs
copies: 1-20Set copies must be 1-20
Schedule type matches populated fieldsWEEKLY_FIXED requires fixedDays