Your AI writes it. I run it.
Get Good Reps runs workouts written as plain JSON. There's no API, no account, and no key to configure — you ask an AI assistant for a routine, paste its answer into the app, and it runs. The whole spec is one page, on purpose.
If you'd rather hand the machine-readable version straight to your assistant, point it at /llms.txt. This page says the same things for humans.
Open Get Good Reps → Plan → Create with AI. Tap Copy the prompt, paste it to ChatGPT, Claude, or whatever you use, answer its questions, then paste the answer back. That prompt already contains everything below, so you don't have to read any of this.
One JSON object. A name, an optional default rest, and a list of exercise blocks that run in order.
{
"name": "Full Body A",
"restBetweenSets": 60,
"exercises": [
{ "exercise": "squat", "sets": 3, "reps": 10 }
]
}
| Field | Meaning |
|---|---|
name | String. Shown while the routine runs. Optional — defaults to "AI routine". |
unit | "lb" or "kg" — the unit every weight in this routine is written in. Optional, defaults to "lb". Declare it once at the top, never per exercise. |
restBetweenSets | Seconds. Used after any set that doesn't set its own. Optional — defaults to 60. |
exercises | Array, required, at least one. Each entry is a block of sets of one movement. |
| Field | Meaning |
|---|---|
exercise | Required. One of the twenty ids below, spelled exactly. |
sets | 1–20. Optional — defaults to 1. |
reps | 1–200. Optional. Leave it out for an as-many-as-you-can set. |
weight | A number, in the routine's unit. Optional. Leave it out for bodyweight. |
weights | Per-set weights for ramping, e.g. [45, 55, 65]. Use this or weight, not both. |
rest | Seconds. Overrides restBetweenSets for this block only. |
unit. What you see in the app is a separate choice — set it under You → Settings → Units, and every weight everywhere follows it.Use the id on the left. The name on the right is just so you know which is which — it doesn't go in the JSON.
That's the whole list, and it can't be extended from a routine. Get Good Reps counts reps by watching one joint angle per movement, so it only coaches what it can actually see well enough to judge. Ask for burpees and you'll get an honest no.
{
"name": "Living Room 20",
"restBetweenSets": 45,
"exercises": [
{ "exercise": "squat", "sets": 3, "reps": 12 },
{ "exercise": "inclinepushup", "sets": 3, "reps": 10 },
{ "exercise": "lunge", "sets": 3, "reps": 10 },
{ "exercise": "bridge", "sets": 3, "reps": 15, "rest": 30 }
]
}
The top-level "unit": "kg" says every weight below is kilograms.
{
"name": "Upper Body B",
"unit": "kg",
"restBetweenSets": 75,
"exercises": [
{ "exercise": "press", "sets": 4, "reps": 8, "weights": [20, 25, 30, 30] },
{ "exercise": "row", "sets": 4, "reps": 10, "weight": 27.5 },
{ "exercise": "curl", "sets": 3, "reps": 12, "weight": 12.5 },
{ "exercise": "tricep", "sets": 3, "reps": 12, "weight": 10 },
{ "exercise": "lateralraise", "sets": 2, "reps": 15, "weight": 5, "rest": 45 }
]
}
Leaving unit out means pounds.
{
"name": "Upper Body B",
"restBetweenSets": 75,
"exercises": [
{ "exercise": "press", "sets": 4, "reps": 8, "weights": [45, 55, 65, 65] },
{ "exercise": "row", "sets": 4, "reps": 10, "weight": 60 },
{ "exercise": "curl", "sets": 3, "reps": 12, "weight": 25 },
{ "exercise": "tricep", "sets": 3, "reps": 12, "weight": 20 },
{ "exercise": "lateralraise", "sets": 2, "reps": 15, "weight": 10, "rest": 45 }
]
}
"jumping lunges", "Overhead Press", "pushups" aren't ids. Get Good Reps forgives case, spacing and plurals, and offers a one-tap fix for a near miss — but it can't invent a movement it doesn't know how to watch.tempo, notes, superset, duration are ignored. Timed holds aren't supported — Get Good Reps counts reps, not seconds.unit. Converting introduces rounding nobody asked for.The camera work is all on-device — no video, frames or landmarks are ever uploaded, and there's no server here that receives routines. You paste the JSON in yourself; that's the entire integration. It's why this is a text file and not an API.