Hevy Routine Creator
Quick Start
<skill-dir>/bin/hevy auth <key> # Authenticate (get key from hevy.com/settings)
<skill-dir>/bin/hevy exercises search "squat"
<skill-dir>/bin/hevy routines template > routine.json
# Edit routine.json
<skill-dir>/bin/hevy routines create routine.json
For all commands: <skill-dir>/bin/hevy --help
Workflow
- Parse workout plan - extract exercises, sets, reps, weights, rest times
- Look up exercise IDs -
hevy exercises search <name>
- Build routine JSON - start with
hevy routines template
- Create routine -
hevy routines create file.json
Critical Rules
- NEVER use
@ in notes (causes silent 400 errors)
- ALWAYS wrap:
{"routine": {...}} not bare object
- ALWAYS match set properties to exercise type:
weight_reps → weight_kg, reps
reps_only → reps only (NO weight!)
duration → duration_seconds
distance_duration → distance_meters, duration_seconds
short_distance_weight → distance_meters, weight_kg (Farmers Walk, Sled Push/Pull)
- NEVER guess IDs - always
hevy exercises search
Exercise Type Decision
| User describes... |
Exercise Type |
Set Properties |
| Weight + reps ("3x10 @ 135lb") |
weight_reps |
weight_kg, reps |
| Just reps ("3x12 pull-ups") |
reps_only |
reps only |
| Time hold ("60s plank") |
duration |
duration_seconds |
| Distance + time ("500m row") |
distance_duration |
distance_meters, duration_seconds |
| Distance + weight ("50m farmers walk @ 80kg") |
short_distance_weight |
distance_meters, weight_kg |
When unsure: hevy exercises get <id> shows the exercise type.
Interpreting Workout Plans
Supersets:
- "A1/A2", "superset", "paired" → same
superset_id (integers: 0, 1, 2...)
- "Circuit" or "EMOM" → all exercises share one superset_id
- Separate exercises →
superset_id: null
Rest: Goes on LAST exercise of superset only
AMRAP/Max effort: Use "reps": null
Example superset structure:
{
"exercise_template_id": "79D0BB3A",
"superset_id": 0,
"rest_seconds": null,
"sets": [{"type": "normal", "weight_kg": 80, "reps": 10}]
},
{
"exercise_template_id": "1B2B1E7C",
"superset_id": 0,
"rest_seconds": 90,
"sets": [{"type": "normal", "reps": 8}]
}
Common Exercise IDs
Use hevy exercises search for current IDs. These are reference examples:
| Exercise |
ID |
Type |
| Squat (Barbell) |
D04AC939 |
weight_reps |
| Deadlift (Barbell) |
C6272009 |
weight_reps |
| Bench Press (Barbell) |
79D0BB3A |
weight_reps |
| Overhead Press (Barbell) |
AE23FF09 |
weight_reps |
| Pull Up |
1B2B1E7C |
reps_only |
| Push Up |
392887AA |
reps_only |
| Rowing Machine |
0222DB42 |
distance_duration |
| Stretching |
527DA061 |
duration |
| Farmers Walk |
49742539 |
short_distance_weight |
Before Creating Custom Exercises
- Search partial names ("row" not "cable row")
- Check equipment variants (Barbell, Dumbbell, Cable, Machine)
- Try alternate names ("Skull Crushers" = "Lying Tricep Extension")
Unit Conversion
User provides lbs → convert to kg: weight_kg = lbs / 2.205
Round to nearest 0.5 kg for practical loading.
Handling Search Results
| Scenario |
Action |
| Exact match |
Use that ID |
| Multiple similar (e.g., "Squat" returns Barbell, Dumbbell, Smith) |
Pick equipment variant matching user's context |
| No results |
Try shorter term ("tricep" not "tricep pushdown cable") |
| Still nothing |
Create custom exercise only as last resort |
Bulk Import Strategy
For programs with 10+ routines:
- Build all JSON files first
- Create one routine, verify it appears correctly in app
- Create remaining with 2-second delays between calls
- If 429 error: wait 60s, resume from failed routine
Troubleshooting
| Problem |
Cause |
Fix |
| HTML response |
@ in notes |
Replace with "at" |
| Exercise not found |
Typo |
Search partial name |
| 401 Unauthorized |
Bad API key |
hevy auth test |
| 429 Rate limit |
Too many requests |
Wait 60s, then retry |
| 400 Bad Request |
Wrong set properties for exercise type |
Check exercise type with hevy exercises get <id> |
| Field not allowed |
Read-only field in update |
Remove id, created_at, updated_at fields |
| Sets rejected |
weight_kg on reps_only exercise |
Remove weight, use only reps |
CLI vs This File
| Need |
Use |
| Exact command syntax, all flags |
hevy <command> --help |
| Workflow, gotchas, interpretation rules |
This file |
| Exploring all capabilities |
hevy --help |
1---2name: hevy3description: Create workout routines in Hevy fitness app. Converts training programs (text/PDF/image) to Hevy JSON format via CLI. Look up exercise IDs, build routine JSON, create via API. Use when: creating gym routines, importing workout plans, looking up exercise IDs, building workout JSON, converting programs (PPL, 5x5, 531, GZCLP, nSuns, Starting Strength, PHUL, PHAT, Upper/Lower, Full Body), syncing to Hevy, or any Hevy API task. Keywords: fitness app, workout tracker, routine builder, gym program, strength training, hypertrophy, exercise database, training log, weightlifting, bodybuilding User-invocable: /hevy4---56# Hevy Routine Creator78## Quick Start910```bash11<skill-dir>/bin/hevy auth <key> # Authenticate (get key from hevy.com/settings)12<skill-dir>/bin/hevy exercises search "squat"13<skill-dir>/bin/hevy routines template > routine.json14# Edit routine.json15<skill-dir>/bin/hevy routines create routine.json16```1718For all commands: `<skill-dir>/bin/hevy --help`1920## Workflow21221. **Parse workout plan** - extract exercises, sets, reps, weights, rest times232. **Look up exercise IDs** - `hevy exercises search <name>`243. **Build routine JSON** - start with `hevy routines template`254. **Create routine** - `hevy routines create file.json`2627## Critical Rules2829- **NEVER** use `@` in notes (causes silent 400 errors)30- **ALWAYS** wrap: `{"routine": {...}}` not bare object31- **ALWAYS** match set properties to exercise type:32 - `weight_reps` → weight_kg, reps33 - `reps_only` → reps only (NO weight!)34 - `duration` → duration_seconds35 - `distance_duration` → distance_meters, duration_seconds36 - `short_distance_weight` → distance_meters, weight_kg (Farmers Walk, Sled Push/Pull)37- **NEVER** guess IDs - always `hevy exercises search`3839## Exercise Type Decision4041| User describes... | Exercise Type | Set Properties |42|-------------------|---------------|----------------|43| Weight + reps ("3x10 @ 135lb") | `weight_reps` | weight_kg, reps |44| Just reps ("3x12 pull-ups") | `reps_only` | reps only |45| Time hold ("60s plank") | `duration` | duration_seconds |46| Distance + time ("500m row") | `distance_duration` | distance_meters, duration_seconds |47| Distance + weight ("50m farmers walk @ 80kg") | `short_distance_weight` | distance_meters, weight_kg |4849**When unsure**: `hevy exercises get <id>` shows the exercise type.5051## Interpreting Workout Plans5253**Supersets:**54- "A1/A2", "superset", "paired" → same `superset_id` (integers: 0, 1, 2...)55- "Circuit" or "EMOM" → all exercises share one superset_id56- Separate exercises → `superset_id: null`5758**Rest:** Goes on LAST exercise of superset only5960**AMRAP/Max effort:** Use `"reps": null`6162**Example superset structure:**63```json64{65 "exercise_template_id": "79D0BB3A",66 "superset_id": 0,67 "rest_seconds": null,68 "sets": [{"type": "normal", "weight_kg": 80, "reps": 10}]69},70{71 "exercise_template_id": "1B2B1E7C",72 "superset_id": 0,73 "rest_seconds": 90,74 "sets": [{"type": "normal", "reps": 8}]75}76```7778## Common Exercise IDs7980Use `hevy exercises search` for current IDs. These are reference examples:8182| Exercise | ID | Type |83|----------|-----|------|84| Squat (Barbell) | `D04AC939` | weight_reps |85| Deadlift (Barbell) | `C6272009` | weight_reps |86| Bench Press (Barbell) | `79D0BB3A` | weight_reps |87| Overhead Press (Barbell) | `AE23FF09` | weight_reps |88| Pull Up | `1B2B1E7C` | reps_only |89| Push Up | `392887AA` | reps_only |90| Rowing Machine | `0222DB42` | distance_duration |91| Stretching | `527DA061` | duration |92| Farmers Walk | `49742539` | short_distance_weight |9394## Before Creating Custom Exercises95961. Search partial names ("row" not "cable row")972. Check equipment variants (Barbell, Dumbbell, Cable, Machine)983. Try alternate names ("Skull Crushers" = "Lying Tricep Extension")99100## Unit Conversion101102User provides lbs → convert to kg: `weight_kg = lbs / 2.205`103104Round to nearest 0.5 kg for practical loading.105106## Handling Search Results107108| Scenario | Action |109|----------|--------|110| Exact match | Use that ID |111| Multiple similar (e.g., "Squat" returns Barbell, Dumbbell, Smith) | Pick equipment variant matching user's context |112| No results | Try shorter term ("tricep" not "tricep pushdown cable") |113| Still nothing | Create custom exercise only as last resort |114115## Bulk Import Strategy116117For programs with 10+ routines:1181. Build all JSON files first1192. Create one routine, verify it appears correctly in app1203. Create remaining with 2-second delays between calls1214. If 429 error: wait 60s, resume from failed routine122123## Troubleshooting124125| Problem | Cause | Fix |126|---------|-------|-----|127| HTML response | `@` in notes | Replace with "at" |128| Exercise not found | Typo | Search partial name |129| 401 Unauthorized | Bad API key | `hevy auth test` |130| 429 Rate limit | Too many requests | Wait 60s, then retry |131| 400 Bad Request | Wrong set properties for exercise type | Check exercise type with `hevy exercises get <id>` |132| Field not allowed | Read-only field in update | Remove `id`, `created_at`, `updated_at` fields |133| Sets rejected | `weight_kg` on reps_only exercise | Remove weight, use only `reps` |134135## CLI vs This File136137| Need | Use |138|------|-----|139| Exact command syntax, all flags | `hevy <command> --help` |140| Workflow, gotchas, interpretation rules | This file |141| Exploring all capabilities | `hevy --help` |