GymApp SaaS API · v1
Small backend that fetches the free-exercise-db catalog (yuhonas/free-exercise-db, public domain), normalizes it into the app's domain shape, and serves it with low latency. Public read endpoints, plus an admin sync endpoint guarded by a bearer token.
GET/v1/healthz
Liveness probe. Returns 200 OK when the server is up.
Response 200
{ "ok": true }
Try it
curl http://localhost:8787/v1/healthz
GET/v1/exercises
Paginated list of exercises. Sorted by group then name.
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
limit | integer | 1000 | Max items returned. Capped at 2000. |
offset | integer | 0 | Offset into the sorted list. |
Response 200
{
"count": 800,
"results": [
{
"id": "free-exercise-db:Barbell_Squat",
"name": "Barbell Squat",
"description": "Begin with a barbell supported on top of the traps ...",
"imageUrl": "https://raw.githubusercontent.com/yuhonas/free-exercise-db/main/exercises/Barbell_Squat/0.jpg",
"group": "Quadriceps",
"muscles": ["Quadriceps", "Calves", "Glutes", "Hamstrings", "Lower Back"],
"muscleSlugs": ["quadriceps"],
"muscleSlugsSecondary": ["calves", "gluteal", "hamstring", "lower-back"],
"equipment": ["barbell"],
"category": "Strength",
"level": "Beginner"
}
]
}
About muscle slugs.
muscleSlugs and
muscleSlugsSecondary are normalized to the
react-native-body-highlighter taxonomy, derived at sync
time from the source dataset's primaryMuscles and
secondaryMuscles lists.
Try it
curl 'http://localhost:8787/v1/exercises?limit=2'
GET/v1/exercises/:id
Single exercise by id. IDs are composite <source>:<sourceId> (e.g. free-exercise-db:Barbell_Squat).
Response 200
{
"id": "free-exercise-db:Barbell_Squat",
"name": "Barbell Squat",
"description": "...",
"imageUrl": "https://raw.githubusercontent.com/yuhonas/free-exercise-db/main/exercises/Barbell_Squat/0.jpg",
"group": "Quadriceps",
"muscles": ["Quadriceps", "Calves", "Glutes", "Hamstrings", "Lower Back"],
"muscleSlugs": ["quadriceps"],
"muscleSlugsSecondary": ["calves", "gluteal", "hamstring", "lower-back"],
"equipment": ["barbell"],
"category": "Strength",
"level": "Beginner"
}
Response 404
{ "error": "not_found" }
Try it
curl http://localhost:8787/v1/exercises/free-exercise-db:Barbell_Squat
POST/v1/admin/sync
Force a fresh sync from free-exercise-db. Upserts every catalog entry and recomputes muscle slugs from the source data.
Admin endpoint enabled —
SAAS_ADMIN_TOKEN is set.Headers
| Name | Value |
|---|---|
Authorization | Bearer <SAAS_ADMIN_TOKEN> |
Response 200
{
"totalSeen": 800,
"inserted": 0,
"updated": 800,
"skipped": 0,
"durationMs": 6800
}
Response 401 / 404
{ "error": "unauthorised" }
{ "error": "not_found" }
Try it
curl -X POST -H 'Authorization: Bearer <your-token>' \
http://localhost:8787/v1/admin/sync