Plan Structure
This page documents all fields in the PWF (Portable Workout Format). Fields marked with * are required.
Top-Level Structure
Every plan file has three sections:
| Field | Type | Description |
|---|---|---|
plan_version * | number | Must be 1 |
meta * | object | Plan metadata (title, author, etc.) |
cycle * | object | The training cycle containing days |
Meta Fields
The meta section describes your plan:
meta-example.yaml
meta:
id: my-unique-plan-id
title: Push Pull Legs
description: Classic 3-day split for strength and hypertrophy
author: Your Name
equipment:
- Barbell
- Dumbbells
- Cable machine
daysPerWeek: 3
tags:
- strength
- intermediate | Field | Type | Description |
|---|---|---|
title * | string | Plan name (max 80 characters) |
id | string | Unique identifier. Auto-generated if omitted. |
description | string | Brief description shown in the app |
author | string | Creator name or attribution |
equipment | string[] | List of required equipment |
daysPerWeek | number | Suggested training frequency. Defaults to number of days in cycle. |
tags | string[] | Categorization tags (e.g., "strength", "beginner") |
Cycle Fields
The cycle contains your training days:
cycle-example.yaml
cycle:
notes: Rest 48 hours between sessions. Deload every 4th week.
days:
- order: 0
focus: Push
# ...exercises
- order: 1
focus: Pull
# ...exercises
- order: 2
focus: Legs
# ...exercises | Field | Type | Description |
|---|---|---|
days * | array | At least one day required |
notes | string | General notes for the entire cycle |
start_date | string | Optional start date (YYYY-MM-DD format) |
Day Fields
Each day in the days array represents a training session:
day-example.yaml
- order: 0
id: push-day
focus: Push (Chest, Shoulders, Triceps)
notes: Start with compound movements
target_session_length_min: 60
exercises:
- name: Bench Press
modality: strength
target_sets: 4
target_reps: 8 | Field | Type | Description |
|---|---|---|
order * | number | Position in cycle (0-indexed). Must be unique. |
exercises * | array | At least one exercise required |
id | string | Unique identifier. Auto-generated if omitted. |
focus | string | Day name or focus area (e.g., "Push", "Upper Body") |
notes | string | Notes specific to this day |
target_session_length_min | number | Expected workout duration in minutes |
scheduled_date | string | Specific date to perform this workout (YYYY-MM-DD) |
Exercise Fields
Each exercise in the exercises array:
exercise-example.yaml
- id: ex-bench-press
name: Bench Press
modality: strength
target_sets: 4
target_reps: 8
target_notes: Warm up with bar, then 50%, then working sets
link: https://www.youtube.com/watch?v=example | Field | Type | Description |
|---|---|---|
name * | string | Exercise name |
modality * | string | One of: strength, countdown, stopwatch, interval |
id | string | Unique identifier. Auto-generated if omitted. |
target_sets | number | Number of sets (for strength/interval) |
target_reps | number | Reps per set (for strength) |
target_duration_sec | number | Duration in seconds (for countdown/stopwatch/interval) |
target_distance_meters | number | Target distance for cardio exercises |
target_notes | string | Coaching cues or notes |
link | string | HTTPS URL to video demo or instructions |
image | string | HTTPS URL to exercise image |
Field Requirements by Modality
Different modalities use different fields:
| Modality | Common Fields | Notes |
|---|---|---|
strength | target_sets, target_reps | Traditional sets × reps |
countdown | target_duration_sec | Fixed timer (e.g., plank for 60 seconds) |
stopwatch | target_duration_sec (optional) | Open-ended timing with optional target |
interval | target_sets, target_duration_sec | Repeated timed sets (e.g., 5 × 30 sec sprints) |
See Exercise Modalities for detailed examples of each type.