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.com the gym’s leaderboard Athlete submits score · judge · photo proof Admin approves or declines, with a reason Leaderboard gym standings, and each athlete’s predicted world rank approved scores predicted ranks sync service a small stateless container Hourly wake-up runs only while a submission window is open Prediction engine places each score on a sampled score-to-rank curve Official leaderboard public API ~300K rows per division sampled pages its 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 ~300K world rank score (better →) each dot: one sampled page of the official leaderboard a gym athlete’s score predicted rank — interpolated between 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 — cloud, network, and security engagements with a fixed scope and a fixed price, delivered as code you own.