← Documentation

Using workouts and programming

Write workouts, program them on the calendar, publish the day, and track results, PRs, and leaderboards.

Updated September 14, 2026

Programming in OurGym is four things stacked on each other. If you know how they stack, everything else on this page is detail.

  1. Movements — your library of exercises. Written once, reused forever.
  2. Workouts — reusable objects made of pieces. Written once, reused forever.
  3. The programming calendar — which workouts land on which day, on which track.
  4. Publishing a day — the switch that makes it visible to members.

Everything here needs the head coach role or above.

The movement library

Programming → Movements is the canonical list of exercises: back squat, thruster, ring muscle-up, row. Each carries a category (barbell, gymnastics, monostructural, dumbbell, kettlebell, strongman), the equipment it needs, and a short slug you’ll use when writing workouts.

You don’t start from an empty list. Every new gym comes with OurGym’s library already installed: the common barbell lifts, gymnastics skills and cardio movements, the named benchmark workouts (Fran, Helen, the Hero WODs) and the 1RM tests. They’re your own copies — rename one, change its category, archive what you never use — and nothing you do affects the original or any other gym. If you ever want the library back (or OurGym has added to it since you joined), Add OurGym’s library on the Movements or Workouts screen shows what you’re missing and adds only that; anything you already have, including anything you’ve edited, is left exactly as it is.

Keep it tight. The library is what makes “how often have we squatted this month?” answerable, so one Back squat is worth ten near-duplicates. Archive what you stop using rather than deleting it — old results keep pointing at it.

Writing a workout

Programming → Workouts is the library; the same composer opens from the calendar, from a day view, and from an assistant draft. There’s only one, and it works the same everywhere.

A workout is a title, a workout-level score, and one or more pieces.

Pieces

A piece is a free-text box. Write the workout the way you’d write it on the whiteboard:

21-15-9
#thruster 95/65
#pull-up

Type # and the movement’s slug to mention a movement from your library — it renders as a chip and links the workout to that movement for cadence reporting and history. Everything else is free text, deliberately. Rep schemes, percentages, weights, and coaching cues don’t fit a grid, so we don’t make you fill one in.

A workout’s pieces are the parts of one scored thing: the main work plus its buy-in, its cash-out, its scaling tiers, its coaching notes. A strength lift and a metcon are two scored things, so they’re two workouts stacked on the same day — not two pieces of one workout. The next section explains why that matters and how to lay a day out.

How to lay out a day

A day on a track holds as many pieces as you like, stacked in order. Give each separately scored thing its own piece:

  • the strength lift is one piece;
  • the metcon is another;
  • the warm-up and the cool-down are a coach note piece, since they belong to the whole session rather than to either.

It’s tempting to put a whole day in one workout, and it looks tidier in the composer. It costs you real things:

  • Results and leaderboards belong to a workout. One workout records one result, so a lift and a metcon squeezed together lose a score between them.
  • Everything you do to a day, you do to a piece. Publish, comment, swap, reorder, drag to another day — all of it acts on one piece. Bundle the metcon in with the strength and you can’t move it to Friday on its own.
  • Splitting later isn’t possible. Nothing takes one workout apart into two. Rewriting it is the only way back, and any scores already logged against it are at stake.

The composer lets you build whatever you want — you’re the coach. This is just the shape that keeps its options open, and it’s the shape the AI assistant and any connected AI client are told to write.

Scoring

Pick a score type at workout level, and optionally override it per piece (default: inherit).

Score typeRanks byUse for
For timeLower is betterFran, chippers
Rounds + repsHigher is betterAMRAPs
WeightHigher is betterStrength, 1RM attempts
Reps / distance / calories / pointsHigher is betterMax-effort work
Not scoredSkill work, warm-ups, rest days

Score a workout’s pieces differently and it becomes a multi-part scored workout automatically — the board splits accordingly. There’s no toggle to remember.

Weight pieces

A piece scored Weight carries sets × reps, and mentions at most one library movement.

