> ## Documentation Index
> Fetch the complete documentation index at: https://docs.posetracker.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Events catalog

> Typed callbacks, key shapes, classic onMessage parity, and error codes.

Two listening styles (pick one). Typed callbacks are recommended for new apps.

```tsx theme={null}
usePoseTracker({
  onInitialization: (e) => {},
  onKeypoints: (e) => {},
  onCounter: (e) => {},
  onError: (e) => console.error(e.code, e.message),
  // or classic:
  onMessage: (msg) => { /* WebView sendDataToNative shape */ },
});
```

Imperative: `client.addEventListener` / `client.addMessageListener`.

## Keypoints-only (no API token)

| Typed callback              | Classic `type`                   | When                                             |
| --------------------------- | -------------------------------- | ------------------------------------------------ |
| `onInitialization`          | `initialization`                 | Boot steps; `ready: true` when inference is live |
| `onKeypoints`               | `keypoints`                      | Every inferred pose                              |
| `onWarning`                 | `warning`                        | Soft issues                                      |
| `onError`                   | `error`                          | Failures (camera, model, webview, …)             |
| `onQualityChanged`          | `warning` (`quality_downgraded`) | Adaptive capture downgrade                       |
| `onPerformanceWarning`      | `error` (`device_too_slow`)      | Mean inference FPS critically low                |
| `onRuntimeDownloadProgress` | —                                | Rare remote runtime parts (legacy path)          |

Business events need [full-engine](/api-key) + [feature flags](/reference/features-plans).

## Full-engine callbacks

| Typed               | Classic `type`     | Key fields                                                                                                                                                          |
| ------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onCounter`         | `counter`          | `count`, `formScore?: { score, average, grade }` — **authoritative** grade for the counted rep. Classic: `current_count`, `form_score: { score, avg_score, grade }` |
| `onAngles`          | `angles`           | `angles: [{ id, side, degrees, score }]` — flag `features.angles`                                                                                                   |
| `onPosture`         | `posture`          | `ready`, `hint`, `direction?`, `missingKeypoints`                                                                                                                   |
| `onProgression`     | `progression`      | `value` 0–100 — flag `features.progression`                                                                                                                         |
| `onRecommendations` | `recommendations`  | `recommendations: string[]` — flag `features.recommendations`                                                                                                       |
| `onFormScore`       | `form_score`       | Convenience; prefer `onCounter.formScore`                                                                                                                           |
| `onExerciseSummary` | `exercise_summary` | `exercise`, `counter`, `averageFormScore`, `grade`, `history[]`                                                                                                     |
| Jump family         | `jump_*`           | See [Exercises](/reference/exercises)                                                                                                                               |

Outside an exercise session, pose-only `keypoints` always stream (free). During an exercise, keypoints need `features.keypoints` + a paid plan.

## Key shapes

### KeypointsEvent

| Field         | Type                      | Notes                                                 |
| ------------- | ------------------------- | ----------------------------------------------------- |
| `keypoints`   | `{ name, x, y, score }[]` | 17 COCO joints; x/y normalized 0–1 (mirrored preview) |
| `score`       | `number`                  | Mean pose confidence                                  |
| `timestampMs` | `number`                  | Frame time                                            |

Classic `onMessage`: joints in `data` instead of `keypoints`.

### InitializationEvent

| Field                     | Notes                                                                                                |
| ------------------------- | ---------------------------------------------------------------------------------------------------- |
| `step`                    | `configuring` \| `downloading` \| `warming` \| `accessing_webcam` \| `loading_pose_model` \| `ready` |
| `message`                 | Human string (WebView parity, e.g. `"running"`, `"accessing webcam"`)                                |
| `ready`                   | `true` when live                                                                                     |
| `mode?` / `acceleration?` | On ready                                                                                             |

Camera boot sequence (classic messages): `accessing webcam` → `loading pose model` → `running` (`ready: true`).

### CounterEvent / form grades

| Grade | Score |
| ----- | ----- |
| A     | ≥ 90  |
| B     | ≥ 80  |
| C     | ≥ 70  |
| D     | ≥ 60  |
| F     | \< 60 |

`minGrade` (A–D): reps below the bar are **not counted** (no `counter` / `form_score`, excluded from summary).

### QualityChangedEvent

`previousProfile`, `activeProfile`, `reason` (`low_fps` | `device_capability` | `crash_guard` | `warmup_estimate` | `manual`), `detail`, optional `estimatedFps` / `medianInferenceMs`.

### PerformanceWarningEvent

`code: 'device_too_slow'`, `meanFps`, `thresholdFps`, `activeProfile`, `message` (English, for developers — localize before showing end users).

## Error codes

| `code`                                                                | Typical cause                                                                       |
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `invalid_token`                                                       | Bad/revoked token, or developer features without a token                            |
| `quota_exceeded`                                                      | Plan quota                                                                          |
| `network` / `network_required`                                        | Handshake or required download failed                                               |
| `offline_metered`                                                     | API key present but camera\_start metering needs network — keypoints-only continues |
| `free_plan_feature_blocked`                                           | Free plan + angles / recommendations / progression / keypoints+exercise             |
| `feature_not_supported`                                               | BlazePose / MediaPipe-style options — SDK is MoveNet only                           |
| `invalid_exercise`                                                    | Unknown exercise id                                                                 |
| `jump_analysis_missing_height`                                        | Missing `userHeightCm`                                                              |
| `model_load_failed` / `engine_load_failed` / `integrity_check_failed` | Load / cache integrity                                                              |
| `webview_error`                                                       | WebView / page failure                                                              |
| `device_too_slow`                                                     | Also as `performance_warning`                                                       |
| `backend_fallback_wasm`                                               | GPU → WASM path                                                                     |
| `internal`                                                            | Unexpected                                                                          |

Messages for plan gating match the PoseTracker WebView product strings.

## HUD vs your UI

The in-page yellow debug HUD is **not** your app’s event stream. Drive UI from `usePoseTracker` / listeners only.

## Related

* [Keypoints quick page](/keypoints)
* [Features & plans](/reference/features-plans)
* [Adaptive quality](/advanced/adaptive-quality)
