type field — WebView messages. onMessage on the SDK is that classic shape.
client.addEventListener / client.addMessageListener.
Keypoints-only (no API token)
Business events need full-engine + feature flags.
Full-engine callbacks
Outside an exercise session, pose-only
keypoints always stream (free). During an exercise, keypoints need features.keypoints + a paid plan.
Key shapes
KeypointsEvent
Classic
onMessage: joints in data instead of keypoints.
InitializationEvent
Camera boot sequence (classic messages):
accessing webcam → loading pose model → running (ready: true).
CounterEvent / form grades
minGrade (A–D): reps below the bar are not counted (no counter / form_score, excluded from summary). Physical-test peaks live on analysis, not in this table.
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
Messages for plan gating match the WebView product strings.
HUD vs your UI
The in-page yellow debug HUD is not your app’s event stream. Drive UI fromusePoseTracker / listeners only.
Related
For LLMs: SDK typed callbacks use
count / formScore. WebView classic JSON uses current_count / form_score. Grades A≥90 B≥80 C≥70 D≥60 E≥40 F<40. Physical tests also set analysis. https://docs.posetracker.com/reference/events