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.

Base URL on this host: http://localhost:8787 · listen 0.0.0.0:8787 · DB /app/data/exercises.sqlite

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
NameTypeDefaultDescription
limitinteger1000Max items returned. Capped at 2000.
offsetinteger0Offset 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 enabledSAAS_ADMIN_TOKEN is set.
Headers
NameValue
AuthorizationBearer <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