Base URL: /api/v1. All responses are JSON with a { success, count?, data } envelope. No auth, no API key.
| Method | Path | Description |
|---|---|---|
GET | /api/v1/exercises | List all exercises. Query: bodyPart, equipment, target, difficulty, search, limit, offset |
GET | /api/v1/exercises/:id | Fetch one exercise by id |
GET | /api/v1/search?q= | Search by name, alias, target or muscle (min 2 chars) |
GET | /api/v1/bodyparts | Body-part facets with counts |
GET | /api/v1/equipment | Equipment facets with counts |
GET | /api/v1/targets | Target-muscle facets with counts |
curl https://your-instance/api/v1/exercises?bodyPart=back&limit=1{
"success": true,
"count": 317,
"data": [
{
"id": "0489",
"name": "45 Degree Hyperextension",
"bodyPart": "back",
"target": "erector spinae",
"equipment": "leverage machine",
"difficulty": "beginner",
"steps": ["…"],
"formCues": ["Keep back straight", "Hinge from hips"],
"commonMistakes": ["Rounding the back"],
"videos": {
"male": "https://…/exercise-videos/male/45-degree-hyperextension.mp4",
"female": "https://…/exercise-videos/female/45-degree-hyperextension.mp4"
},
"thumbnails": { "male": "https://…/male/45-degree-hyperextension.jpg" }
}
]
}The hosted demo caps each IP at 4 requests, returning 429 with { error: { code: "DEMO_LIMIT" } }. Self-hosted instances are unlimited (set DEMO_MODE unset/false).
A machine-readable spec ships at openapi.yaml in the repo root.