live against api.workout-lib.gr·exercise catalog·rest api

···· exercises.Searched in ····ms.

Strength, cardio and mobility movements, searchable in English and Greek from one index — typo-tolerant, accent-folded, filterable by muscle and muscle group. Roughly half carry a muscle map and a growing share carry demonstration footage. The rest of the fields are thinner, the table below prints exactly how thin, and none of it is rounded in our favour. The box is searching it as you type, with no key.

muscles
demo clips
muscle groups
languages
try
type
works

server

ms

round trip

ms

showing

with footage

api networkmedianlast 0 queries

Type a movement. English or Greek, misspelled is fine.

GETapi.workout-lib.gr/api/demo/search?q=squat

what is in a row

Including the columns we have not filled.

Every exercise carries a name, a slug and a category — not as a statistic that happens to be high, but because those columns cannot be null. A row missing one does not exist.

Everything else is optional, and this catalog is young enough that "optional" means it. The table is counted live on every request and sorted by what is actually there, so it cannot flatter itself into a better order. Footage is the field we promote — the search above prefers exercises that have it — which makes its real share the last thing that should be a footnote.

The bottom of the list is the honest embarrassment. Instruction steps, Greek text and coaching notes exist for a founding subset of the catalog and not for the long tail that was imported around it; classifying every movement as compound or isolation, push or pull, is work nobody has started. We would rather you read the real figure here than build a filter on one of those columns and discover it yourself.

What that means in practice: treat the taxonomy and the search as the product, and treat every nullable field as something to render conditionally. Your UI wants to tell "nobody recorded this" apart from "this is zero", because the API does.

guaranteed by the schema

  • Nameall
  • Slugall
  • Categoryall

measured, live

  • Primary muscles···
  • Secondary muscles···
  • Demonstration footage···
  • Greek translation···
  • Instruction steps···
  • Coaching note···
  • Description···
  • Mechanic···
  • Force···
  • Separate thumbnail···

the catalog over time

Still being worked on.

An exercise catalog is only worth integrating against if somebody is still tending it. So the useful question is not how big this one is today — it is what changed last month, and whether anyone is listening about what to change next.

Two things move. New movements get added, and — more often — existing rows get filled in: footage attached, muscles corrected, instructions written, Greek translated. The second is the work that matters most here, which is why the clip figure beside this paragraph is counted separately from the exercise figure and can be the larger of the two.

What gets filled in next is driven by what people ask for. We review the catalog on a regular cycle and reprioritise from the requests we get — a missing movement, a wrong muscle map, a clip that demonstrates the lift badly. If you are building on this and something is not there, saying so is the fastest way to change the order of the queue. That is a commitment about process, not a promised date: we are not going to tell you a gap closes by a particular week.

Nothing is quietly dropped, either. Deletions are soft, so an exercise you built against does not disappear from under you between releases, and an id that gets merged into another row keeps resolving.

clips added

last 30 days, rolling

exercises added

last 30 days, rolling

exercises today

live count

newest in

gif_url · media[]

Many of them come with the movement, not just the name.

Demonstration clips come back as absolute URLs on every hit — nothing to assemble client-side, no second request, no signing. Some movements carry more than one take. These are loading from the catalog right now.

This wall is assembled from exercises that have a clip, which is a share of the catalog printed live in the coverage table above — not all of it. The rest have their muscles, mechanics and instructions and are waiting on footage, which is the queue we work through and reorder from what people ask for.

what you get

Built for an exercise picker that has to feel instant.

?q=

Spell it however it comes out

sqaut finds Squat – Barbell and deadlfit finds Deadlift – Barbell; benchpress works without the space. Accents fold, so καθισμα finds the rows whose Greek name is κάθισμα. All of it is one Meilisearch index, so a misspelled Greek query is not a special case.

translated_locales

Bilingual search, per-field fallback

A query in English or Greek hits the same document — one index, no language parameter needed to search. Ask for ?lang=el and the response comes back Greek, falling back field by field where a translation is missing rather than dropping to English wholesale. How much Greek text exists is a separate question from whether the mechanism works, and translated_locales answers it per row: the coverage table above prints the catalog-wide figure, and it is currently a minority.

gif_url · media[]

The movement, not a description of it

Demonstration clips arrive as absolute URLs on the search response itself — no base path to assemble, no signing step, no follow-up request. Some exercises carry more than one take, exposed as media[] with a variant on each, so you can show the one that fits your user. Coverage is the honest caveat and it is printed live further up this page.