Mention one — “5×3 #back-squat” — and the loads members log are attributed to that lift, which is what feeds 1RMs, PR detection, and a member’s strength history. Mention none — “Build to a heavy single, your choice” — and the composer says so and saves anyway: the piece works, its loads simply aren’t counted towards any movement’s leaderboard or 1RM. That’s a note, not a blocker.

Mentioning two is the one thing the composer refuses. A member logs one number, and with two lifts in the piece there’s no answer to which one it belongs to — split them into their own pieces.

Time caps

Any piece can carry a time cap: type minutes (12), or minutes:seconds (7:30) when a cap isn’t a round number. It shows on the day view, on the gym-floor TV board, and — the point of it — on the calendar, so you can see how long a day runs without opening it.

Everywhere it shows, it reads back the way you wrote it: a round number of minutes as 12 min cap, anything else as a clock (7:30 cap), and a cap under a minute in seconds (45 sec cap). Nothing is rounded to the nearest minute.

A cap is the flat “finish inside this” answer. When the work is structured around the clock (every minute on the minute, 8 rounds of 20 on / 10 off), use the interval builder below instead.

Intervals

A piece can carry an interval builder instead of being timed by you in your head: rounds × timed slots, with EMOM, Tabata, and Custom presets. Set the rounds, set each slot’s duration and what happens in it. The result runs on the gym clock and displays correctly on the TV board.

Let the assistant draft it

The composer has a prompt box. Paste a workout in any format — from a text message, an email from a coach, last year’s notes — and it fills in the title, the score type, and the pieces, mentioning the movements it recognises.

It produces a draft in the form, always. Nothing saves until you read it and press save. Treat it as a fast typist, not an authority: check the score type and the weight-piece movement before saving.

The same drafting rules apply when you connect Claude or ChatGPT to the gym: programming an assistant writes lands on the calendar as a draft, and publishing the day stays a staff action — in the calendar, or by confirming the assistant’s publish request. See Connecting Claude or ChatGPT to your gym.

Programming the calendar

Programming → Calendar opens on a month view on a computer, and on a single day on a phone — the view that actually fits the screen you’re on. Whichever you pick travels in the page address, so a link you send opens on the view you meant. The month view is a classic calendar grid where each day lists what’s programmed on every track — each piece’s title and a line or two of what’s actually in it — with a Draft chip where a day isn’t published yet and a comment badge on any day, and any individual workout, where staff are discussing it. A busy day folds into “+n more”; switch on Full days to show every workout of every day in full (the whole scheme and every note, nothing clipped) for reading a block end to end, and switch it off to bring the compact grid back. Switch to Week for the track-by-day grid (days across, tracks down) when you’re writing a block of days — the week view always shows each day in full, so there’s nothing to switch on there. Previous and next are instant — the calendar loads the neighbouring months (or weeks) ahead of you.

3 days is the same week again, for reading rather than laying out. Instead of squeezing seven columns onto the screen it gives each day a column of its own, about three times as wide, and lets you scroll sideways through the week — three days at a time on a computer, one at a time on a phone, opening on today. On a phone this is where the calendar starts, and swiping past the last day of the week carries you into the next one — the same backwards. Each day stacks its tracks down the column, and the workouts are set a size larger with more space between the pieces. Reach for it when you want to actually read what you’ve written; reach for Week when you want the whole week in one picture. Everything works the same in both — adding, dragging, comments, Publish day — and Publish week, Clear week’s drafts and the previous / next buttons all mean the same seven days.

Wherever a workout is shown in full — the week and 3-day views, and the month view with Full days on — it reads the way you wrote it. Each piece keeps its own heading in bold, the line breaks you typed stay put, and a rule separates one piece from the next, so a day is a list of pieces rather than one paragraph. A piece longer than its card scrolls inside the card: put your cursor over it and scroll, and the rest of the workout comes up without leaving the grid or opening anything. The compact month view still shows one line per piece — that’s what makes it compact — so switch Full days on when you want to read rather than scan.

