Integrate in one afternoon
54 exercises, each with a multi-frame demonstration in male and female variants. One API for the metadata, one URL pattern for the images.
Quickstart
Three steps to an image on screen.
1. Fetch the catalogue
curl https://api.moveindex.dev/v1/exercises \
-H "Authorization: Bearer $MOVEINDEX_KEY" 2. Read an image URL from the response
{
"slug": "plank",
"name": "Plank",
"frame_count": 2,
"images": {
"male": "https://cdn.moveindex.dev/$MOVEINDEX_KEY/exercises/plank-male.png",
"female": "https://cdn.moveindex.dev/$MOVEINDEX_KEY/exercises/plank-female.png"
},
"watermarked": false
} 3. Render it
<img src="https://cdn.moveindex.dev/$MOVEINDEX_KEY/exercises/plank-male.png"
alt="Plank 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.
# API
curl https://api.moveindex.dev/v1/exercises -H "Authorization: Bearer xdb_…"
# Images
https://cdn.moveindex.dev/xdb_…/exercises/plank-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, it cannot change anything, and you can rotate or revoke it at any time without a code change if you keep it in an environment variable. If you would rather it never reach the client, proxy image requests through your own server.
Images
Two canvases, two variants, one URL pattern.
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_count | Canvas | Typical |
|---|---|---|
| 3 | 768 × 1376 | most exercises |
| 2 | 896 × 1200 | holds 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
/v1/exercises Search and filter the catalogue.
params: muscle, equipment, category, q, limit, offset
/v1/exercises/:slug One exercise. Aliases resolve to their canonical entry.
/v1/meta Every filter value with live counts.
/v1/usage What this key has requested.
/health Unauthenticated liveness check.
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
- quads (12)
- core (9)
- back (9)
- glutes (6)
- hamstrings (5)
- chest (4)
- full_body (3)
- shoulders (3)
- forearms (2)
- calves (1)
equipment
- dumbbell (16)
- bodyweight (13)
- barbell (11)
- cable (3)
- sled (3)
- sandbag (2)
- pull_up_bar (2)
- kettlebell (1)
- medicine_ball (1)
- machine (1)
- band (1)
category
- strength (40)
- core (7)
- hyrox (6)
- mobility (1)
Errors
Every failure returns JSON with a stable error code.
missing_key No Authorization header, or it does not start with xdb_. invalid_key The key is unknown or has been revoked. inactive_key Billing has lapsed. The key exists but is not active. upgrade_required A free key asked the CDN for a clean original. 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.
Free tier
Integrate before you pay.
A free key returns the same metadata and the same URL shapes, pointing at watermarked
560px previews. Every field your integration reads is identical, so switching to a
paid key changes the pictures and nothing else. Responses carry
"watermarked": true so you can tell.
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.