Skip to content

Integrate in one afternoon

44 exercises, each with a multi-frame demonstration in male and female variants. One exercise image API for the metadata, one URL pattern for the images. New here? Start with what the exercise database API returns.

Quickstart

Three steps to an image on screen.

First, get a key

Free, no card. Either sign up in the portal, or straight from your terminal:

bash
curl -X POST https://api.moveindex.dev/v1/signup \
  -H "content-type: application/json" \
  -d '{"email":"you@example.com"}'

1. Fetch the catalogue

bash
curl https://api.moveindex.dev/v1/exercises \
  -H "Authorization: Bearer $MOVEINDEX_KEY"

2. Read an image URL from the response

json
{
  "slug": "farmer-carry",
  "name": "Farmer Carry",
  "frame_count": 2,
  "images": {
    "male":   "https://cdn.moveindex.dev/$MOVEINDEX_KEY/exercises/farmer-carry-male.png",
    "female": "https://cdn.moveindex.dev/$MOVEINDEX_KEY/exercises/farmer-carry-female.png"
  },
  "watermarked": false
}

3. Render it

html
<img src="https://cdn.moveindex.dev/$MOVEINDEX_KEY/exercises/farmer-carry-male.png"
     alt="Farmer Carry demonstration" />

You can also build the URL yourself from a slug rather than storing ours — the pattern is stable and documented below.

Authentication

The API takes a bearer token. The image CDN takes the key in the path, because an <img> tag cannot send headers.

bash
# API
curl https://api.moveindex.dev/v1/exercises -H "Authorization: Bearer xdb_…"

# Images
https://cdn.moveindex.dev/xdb_…/exercises/farmer-carry-male.png

Your CDN key is not a secret

It ships in your web bundle and inside your app binary, so treat it as a public identifier rather than a credential. It is read-only and cannot change anything, and you can restrict it to your own domains in the portal so a copied key is useless elsewhere. Rotating is instant, but if your framework inlines public variables at build time — Next, Vite, Expo all do — the key is compiled into your bundle, so a rotation needs a rebuild and deploy rather than a config change. If you would rather it never reach the client, proxy image requests through your own server.

Images

Two canvases, two variants, one URL pattern.

bash
https://cdn.moveindex.dev/{key}/exercises/{slug}-{male|female}.png

Each image is a single tall picture containing the phases of the movement stacked vertically. frame_count tells you how many.

frame_countCanvasTypical
3768 × 1376most exercises
2896 × 1200holds and carries

Images are dark-gym photographs, which sit well on dark interfaces and poorly on light ones. They are scenes, not cutouts, so they cannot be composited onto another background. Check one against your design before you commit.

Endpoints

GET /v1/exercises

Search and filter the catalogue.

params: muscle, equipment, category, q, limit, offset

GET /v1/exercises/:slug

One exercise. Aliases resolve to their canonical entry.

GET /v1/meta

Every filter value with live counts.

GET /v1/usage

What this key has requested.

GET /health

Unauthenticated liveness check.

bash
curl https://api.moveindex.dev/v1/exercises \
  -H "Authorization: Bearer $MOVEINDEX_KEY" \
  -G -d muscle=quads -d equipment=barbell -d limit=20

Filter values

Live counts from the catalogue. Nothing to guess.

muscle

  • core (9)
  • quads (9)
  • back (7)
  • glutes (5)
  • hamstrings (4)
  • chest (3)
  • full_body (3)
  • shoulders (2)
  • forearms (1)
  • calves (1)

equipment

  • bodyweight (13)
  • dumbbell (10)
  • barbell (8)
  • sled (3)
  • cable (2)
  • sandbag (2)
  • pull_up_bar (2)
  • kettlebell (1)
  • medicine_ball (1)
  • band (1)
  • machine (1)

category

  • strength (30)
  • core (7)
  • hyrox (6)
  • mobility (1)

Errors

Every failure returns JSON with a stable error code.

401 missing_key No Authorization header, or it does not start with xdb_.
403 invalid_key The key is unknown or has been revoked.
403 inactive_key Billing has lapsed. The key exists but is not active.
403 upgrade_required This key cannot fetch originals. Subscribe.
403 trial_expired The trial ran out. Subscribe to carry on.
403 origin_not_allowed The key is restricted to domains this request did not come from.
404 not_found No such exercise. We log these — they become the generation queue.

Image responses also carry an x-moveindex-error header, so a lapsed key is distinguishable from a missing file rather than looking like a broken image.

Trial

Seven days, everything, no card.

A trial key gets what a paid key gets: clean, full-resolution images, the full catalogue and every field. After seven days its images stop until you subscribe.

Licence

Every image is generated by us. There is no stock-photo chain, no model releases to chase and no unclear attribution — which is why we can license them cleanly for commercial use in your app.

Full terms are being drafted. Ask if you need them before then.