Every workout on the calendar also shows the movements in it as small pills and its time cap as a chip. That’s what makes the zoomed-out views worth reading: “Build the Frame” tells you nothing on its own, but “Build the Frame · 12 min cap · Strict Press · Floor Press” tells you at a glance whether you’ve pressed three days running. The pills appear on the week and 3-day views, and on the month view with Full days switched on.

Each track carries its own colour too, on both views: the dot beside the track’s name in the week grid, and the tint on every card that belongs to it. Pick a track’s colour when you create or rename it, under Tracks.

Tracks shown folds tracks out of sight. Tick a track off and it disappears from the week grid, the month grid, and nothing else — it is still programmed, still published, still on the member’s calendar. It’s for reading: hide Kids and Open Gym while you write next week’s CrossFit. What you hide travels in the page address, so a link you copy opens the way you left it.

Click a day (month view) or a piece (week view) to open the day view: every piece for that track and date, with its comments beside it. If you program more than one track, a Track picker at the top of the day view switches between them without closing anything. Publish day, Return to draft, and per-piece Remove — and Move…, which sends the piece to another day or track — live there too, so nothing needs the week view.

Moving a piece by dragging it

On a computer, every piece on the calendar can be dragged — in all three views. Pick a piece up and drop it:

  • higher or lower in the same day, to change the order a coach reads it in;
  • on another day, to shift it a day earlier or later;
  • on another track, to move it from (say) CrossFit to Open Gym.

While you’re holding a piece, every day outlines itself so you can see where it can go, and the one under your cursor fills in. The pieces around it slide out of the way as you move, so you’re always looking at the result before you let go. The month view also shows every track’s row on each day while you drag, including the empty ones, so you can drop onto a track that has nothing on it yet. Drop it on empty space in a cell and it goes to the end of that day.

On a phone, press and hold a piece for about half a second to pick it up — the pause is what tells us you meant to move it rather than scroll past it, so a quick swipe still scrolls the day. Once it’s in your hand you can drag it up and down to reorder that day. To move it to a different day or track, tap the piece to open the day view and use Move… — a phone only shows one day at a time, so there’s nowhere to drag it to.

Move… is there on a computer too, and it’s usually the better tool for a long move: picking a date beats dragging a piece across three weeks of calendar. It drops the piece at the end of the day you choose; drag it from there if the order matters.

You don’t have to use a mouse. Each piece has a small grip on its left edge that appears when you hover it or reach it with the keyboard: focus the grip, press space to pick the piece up, use the arrow keys (left and right for days, up and down to reorder within a day or reach the next track), then space to drop it or escape to put it back. Each step is announced, so a screen reader says which track, which date, and which position.

Two things to know:

  • A draft piece moves with no fuss. Nothing is public yet, so nothing changes for members.
  • A published piece asks first. Members can already see it on its current date, so moving it changes what they see — the confirm names both dates before anything happens. And because a piece should never become member-visible by accident, a published piece that lands on a day you haven’t published yet goes back to draft; the calendar tells you it did. Publish its new day when you’re ready. (Move it onto a day that’s already fully published and it stays published — it’s joining a day members already see.)

A track is one program you write for a group of classes — CrossFit, Olympic Lifting, Kids. Each track is a row on the calendar, and linking a class type to a track is what puts the right workout in front of the right class. Most gyms start with a single track named after their main program.

A brand-new gym has no tracks yet, so the calendar opens on a New track button: give it a name (a one-line description is optional) and the row appears. Track names are unique, and the comparison ignores capitals and spaces — so crossfit, CROSSFIT and Cross FIT are all the same track. Create one with a name you already use and you get the track you already have, not a second row that looks identical on the calendar. (This is also what stops an AI assistant connected to your gym from inventing a duplicate when it’s told the name a slightly different way.)

