> For the complete documentation index, see [llms.txt](https://posetracker.gitbook.io/posetracker-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://posetracker.gitbook.io/posetracker-api/use-posetracker-on-real-time-camera-webcam/query-params-details/exercise-optional/jump-analysis-jump_analysis.md).

# Jump analysis (jump\_analysis)

Measure **vertical jump height** from the user’s hip movement in pixels.

This mode needs a user-provided height (`userHeightCm`).

See also:

* [Shared query parameters (Tracking + Upload Tracking)](/posetracker-api/posetracker-api-query-parameters.md)
* [Upload Tracking endpoint (video & image)](/posetracker-api/use-posetracker-on-uploaded-files/upload-tracking-endpoint-video-and-image.md)
* [WebView messages (Upload Tracking)](/posetracker-api/use-posetracker-on-uploaded-files/upload-tracking-endpoint-video-and-image/webview-native-messages.md)

### Overview

#### What you get

* Live **jump detection** and **jump height** estimates.
* A one-time **calibration** step to lock a baseline and scale.
* Optional **device pitch correction**.

#### Key features

* Uses only **hip keypoints** (`left_hip`, `right_hip`).
* Works in **real time** (`/pose_tracker/tracking`) and on **video** (`/pose_tracker/upload_tracking`).
* Emits simple PostMessage events: `posture`, `jump_calibration`, `jump_started`, `jump_height`, `jump_summary`, `error`.

### Prerequisites

#### Required query parameters

* `exercise=jump_analysis`
* `token=...`
* `userHeightCm=...` (number, centimeters)

If `userHeightCm` is missing or invalid, the iframe sends an `error` event with:

* `error: "jump_analysis_missing_height"`

#### Optional query parameters

* `devicePitchDeg=...` (number, degrees)
  * Used to compensate for a camera pitched up/down.
  * See **Measurement algorithm**.

#### Tracking prerequisites (pose)

* Both hip keypoints must be detected with **score > 0.5**.
* The full body should be visible.
* The camera must stay fixed.

### Comparison: jump\_analysis vs air\_time\_jump

Use this when you can provide user height.

| Aspect      | jump\_analysis                                                       | air\_time\_jump                                                |
| ----------- | -------------------------------------------------------------------- | -------------------------------------------------------------- |
| User height | Required (`userHeightCm`)                                            | Not required                                                   |
| Calibration | Yes (stable standing → `baselineY` + `cmPerPixel` from frame height) | No (dynamic baseline from recent frames)                       |
| Scale       | Pixel-to-cm via `cmPerPixel`                                         | Time-to-height via physics                                     |
| Formula     | `jumpHeightCm = (baselineY - minY) * cmPerPixel`                     | `h = (1/8)*g*t²`, then cm                                      |
| Outputs     | jumpHeightCm, deltaPixels, cmPerPixel, baselineY, minY               | jumpHeightCm, airTimeMs, airTimeSeconds, baselineY, minY       |
| Use when    | User height is known; you want a scale tied to frame/user            | User height unknown; you want a simple, physics-based estimate |

Also see: [Air time jump (air\_time\_jump)](/posetracker-api/use-posetracker-on-real-time-camera-webcam/query-params-details/exercise-optional/air-time-jump-air_time_jump.md)

### Exercise detection

Always pass `exercise=jump_analysis` to enable jump height mode.

### API endpoints

#### Live (camera)

Base URL:

```
https://app.posetracker.com/pose_tracker/tracking
```

Example:

```
https://app.posetracker.com/pose_tracker/tracking?token=YOUR_API_KEY&exercise=jump_analysis&userHeightCm=178
```

#### Upload Tracking (video)

Base URL:

```
https://app.posetracker.com/pose_tracker/upload_tracking
```

Example:

```
https://app.posetracker.com/pose_tracker/upload_tracking?token=YOUR_API_KEY&source=video&exercise=jump_analysis&userHeightCm=178
```

Common optional flags on video:

* `export=true` (keeps the last frame visible and enables export UI)
* `skeleton=true|false`
* `keypoints=true` (plan-gated)

### PostMessage events

These events are sent from the iframe/WebView to your host app.

If you’re new to placement messages, read: [Exercise Placement](/posetracker-api/use-posetracker-on-real-time-camera-webcam/tracking-endpoint-message-to-handle/exercise-placement.md).

#### `posture`

Sent continuously to guide placement.

```json
{
  "type": "posture",
  "message": "...",
  "direction": "in-frame",
  "ready": false,
  "requirements": []
}
```

#### `jump_calibration` (jump\_analysis only)

Sent while the user is standing still for calibration.

Payload varies by version.

You should treat this as:

* a progress/ready signal
* plus optional debug fields (baseline, scale)

```json
{
  "type": "jump_calibration",
  "ready": false,
  "message": "Hold still"
}
```

#### `jump_started`

Sent once when upward movement crosses the detection threshold.

```json
{
  "type": "jump_started"
}
```

#### `jump_height`

Sent during measurement of a jump.

```json
{
  "type": "jump_height",
  "jumpHeightCm": 34.2,
  "deltaPixels": 171,
  "cmPerPixel": 0.2,
  "baselineY": 512.3,
  "minY": 341.3,
  "devicePitchDegUsed": 0,
  "final": true
}
```

Notes:

* `deltaPixels = baselineY - minY` (hip Y decreases when the user goes up).
* `final=true` indicates the jump is completed (landing detected).

#### `jump_result`

Sent at the end of a jump.

```json
{ 
  type: "jump_result",
  jumpNumber: number,
  jumpHeightCm: number,
  airTimeMs?: number,
  airTimeSeconds?: number,
  baselineY?: number,
  minY?: number,
  deltaPixels?: number,
  visibleHips?: object
}
```

#### `jump_summary` (video)

Sent at the end of a video analysis. And after every new jump (after the `jump_result`) on real-time mode.

Multiple jumps can be detected in a single clip.

Heights are in **centimeters**.

```json
{
  "type": "jump_summary",
  "totalJumps": 3,
  "avgJumpHeight": 32.1,
  "maxJumpHeight": 38.4,
  "minJumpHeight": 27.9,
  "final": true
}
```

#### `error`

Sent on invalid config or runtime failures.

```json
{
  "type": "error",
  "error": "jump_analysis_missing_height",
  "message": "userHeightCm is required"
}
```

### Placement overlay behavior

* Uses the standard placement system (`posture`).
* You should keep the user **centered** and **fully in frame**.
* Calibration only becomes ready when hip Y is stable for \~1 second.

### User flow

1. **Placement**: wait for `posture.ready=true`.
2. **Calibration**: wait for `jump_calibration.ready=true`.
3. **Jump**:
   * Receive `jump_started`.
   * Receive `jump_height` updates.
   * Consider the jump complete when `jump_height.final=true`.

### Measurement algorithm

#### 1) Hip signal

* Read `left_hip` and `right_hip` keypoints.
* Require **score > 0.5**.
* Use a single hip Y signal (implementation may average hips).

#### 2) Baseline calibration

* The user must stand still for a short stable window (\~1s).
* Baseline:

```
baselineY = average(hipY over stable window)
```

#### 3) Pixel-to-cm scale

Scale is derived from user height and the frame height.

```
cmPerPixel = userHeightCm / (frameHeight * 0.9)
cmPerPixel = clamp(cmPerPixel, 0.2, 2.0)
```

Important:

* Current implementation does **not** use ankle-to-hip pixel distance.
* It uses **frame height × 0.9** as an approximate body span.

#### 4) Jump detection + landing

* Jump starts when hip moves up by **> 15 px** from baseline.

```
started when (baselineY - hipY) > 15
```

* Landing when hip returns to within **10 px** of baseline.

```
landed when abs(hipY - baselineY) < 10
```

#### 5) Height calculation

During the jump, track the minimum hip Y (`minY`).

```
deltaPixels = baselineY - minY
jumpHeightCm = deltaPixels * cmPerPixel
```

#### 6) Optional pitch correction

If `devicePitchDeg` is provided, height can be corrected by:

```
pitchRad = devicePitchDeg * PI / 180
jumpHeightCmCorrected = jumpHeightCm / cos(pitchRad)
```

The handler clamps the pitch it uses.

### Integration examples

#### Web (iframe)

```html
<iframe
  id="posetracker"
  src="https://app.posetracker.com/pose_tracker/tracking?token=YOUR_API_KEY&exercise=jump_analysis&userHeightCm=178"
  style="width:100%;height:100%;border:0;"
  allow="camera;microphone"
></iframe>

<script>
  window.addEventListener('message', (event) => {
    const msg = event.data;
    if (!msg || !msg.type) return;

    switch (msg.type) {
      case 'posture':
        // show msg.message, gate your UI on msg.ready
        break;
      case 'jump_calibration':
        // show calibration progress; wait for ready=true
        break;
      case 'jump_started':
        // start your timer/animation
        break;
      case 'jump_height':
        // msg.jumpHeightCm + debug fields
        break;
      case 'jump_summary':
        // video-only aggregate
        break;
      case 'error':
        console.error(msg);
        break;
    }
  });
</script>
```

#### Upload Tracking (video URL)

```
https://app.posetracker.com/pose_tracker/upload_tracking?token=YOUR_API_KEY&source=video&videoSrc=https://your-cdn.com/jump.mp4&exercise=jump_analysis&userHeightCm=178&export=true
```

When `export=true`, the last analyzed frame stays visible.

### Best practices and limitations

#### Best practices

* Keep the camera fixed and avoid zoom changes.
* Keep the user fully visible (especially hips).
* Ask the user to stand still for calibration.

#### Limitations

* Absolute height depends on the `userHeightCm` you provide.
* Any camera pitch reduces vertical pixel motion. Use `devicePitchDeg` when you can.
* This measures **hip vertical displacement**, not true COM displacement.

### Troubleshooting

* Getting `jump_analysis_missing_height`:
  * Pass `userHeightCm` as a number in centimeters.
* Calibration never becomes ready:
  * Improve lighting.
  * Ensure hips are visible and stable.
  * Reduce camera shake.