primary_muscles[]

A muscle map you can filter on

Twenty-one muscles in six groups, attached to an exercise as primary or secondary. Filter by muscle, by group, or by group-and-role — which is what turns a catalog into a program builder, because "what else hits the posterior chain" becomes a query rather than a lookup table you maintain yourself. This is the best-covered optional field and still not a universal one; the live share is in the table above.

steps[]

Instructions, where they have been written

Ordered, numbered coaching steps come back on the search response itself rather than behind a second request. They are on a minority of the catalog today — the founding set rather than the long tail — so build the list to render conditionally and check the coverage figure above before you depend on it. It is one of the queues that requests reorder.

If-None-Match

Stop re-downloading the catalog

Every cached read carries an ETag; send it back and an unchanged body returns as a 304 with no payload — most of them, on a catalog that moves slowly. There is deliberately no freshness window, so an edit reaches you on your very next read rather than after a TTL expires.

DELETE (soft)

Ids do not rot

Deletes are soft, so an exercise you built against does not vanish between releases. Duplicates that get merged keep resolving too — request the old id and you get the row that replaced it, rather than a 404 in somebody’s saved workout.

integration

One GET, one header, done.

No SDK to install and none needed — it is JSON over HTTP with a bearer token. The reference is a single page, hand-maintained in the same commit as the endpoint it documents, which is a smaller promise than a generated spec and a more reliable one.

Read the reference
# Exchange credentials for a 60-minute token. Accounts are created by an
# operator — there is no self-service signup, see below.
TOKEN=$(curl -sS -X POST https://api.workout-lib.gr/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"you@example.com","password":"…"}' | jq -r .access_token)

# -G with --data-urlencode keeps Greek readable instead of %CE%BA%CE%AC…
curl -sS -G 'https://api.workout-lib.gr/api/exercises/search' \
  --data-urlencode 'q=bench press' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

# → 200 matches, top one "Bench Press – Barbell".
#   Misspell it (benchpress, sqaut, deadlfit) and you still land on the lift.

# Same catalog in Greek — names, notes and every step:
curl -sS -G 'https://api.workout-lib.gr/api/exercises/search' \
  --data-urlencode 'q=καθισμα' --data-urlencode 'lang=el' \
  -H "Authorization: Bearer $TOKEN"

# No token at all? The public demo window answers, capped and page-pinned:
curl -sS -G 'https://api.workout-lib.gr/api/demo/search' --data-urlencode 'q=squat'

access

No plan tiers, because there are none yet.

A pricing table would be easy to draw and impossible to keep. This API has one enforced limit and no monthly quota, so that is what gets printed — and what it costs depends on what you are building, which is a conversation rather than a number.

120requests / minute

per account, on every authenticated route

Keyed on the token holder, so your traffic is never shaped by somebody else’s.

60requests / minute

per IP, on the keyless demo above

Its own bucket, so a visitor typing in that box cannot spend your allowance.

10attempts / minute

per IP, on login

Credential stuffing, not you. Tokens last 60 minutes and refresh without re-authenticating.

What it costs

Not published, and not because it is expensive. There is no metering code, so any figure printed here would be a number nobody could enforce or audit — including us. Tell us what you are building and roughly how much traffic it means, and you get a straight answer, plus an honest read on whether the catalog actually covers your use case.

No monthly cap exists today. That is a statement about the current implementation, not a promise for ever — if one is added it will be enforced by the server and printed here at the same time, in that order.

Start a conversation

included, whatever we agree

  • The whole catalog and every field — nothing is held back behind a tier
  • Both languages, all six muscle groups, every clip that exists
  • ETags on the cached reads, so most of your polls cost no bandwidth
  • Soft deletes and merge-following, so the ids you store keep resolving

getting access

There is no signup form.

Accounts are created by a person, one at a time — which means we read what you are building before you integrate, and you get a straight answer about whether the catalog covers it. Tell us the shape of it and expect a reply the same week.

worth mentioning

  • What you are building. A training app, a coaching tool, a gym screen — it changes which fields matter and which gaps would actually block you.
  • Rough monthly volume. The per-minute limit is the only one enforced today, so this is about whether we need to raise it for you, not about a bill.
  • Which language. Greek is fully translated alongside English. If you need a third, it is a locale row and a translation pass rather than a new schema.
  • What is missing. The honest gaps are footage on the long tail, and the mechanic/force classification. Both are queues we work through, and both get reordered by what people actually ask for — so ask.