# Air time jump (air\_time\_jump)

Measure **vertical jump height** from **air time** only.

This mode does **not** require `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.
* No explicit calibration step.
* Height computed from a simple physics model.

#### Key features

* Uses only **hip keypoints** (`left_hip`, `right_hip`).
* Dynamic baseline keeps tracking robust without calibration.
* Works in **real time** (`/pose_tracker/tracking`) and on **video** (`/pose_tracker/upload_tracking`).

### Prerequisites

#### Required query parameters

* `exercise=air_time_jump`
* `token=...`

#### Optional query parameters

* `devicePitchDeg=...` (number, degrees)
  * Accepted for consistency.
  * Height is driven by air time.

#### 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 user height is unknown.

| 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: [Jump analysis (jump\_analysis)](/posetracker-api/use-posetracker-on-real-time-camera-webcam/query-params-details/exercise-optional/jump-analysis-jump_analysis.md)

### Exercise detection

Always pass `exercise=air_time_jump` to enable air-time jump 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=air_time_jump
```

#### 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=air_time_jump
```

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`

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

#### `jump_started`

Sent once when upward movement crosses the trigger threshold.

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

#### `jump_height`

Sent during measurement and at the end of a jump.

```json
{
  "type": "jump_height",
  "jumpHeightCm": 29.7,
  "airTimeMs": 492,
  "airTimeSeconds": 0.492,
  "baselineY": 510.1,
  "minY": 355.8,
  "measuring": true,
  "landed": true,
  "final": true
}
```

Notes:

* `airTimeMs` covers the full airborne duration (takeoff → landing).
* Unlike `jump_analysis`, there is no `cmPerPixel` field.

#### `jump_summary` (video)

Sent at the end of a video analysis.

Multiple jumps can be detected in a single clip.

Heights are in **centimeters**.

Air times are in **seconds**.

```json
{
  "type": "jump_summary",
  "totalJumps": 4,
  "avgJumpHeight": 28.8,
  "maxJumpHeight": 33.5,
  "minJumpHeight": 22.1,
  "avgAirTimeSeconds": 0.48,
  "maxAirTimeSeconds": 0.53,
  "minAirTimeSeconds": 0.41,
  "final": true
}
```

#### `error`

```json
{
  "type": "error",
  "message": "..."
}
```

### Placement overlay behavior

* Uses the standard placement system (`posture`).
* Baseline is computed dynamically from recent hip Y values.
* Baseline can be locked when jump starts, and released after landing.

### User flow

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

### Measurement algorithm

#### 1) Hip signal + baseline

* Read `left_hip` and `right_hip` keypoints.
* Require **score > 0.5**.
* Keep a rolling window of recent hip Y values.
* Use that window to estimate a dynamic `baselineY`.

#### 2) Jump detection + landing

* Jump starts when upward movement exceeds **20 px** from baseline.
* A few consecutive frames are required to avoid false triggers.
* Landing occurs when hip Y returns within **20 px** of baseline.

#### 3) Air time

* Measure air time `t` from jump start to landing.

```
t = (landingTime - startTime) in seconds
```

#### 4) Height from physics

Use the vertical motion relationship:

* time up = time down = `t/2`
* initial vertical velocity at takeoff: `v = g * (t/2)`
* max height: `h = v² / (2g) = g * t² / 8`

Formula (meters):

```
h = (1/8) * g * t^2
```

Where:

* `g = 9.81 m/s²`
* `t` in seconds

Convert to centimeters:

```
jumpHeightCm = h * 100
```

### Integration examples

#### Web (iframe)

```html
<iframe
  id="posetracker"
  src="https://app.posetracker.com/pose_tracker/tracking?token=YOUR_API_KEY&exercise=air_time_jump"
  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':
        break;
      case 'jump_started':
        break;
      case 'jump_height':
        // msg.jumpHeightCm + msg.airTimeSeconds
        break;
      case 'jump_summary':
        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=air_time_jump&export=true
```

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

### Best practices and limitations

#### Best practices

* Use a high FPS camera when possible.
* Keep the camera fixed and avoid motion blur.
* Ensure clear landing visibility (hips must be tracked).

#### Limitations

* This assumes a mostly vertical ballistic jump.
* Arm swing and knee tuck can change air time.
* Landing detection is hip-based, not foot-contact-based.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://posetracker.gitbook.io/posetracker-api/use-posetracker-on-real-time-camera-webcam/query-params-details/exercise-optional/air-time-jump-air_time_jump.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