After that, Tracks in the calendar toolbar lists every track, with how much is programmed on it and the right way to get rid of it:

  • A track with nothing programmed on it — a duplicate, or one you created by mistake — has a Delete button. It’s removed for good. Nothing is lost, because nothing was on it, but you can’t undo it; you’d create the track again.
  • A track that carries programming has Archive instead. It disappears from the calendar, from every track picker, and from what members see, and the confirm tells you exactly that before anything happens. Nothing is deleted — the programming already written on it and any class types linked to it are kept — so an archived track sits in the same list with a Archived chip and a Restore button, and one click brings it back with its programming intact. Archiving also frees the name, so you can start a fresh track with it later.

Editing a track also shows its link name (the short lowercase name used in web links, set from the name when you created it); change it only if you need a specific link. You’ll also find New track beside every track picker — in the CSV import, in a new cycle, and on a class type in scheduling — so you’re never sent somewhere else to create one first.

Every day has a + button — on the day cell in the month view, on each day/track cell in the week view — with the same three choices:

  • Add workout — pick one from the library, or write a new one inline.
  • Add note — free text, with visibility set to Staff only or All members. This is where the coach’s warm-up plan, scaling options, and teaching points go. Staff-only notes carry a “Coach only” chip so nobody mistakes one for member-facing copy.
  • Comments & day view — open the whole day with its comment rail.

If you program several tracks, which track is a Track picker at the top of the dialog that opens, not a longer menu. In the week view, where each track has its own +, that picker arrives already set to the track you pressed.

Other tools on this screen:

  • Import — load programming from a file: a complete .json/.yaml export from here, or a PushPress .csv.
  • Export CSV — send a week of a track out to PushPress. Its dropdown holds Export JSON and Export YAML, which carry everything instead.
  • New cycle — set up a training cycle across a date range.
  • Clear week’s drafts / Clear all drafts — bulk-delete leftover draft pieces (workouts and notes) instead of removing them one at a time. Pick Clear week’s drafts from the button, or Clear all drafts from its dropdown, for every draft the location has ever accumulated. Either way you get a warning naming exactly how many pieces and how many days are about to be cleared before anything is deleted. This only ever touches drafts — anything already published is never affected.

Complete exports: JSON and YAML

A CSV is what PushPress reads, and it is a lossy shape: one row per piece, one cell of text per workout. Export JSON and Export YAML (in the Export button’s dropdown) carry everything instead — each workout’s separate parts, their time caps and score types, interval rounds and slots, the movements with their sets, reps and prescribed loads, the scaling tiers, the linked benchmark, your coach notes, the day notes at both tiers, and which pieces are still drafts. Every track in the range comes along.

Pick either and you get a date range, already set to the window you’re looking at — the week or the month on screen. Widen it for a season’s backup; one file covers up to a quarter.

The two formats hold exactly the same thing. JSON is for tooling; YAML is the one to open in a text editor if you want to read or hand-edit a week.

Use it to back programming up before a big change, to move a block between gyms, or to write a cycle once and reuse it next season.

Importing a week from a CSV

Import takes any of the three: a .json or .yaml file exported from here, or a PushPress .csv. You don’t choose a format — the file’s name says which it is. What happens next differs, so each is described in turn.

The CSV branch takes a PushPress workout-builder export — the Date, Title, Description, Score Type, Divisions columns — one week at a time. Pick the track, choose the file, and press Preview (dry run): nothing is written until you press Import. Imported workouts land as drafts, so you can flesh them out before publishing the day.

A CSV has no parts. Whatever shape you wrote a day in, one row is one Description cell, and it imports as one block of text — no separate strength and metcon, no per-part score types, no time caps. The preview says so: any row that reads like a multi-part session is marked Needs rebuilding, with a count above the table. Import it, then open those workouts in the composer and split them into pieces. This is also why assistants can’t use CSV import at all — see Connecting Claude or ChatGPT.

You don’t tell us which week it is — we read the dates out of the file. Dates have to be written 2026-09-07 or 20260907. A date like 09/07/2026 is refused rather than guessed at: it means 7 September in some countries and 9 July in others, and picking wrong would put your week on the wrong days.

If something’s off, we list one entry per problem — not one per row — with the rows it affects and what to do about it. Nothing is imported until the whole file is clean.

