Errors & Access Rules
Errors
Every error is a JSON object with an error string, sometimes with details or message alongside it.
| Status | Body | Cause |
400 | {"error": "Invalid level value: must be an integer"} | Non-numeric ?level= on the plan list |
401 | {"error": "Unauthorized"} | No x-api-key and no Authorization header |
401 | {"error": "Invalid API key"} | The key is not recognized |
403 | {"error": "User does not belong to this company"} | The x-user-id you sent belongs to another company |
404 | {"error": "User not found"} | The x-user-id you sent does not exist yet |
404 | {"error": "Workout not found"} | No workout matches that ID or title in your scope |
404 | {"message": "Exercise not found", "details": "..."} | No exercise matches that ID or title in your scope |
404 | {"error": "Plan not found", "message": "..."} | No plan matches that ID or title in your scope |
429 | {"error": "<limit message>"} | Your company's daily read quota is spent |
500 | {"error": "Failed to fetch exercises"} | Server-side failure, safe to retry |
An unrecognized filter value is not an error. You get 200 with an empty array and pagination.total: 0.
A sane client treats 401 and 403 as configuration bugs (do not retry), 404 as "this content is not in your catalog", 429 as back-off-and-retry-later, and 500 as retry with exponential backoff.
Access rules
You see two pools of content:
1. Your own content, created by your company in the KinesteX admin panel or through the API.
2. The shared KinesteX library, included by default on every list.
| Setting | Effect |
include_shared_library=true (default) | Your content plus the active shared library |
include_shared_library=false | Your content only |
include_shared_library=false removes the shared library, never your own content.
Deactivated content
| Catalog | Your own deactivated items | Deactivated shared-library items |
| Exercises | Hidden unless remove_inactive=false | Always hidden |
| Workouts | Visible in lists | Always hidden from lists |
| Plans | Visible in lists | Always hidden from lists |
Single-item fetches by ID are deliberately not gated on the active flag: content a plan or a saved workout already references keeps resolving after it is retired from the catalog.
Workouts generated for individual users' personalized plans are excluded from the shared-library listing, and personal (AI-generated) plans are excluded from the plan list entirely.
Rate limits
Content reads count against your company's daily read quota. When it is exhausted the API returns 429 with the limit message in error. If you are running a bulk sync and hit it, contact KinesteX to raise the quota rather than retrying in a tight loop.