# 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.

---
Source: https://www.kinestex.com/docs/content-api-v2/content-api-v2-errors · Index: https://www.kinestex.com/llms.txt
