KinesteX

Getting Started

Everything on this page applies to all six endpoints.


Authentication


Send one of the two credentials. If an Authorization header is present it wins and the API key is ignored.


HeaderUse when
x-api-key: YOUR_API_KEYServer to server, or SDK calls made on behalf of your company
Authorization: Bearer YOUR_JWTA signed-in end user (see obtaining a JWT)
x-user-id: END_USER_IDOptional, alongside x-api-key, to resolve a specific end user

x-user-id only matters for plan progress: with it, GET /api/plans/client/{id} returns that user's completion flags. For pure catalog reads you can leave it out.


Keep your company API key on your server. A client app should send a user JWT instead. These endpoints do not accept a raw session ID.

Two ways to get that JWT, both starting on your backend:


  • Call verify-api-key with your API key and the user's ID, then hand the returned token to the client.
  • Mint a short-lived session with POST /api/sessions, ship the session ID to the client, and have the client exchange it for a JWT at POST /api/auth/session-verify with an x-session-id header. The token it returns expires with the session, so the client can never outlive it. Full request and response shapes are in Session tokens.

Either way the client then sends Authorization: Bearer <token> on these requests.


Language


One value controls the language of every title, description, tip, and step in the response. Resolution order, highest first:


1. ?lang=es query parameter

2. Language: es header

3. Accept-Language: es-MX,es;q=0.9 header (the first entry wins)

4. English


All sources are normalized to the ISO 639-1 base code, so es, ES, es-MX, and pt_BR resolve the way you expect in whichever form you send them. en-GB and EN both resolve to en.


Where ?lang= is honored:


Endpoint?lang=Missing translation falls back to English
GET /api/exercises/clientYesYes
GET /api/exercises/client/{id}YesYes
GET /api/workouts/clientYesNo, see below
GET /api/workouts/client/{id}YesYes
GET /api/plans/clientYesYes
GET /api/plans/client/{id}No, headers onlyYes

Two exceptions worth coding around:


  • The single-plan endpoint ignores the lang parameter. GET /api/plans/client/{id} reads the Language or Accept-Language header only.
  • The workout list does not fall back to English. If you request ?lang=es and a workout has no Spanish row, that workout's translation is null while translation_languages still lists what exists. Handle the null, narrow the list with translation_languages=es, or pass include_exercises=true (that path does fall back to English).

Recommended: send the Language header on every request and ?lang= on list requests. The header covers the endpoints that only read headers; the parameter makes the language explicit in the cache key and in your logs.

Supported language codes


Any ISO 639-1 code is accepted; what you get back is whatever translations exist. The platform languages KinesteX ships today are listed in Language & Localization, and more can be added on request.


Coverage is per item, not global. Read translation_languages on a list item to see what that item actually has, or filter the list with translation_languages=<code> to return only items that have it. An unknown or untranslated code is never an error: you get English (or, on the workout list, a null translation).


Media URLs


Image, video, and audio URLs are returned as Firebase Storage download URLs (https://firebasestorage.googleapis.com/v0/b/.../o/<path>?alt=media). Treat them as opaque: fetch them as-is, and do not rebuild or parse the path. They are stable for the lifetime of the asset but the host and encoding are an implementation detail.