Products we run

Scoredly Open

Host the Open at your gym, free: athletes submit scores, admins approve them, and the leaderboard shows the number everyone actually wants — where that score lands worldwide.

The Scoredly Open landing page: “Run the Open at your gym” with leaderboards, score tracking, and predictions — shown with a seeded demo gym.

The problem

For three weeks a year, thousands of gyms become competition venues. Most run it on a whiteboard.

Every year the CrossFit Open turns ordinary gyms into competition floors: three workouts, judged scores, and a worldwide field. Inside the gym, that usually means a whiteboard and a spreadsheet — and the question every athlete asks first, where does my score land worldwide?, has no gym-sized answer. We built one, and made it free for gyms.

What we built

A leaderboard for the gym, a sync service for the world, and documentation for the API nobody documented.

The leaderboard is where the gym lives: athletes sign in with a magic link, register themselves, and submit each score with the judge’s name and optional photo proof. An admin approves or declines every score — with a reason — before it counts. Standings are scored the way the real event scores them (a missed workout costs last place plus one), across all eighteen official divisions and three scaling tiers, in five languages, fast on a phone held up between sets.

The sync service is a separate, stateless container with one job: give every athlete a predicted world rank. Once an hour — and only while a submission window is actually open — it pulls the gym’s approved scores, samples the official leaderboard, and pushes each athlete’s predicted rank and percentile back to the board.

The reference came out of building both: the official leaderboard API is public but undocumented, so we reverse-engineered it and wrote it down properly — score encodings, tiebreak rules, divisions, where each kind of data actually lives — as a standalone reference, so the knowledge outlives any one service.

A gym leaderboard on a phone: ranked athletes with per-workout scores across the three Open workouts. Seeded demo data.
the board on a gym-floor phone — demo gym, demo athletes

The board itself

Real product, replaced data: a seeded demo gym — never real gyms or athletes.

The Iron Athletics demo leaderboard: athletes ranked across Open 26.1, 26.2, and 26.3 with reps, times, scaled and foundations tags, submission windows, and points.

One table carries the whole event: times, reps, capped finishes, and scaling tags rank side by side (that is the one-integer encoding at work), each workout column knows whether its submission window is open, and points accumulate exactly the way the official event scores them.

How it works

The gym app never touches the official leaderboard. A small service does, carefully.

open.scoredly.comthe gym’s leaderboardAthlete submitsscore · judge · photo proofAdmin approvesor declines, with a reasonLeaderboardgym standings, and eachathlete’s predicted world rankapprovedscorespredictedrankssync servicea small stateless containerHourly wake-upruns only while asubmission window is openPrediction engineplaces each score on asampled score-to-rank curveOfficial leaderboardpublic API~300K rows per divisionsampledpagesits unofficial behavior,reverse-engineered &documented properly
The gym app never calls the official leaderboard. A small stateless service does — hourly, only while a submission window is open — and pushes each athlete’s predicted world rank back.

The separation is deliberate. The leaderboard app runs at the edge and serves gyms; the sync service is the only thing that talks to the official API, with bounded concurrency and polite pacing against an upstream that owes us nothing. It is built to be ignored: outside submission windows it wakes, sees nothing to do, and exits silently. During windows, a failed stage alerts us on Telegram and a missed run trips an external monitor. Nobody babysits it.

The hard part: a world rank without downloading the world

A division’s leaderboard is ~300,000 rows. We fetch fourteen pages of it.

Ranking one gym athlete against the world does not require the world — it requires knowing what scores sit at which ranks. The sync service samples evenly spaced pages of the official leaderboard (more pages for the crowded Rx field, fewer for smaller tiers) and turns them into a score-to-rank curve. Each gym athlete’s score is then placed by binary search and interpolated between the two nearest anchors.

rank 1~300Kworldrankscore (better →)each dot: one sampled pageof the official leaderboarda gym athlete’s scorepredicted rank — interpolatedbetween the two nearest anchors
Fourteen pages instead of three hundred thousand rows: evenly spaced sample pages become score-to-rank anchors, and each athlete lands between the two nearest. Better than the best anchor rounds to rank 1; worse than the worst extrapolates, capped at the field size.

Decisions worth noting

  • One integer ranks every score type. Times, reps, capped finishes with tiebreaks, and loads are all encoded so that higher is better — the entire board sorts with a single ORDER BY, with no per-type special cases to get wrong.
  • The tiers rank like the real event. Every Rx score outranks every Scaled score, which outranks every Foundations score — the same absolute ordering the official leaderboard uses, encoded rather than patched in afterwards.
  • Server-rendered pages, islands of interactivity. The board is mostly read, so the server renders HTML and small interactive islands hydrate only where they earn their weight. It stays fast on a gym Wi-Fi phone.
  • Documented the undocumented. Everything we learned about the unofficial API became a standalone reference document — durable knowledge instead of tribal knowledge.
  • Built to be ignored. Stateless, monitored, alert-on-failure, silent when there is nothing to do. Operations effort rounds to zero for fifty weeks a year.

Built with

  • Cloudflare Workers
  • Hono
  • htmx
  • Preact
  • D1

This is how we run our own products

The same standards go into client work — defined projects or prepaid blocks of cloud, network, and security engineering hours.