The one you’ll hit on your first import is divisions. A division is a level you program for, like Rx or Scaled, and OurGym only knows the ones your workouts already use — so on day one it knows none of them. Each unfamiliar name comes with an Add division button: press it and we re-check the file straight away, use the name for this import, and keep it for next time. Nothing is created until you say so.

Importing a complete JSON or YAML file

A .json or .yaml file exported from here restores the days whole — parts, caps, movements, tiers, benchmarks, notes and all — onto the tracks they came from. Press Preview (dry run) first; nothing is written until you press Import.

The preview tells you what the file holds and asks you about anything it can’t decide for you:

  • Days that already have programming. It names them, and asks whether to keep what’s there and add alongside it, or to replace those days — replacing deletes what is on them now.
  • Pieces that were published. A file remembers what was live. By default everything comes in as a draft and you publish when ready; the other option keeps them published, and those days go live for members immediately.

Three things resolve themselves, and the preview says so before you commit:

  • A track in the file that this gym doesn’t have is created.
  • A benchmark or movement it references that this gym doesn’t have comes in as plain text — the workout imports, that one link doesn’t.
  • A location it names that this gym doesn’t have is refused, because quietly making one site’s programming gym-wide would show it at every site.

If the file itself is malformed, you get one line per problem naming exactly where it is (days[2].pieces[0].workout.scoreType), and nothing is imported.

Exporting a week to PushPress

If you also run PushPress Train, Export CSV sends a week the other way. Pick the track and the week — it opens on the week you’re looking at — and press Export CSV. The file downloads, and you upload it in PushPress under Train → Import workouts.

One file is one week, because that’s PushPress’s own limit. The file carries Date, Title, Description, Score Type, Coaches Notes, Athlete Notes, Divisions, Linked Benchmark, which is everything PushPress’s importer reads.

What goes in it:

  • Every piece on that track that week, in calendar order — drafts included, since the week you’re exporting is often the one you’re still writing.
  • A workout’s full text, its coach notes, its divisions, and the benchmark it’s linked to.
  • Coach notes and member notes on a day, each in its own column.

If nothing is programmed on that track that week, nothing downloads and we say so, rather than handing you an empty file that imports zero workouts.

Comments on a day

Programming is a conversation between coaches, so every day has a comment thread — think Google Docs comments, but on the calendar.

You never have to go looking for the affordance. On the week and 3 days views every date heading carries a speech-bubble button beside it, and every workout or note carries one at its bottom-right — on an empty day too, since that’s where the first comment usually gets written. The button is also the badge: it shows the number of unresolved threads in your gym’s accent colour, a ✓ with a count once every thread there is resolved, and a plain bubble when nobody has said anything yet. If you program several tracks, the date heading’s button asks which track first, listing each with its own count. In the month view every day carries its own speech-bubble button, immediately left of the +, which opens that day with its comment rail; the day’s tracks badge the same counts (per day and per workout) and open the day when you click them.

All of this works the same in the staff app and in the standalone programming app at programming.ourgym.app — same calendar, same comments.

Open a day and use the Comments rail on the right:

  • Comment on this day, or press the bubble on a specific workout or note to pin the thread to that piece (“on Fran”). If that piece is later removed, the thread stays on the day — it just loses its pin. A day with nothing programmed yet can still be opened from its + menu (Comments & day view).
  • @mention a colleague — type @ and their name or email address; they get an email with your comment and a link straight to the day.
  • Reply under any thread. Resolve when it’s settled; resolved threads are hidden by default (toggle Show resolved), and anyone can Reopen one.

Every comment, reply, and resolve also lands in Chat, in a channel called #programming that the whole staff is in, as a card showing the track, the day, the piece, and the comment. From the card you can reply, resolve, or jump to the day on the calendar — so the discussion is visible to everyone without anyone having to go looking for it.

Comments are staff-only: members never see them, and commenting needs the same head coach (or above) access as writing programming.

Publishing a day

Programmed days start as Draft. Members see nothing.

