# Calorie Calculation API

Compute calories for activity done **outside** the KinesteX player (for example a workout logged in your own app) with the same calorie model the player uses. Send the exercises and how long they took; you get a per-exercise breakdown.

```
POST https://data.kinestex.com/api/calories/calculate
```

Requires the same JWT Bearer token as the trainer endpoints (see [Authentication](/docs/trainer-api/trainer-api-auth)) and counts against your company's read quota.

**Request fields:**

| Field | Required | Description |
|-------|----------|-------------|
| `exercises` | **Yes** | 1-100 entries. The response has one result per entry, in the same order |
| `exercises[].duration_seconds` | **Yes** | Total time on the exercise, more than 0 and at most 86400 |
| `exercises[].exercise_id`, `exercise_title` or `met` | One of them | KinesteX exercise ID (number), English exercise title (case and punctuation insensitive), or an explicit MET for activity outside the library (clamped to 1-20, wins over ID and title) |
| `exercises[].reps` | No | Reps completed (0-10000). Each rep counts 5 seconds at the exercise MET; the rest of the duration counts at idle MET 2 |
| `exercises[].perfect_position_seconds` | No | For holds (plank, wall sit): seconds in the correct position, counted at the exercise MET; the remainder at idle MET 2. Wins over `reps` |
| `user_profile` | No | `{ "weight", "height", "age", "gender" }` in kg, cm, years and `"male"` / `"female"`. With all four, BMR uses Mifflin-St Jeor; otherwise a default BMR of 1700. BMR is clamped to 1000-2800 |
| `rest_seconds` | No | Rest between exercises (0-86400), counted at MET 2 |
| `apply_calibration` | No | Default `true`: every calorie value is multiplied by 1.5, the device-calibration factor the KinesteX player uses so numbers match typical consumer fitness devices. `false` returns the uncalibrated MET x BMR estimate |

Without `reps` or `perfect_position_seconds`, the whole duration counts at the exercise MET.

```bash
curl -X POST "https://data.kinestex.com/api/calories/calculate" \
  -H "Authorization: Bearer <jwt>" -H "Content-Type: application/json" \
  -d '{
    "user_profile": { "weight": 80, "height": 180, "age": 30, "gender": "male" },
    "rest_seconds": 120,
    "exercises": [
      { "exercise_id": 512, "duration_seconds": 60, "reps": 12 },
      { "exercise_title": "Plank", "duration_seconds": 60, "perfect_position_seconds": 45 },
      { "exercise_title": "Treadmill Run", "duration_seconds": 600, "met": 9.8 }
    ]
  }'
```

**Response:**

```json
{
  "exercises": [
    {
      "exercise_id": 512,
      "exercise_title": "Squats",
      "duration_seconds": 60,
      "reps": 12,
      "met": 7.8,
      "met_source": "ai_model",
      "active_seconds": 60,
      "calories": 14.46
    }
  ],
  "total_exercise_calories": 201.97,
  "rest_seconds": 120,
  "rest_calories": 7.42,
  "total_calories": 209.38,
  "bmr": 1780,
  "bmr_source": "profile",
  "calibration_applied": true,
  "calibration_factor": 1.5
}
```

- `met_source`: `"request"` (your `met`), `"ai_model"` (from the exercise's motion-tracking model), or `"default"` (MET 4; the entry then carries a `warning` such as `"exercise not found; used default MET"`). Unknown exercises do not fail the batch.
- `active_seconds`: time counted at the exercise MET; the rest of the duration counted at idle MET 2.
- `bmr_source`: `"profile"` or `"default"`. `calibration_factor` is `1.5` or `1` and is already included in every calorie value.
- ID and title lookups see your company's own exercises plus the active KinesteX library.

**Errors:** `400` (empty or oversized batch, non-positive duration, an entry with no `exercise_id`, `exercise_title` or `met`, out-of-range values; the message names the entry index), `401` (missing or invalid JWT), `429` (company quota), `500`.

---
Source: https://www.kinestex.com/docs/trainer-api/trainer-api-calories · Index: https://www.kinestex.com/llms.txt
