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

# Features & plans

> Feature flags, plan gating matrix, form grades, watermark, and error messages.

The **SDK** and the **WebView** share the same plan gating and error messages. SDK keypoints without a token are free; the WebView tracking URL always needs `token=`. Overlay/timer colors stay WebView-only.

## Free vs paid

| | No API key | With API key |
| - | - | - |
| Keypoints (pose-only) | **Free** — offline package needs no network; light needs CDN/model | Same |
| Movement engine / exercises | No | Yes (handshake + metering) |
| Developer streams (`angles`, …) | Blocked | Paid plans only |

With a key, internet is required to authenticate and meter (`POST /api/sdk/configure`, `POST /api/sdk/track` `camera_start`). Offline metered sessions refuse key-gated features (`offline_metered`); keypoints-only keeps running from cache.

## Feature flags

Set on the provider:

```tsx theme={null}
<PoseTrackerProvider
  apiToken="ptk_…"
  options={{
    features: {
      angles: true,
      recommendations: true,
      progression: true,
      keypoints: false, // keypoints DURING an exercise
      minGrade: 'B',
    },
  }}
>
```

| Flag | Default | Meaning |
| - | - | - |
| `angles` | `false` | Stream `angles` during exercise — paid |
| `recommendations` | `false` | Form advice strings — paid. Not sent for every exercise; use `counter` / `onCounter.formScore` for the grade |
| `progression` | `false` | 0–100 within the current rep or hold — paid |
| `keypoints` | `false` | Raw keypoints **during** an exercise — paid. Pose-only (no exercise) always streams. |
| `minGrade` | — | `'A'…'D'` — only count reps at/above this grade |

Not supported as **features flags**: `blazepose`, `poseEngine`, `mediapipeModel`,
`poseBackend`, `runInWorker` → `feature_not_supported`.
Select BlazePose with `options.model = 'blazepose'` on light / web (not via `features`).

## Plan gating matrix

Plan type from handshake (`plan.plan` / `client.getPlanType()`).

| Plan | angles / recommendations / progression | keypoints + exercise | Exercises |
| - | - | - | - |
| No key | Blocked | Blocked | No |
| `free` | **Blocked** | **Blocked** | Yes (non-premium list) |
| `developer`+ | OK if flags on | OK if flag on | Yes |

### When gating runs

1. **configure / preload** — `free` + angles/recommendations/progression → `free_plan_feature_blocked` (one-shot). Keypoints-only keeps running.
2. **`startExercise()`** — re-check; on `free`, `features.keypoints` also blocks. Throws with the same message.

### Emission filtering (during exercise)

| Event | Requires |
| - | - |
| `angles` | `features.angles` |
| `recommendations` | `features.recommendations` |
| `progression` | `features.progression` |
| `keypoints` | `features.keypoints` (outside session: always on) |
| `counter`, `posture`, `form_score`, `exercise_summary` | Always (core streams) |

## Form grades & minGrade

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

Authoritative counted-rep grade: nested on `onCounter` → `formScore` (classic `counter.form_score`). Standalone `form_score` is convenience only.

`minGrade: 'B'` counts A and B only; below-bar reps emit neither `counter` nor `form_score`.

## Watermark

On the free plan, and when no API key is set, the live camera shows a dofollow link. The anchor text is **Powered by PoseTracker**. It opens `https://www.posetracker.com/` with `utm_source=watermark`. The medium is `webview` on the tracking page, `react-native` in the React Native SDK (`Linking.openURL`), and `web-sdk` in the web SDK.

Developer and Business plans do not show the link. The same removal applies to any paid plan (`developer`, `company`, `enterprise`, custom).

| Plan | Watermark on live camera |
| - | - |
| Keyless / `free` | Link shown |
| Paid | Hidden |

To remove it on a build that would otherwise show it, set `showWatermark={false}` on `WebViewPoseView` (React Native) or `showWatermark: false` in `createPoseTracker` (web). Omitting the prop keeps the plan rule. `coldStart: 'basic'` warmers never show it. A plan upgrade after `configure()` hides it without remounting.

## WebView param → SDK map

| WebView query | SDK |
| - | - |
| `token` | `apiToken` / `configure(apiToken)` |
| `exercise` | `startExercise(id, options?)` |
| `userExercise` | **WebView only** — Studio custom UUID |
| `difficulty` | SDK `startExercise(id, { difficulty })` only — **not read** by the tracking URL |
| `userHeightCm` / `devicePitchDeg` | `StartExerciseOptions` |
| `skeleton` | `drawSkeleton` / `skeletonUuid` / `skeletonDef` |
| `loading_message` | `loadingText` |
| `postureBox` | `drawPlacementBox` |
| `angles` / `recommendations` / `progression` / `keypoints` / `minGrade` | `options.features.*` |
| `reference` / `reference_movement` | **WebView only** — not in the SDK yet. See [Reference movement](/webview/reference-movement) |
| `placementOverlay`, colors, `timer`, `guide` | **WebView only** — [query parameters](/webview/query-params) |

## Common error codes

| Situation | `code` |
| - | - |
| Dev features, no token | `invalid_token` |
| Unknown exercise | `invalid_exercise` |
| `jump_analysis` without height | `jump_analysis_missing_height` |
| Free + developer features | `free_plan_feature_blocked` |
| Unsupported `features` keys (use `options.model` for BlazePose) | `feature_not_supported` |
| Offline + key at camera start | `offline_metered` |
| Quota | `quota_exceeded` |
| Revoked token | `invalid_token` (caches purged → keypoints-only) |

## Related

* [API key](/api-key)
* [Exercises](/reference/exercises)
* [Events](/reference/events)
* [WebView query parameters](/webview/query-params)

<Note>
  **For LLMs:** Same gating on WebView and SDK. BlazePose is `options.model`, not a features flag. `difficulty` is SDK-only. `reference=` is WebView-only. Overlay/timer params are WebView-only. [https://docs.posetracker.com/reference/features-plans](https://docs.posetracker.com/reference/features-plans)
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.