Publish day is what makes that day’s programming member-visible: it lands on their Today’s workout, on their programming calendar, and on the TV board. Return to draft hides it again.

This is the single control over member visibility, per day, per track. Program a whole cycle in advance and release it a week at a time; nobody sees Thursday until you say so.

Publishing a whole week

In the week and 3 days views, Publish week does the same thing to every drafted day of that week at once — including, in the 3-day view, the days you’d have to scroll to reach. It asks first, naming exactly what it’s about to release — how many days, on which tracks, over which dates — because this is the one button that puts a week of programming in front of your members.

It only ever publishes tracks you can see. Anything folded away under Tracks shown is left alone, so hiding a track to read the week can’t accidentally release it.

Benchmarks

Programming → Benchmarks is your named-workout list — the Girls, the Heroes, your own gym tests. A benchmark is the thing a member’s score is compared against over time, so their Fran from today lines up with their Fran from March.

Benchmark kinds: 1RM lift, Named WOD, Time trial, Max reps, and Skill. Members see their own history at Benchmark history, and their lifts at My 1RMs.

What members see

Once a day is published, a member gets:

  • Today’s workout — the day’s programming for their track.
  • Programming calendar — read-only, published days only.
  • My results — everything they’ve logged, with PRs marked.
  • Leaderboard — the day’s board for a workout.
  • My 1RMs and Benchmark history — their strength and benchmark curves.
  • Gym feed — results, PRs, and shout-outs across the gym, with likes and comments.

Members log their own results; a coach can log on someone’s behalf from the front desk. PRs are detected automatically from what’s logged — nobody has to declare one.

Editing a workout that’s already been done

Workouts are reusable objects, so editing one reaches everywhere it’s been used. Our rule is warn, don’t lock.

You can always edit. Before you save, the composer tells you the blast radius: how many days it’s programmed on, how many are in the past, how many are published, and how many members have already logged results against it. If logged scores are at stake, saving takes a second, explicit confirmation.

When the honest answer is “this is a different workout now”, take Clone & modify instead — it copies the workout, retargets your edits onto the copy, and repoints today’s programming at it. History stays intact and today gets what you meant.

Only archived workouts are immutable. There’s no ownership lock: any coach with programming permission can edit any workout, because a gym where only the author can fix Tuesday is a gym with a broken Tuesday.

The programming-only app

Everything on this page also lives at programming.ourgym.app — the same five screens (Calendar, Workouts, Movements, Benchmarks, Cadence) with nothing else around them: no sidebar, no members, no billing, no assistant.

Sign in with the same staff account you use for the main app; it is the same gym, the same data, and the same head coach requirement. A change made in one shows up in the other, because it is one system, not a copy.

Use it when programming is the whole job — a coach writing next week’s cycle on a laptop at the gym, or a programmer who works for you but has no reason to see the roster or the money. Everything else about the gym stays in the main app.

Two coaches at once

Programming is often a shared job, so the screens keep themselves current while you work. When a colleague adds a workout, moves a piece, publishes a day, renames a movement, or leaves a comment, it appears on your calendar and in your libraries on its own — no refresh, and no spinner over the work you are looking at. The same is true in reverse, and in the standalone programming app.

Two things worth knowing:

  • Whatever you have open stays yours. A workout you are part-way through writing is never overwritten from under you while you type. Only saved work syncs.
  • The last save wins. If two of you edit the exact same workout at the same moment, whoever saves second is the version that sticks. In practice this is rare — but it is worth a word in chat before two people work the same day.

A workable weekly rhythm

  1. Sunday: block out the week on the calendar, all tracks, left as drafts.
  2. Write or reuse the workouts; add coach-only notes for warm-ups and scaling.
  3. Publish tomorrow’s day each evening — or the whole week, if you program open.
  4. Coaches read the day view before class; the TV board picks up the same data.
  5. Members log results; PRs, the leaderboard, and the feed take care of themselves.

Where to go next


Something here out of date, or a step that didn't work? Tell us at support@ourgym.app.