Data Points
PostMessage events sent from KinesteX SDK for integration with native apps and external systems. Events are sent in real-time, work safely offline, and provide comprehensive tracking for workouts, exercises, and health assessments.
Receiving Data
Each platform has a specific pattern for receiving data from KinesteX.
SDK Platforms (Swift, Kotlin, React Native, React-TS, Flutter): Use the callback function provided by the SDK with typed message enums.
HTML/JS: Set up a message event listener manually since there's no SDK wrapper.
1// onMessageReceived callback passes WebViewMessage enum
2// Available message types:
3
4// kinestex_launched([String: Any]) - KinesteX View launched
5// finished_workout([String: Any]) - Workout completed
6// error_occurred([String: Any]) - Errors (e.g., missing camera)
7// exercise_completed([String: Any]) - Exercise finished
8// exit_kinestex([String: Any]) - User exits KinesteX view
9// workout_opened([String: Any]) - Workout description viewed
10// workout_started([String: Any]) - Workout begins
11// plan_unlocked([String: Any]) - Workout plan unlocked
12// custom_type([String: Any]) - Unrecognized messages
13// reps([String: Any]) - Successful repetitions
14// mistake([String: Any]) - Detected mistakes
15// left_camera_frame([String: Any]) - User left camera frame
16// returned_camera_frame([String: Any]) - User returned to frame
17// workout_overview([String: Any]) - Workout summary
18// exercise_overview([String: Any]) - Exercise summary
19// workout_completed([String: Any]) - Workout done, overview exitedApplication Lifecycle
Events for app startup, loading, and exit.
| Event | Data Fields | Description |
| kinestex_launched | data: string ("dd mm yyyy hh:mm:ss") | KinesteX application is launched |
| kinestex_loaded | date: string (ISO format) | KinesteX fully loaded and ready |
| exit_kinestex | date: Date, time_spent: string ("hh:mm:ss") | User exits with total time spent |
| main_page_opened | date: string (ISO format) | Main/home page is opened |
| home_page_opened | date: string (ISO format) | Home Page integration screen opened. Fires exactly once per mount |
| streak_extended | data: object | User's daily streak was extended by completing a qualifying activity (workout, challenge, plan day, assessment) |
streak_extended Data Structure:
1{
2 current_streak: number, // Current streak count (days)
3 longest_streak: number, // User's longest streak ever
4 last_activity_date: string // ISO date of the activity that extended the streak
5}Workout Events
Events for workout lifecycle and statistics.
| Event | Data Fields | Description |
| workout_opened | title: string, id: string, date: string | Workout details page opened |
| workout_started | id: string, date: string | Workout session started |
| workout_started (alt) | workoutId: string | Alternative workout start format |
| workout_completed | workout: string, date: string | Workout finished, user exits overview |
| workout_ended | id: string, exit_type: string, date: string | Workout session ended (see exit_type values below) |
| workout_overview | data: object | Complete workout summary statistics |
workout_ended exit_type values:
| Value | Meaning |
| complete | User finished the entire workout including outro |
| exit | User abandoned the workout mid-session |
| outro | User exited from the outro/cooldown screen after completing all exercises |
workout_overview Data Structure:
1{
2 workout_title: string, // Workout name
3 workout_id: string, // Unique workout ID
4 target_duration_seconds: number, // Target workout duration (seconds)
5 workout_duration_seconds: number, // Total wall-clock session time
6 // (includes rest, transitions, pauses).
7 // For challenges/assessments this equals
8 // total_time_spent (no wall-clock concept)
9 total_time_spent: number, // Active exercise time only (seconds)
10 completed_reps_count: number, // Total completed reps
11 target_reps_count: number, // Total target reps
12 calories_burned: number, // Calories (2 decimal places)
13 completion_percentage: number, // Completion % (2 decimals)
14 total_mistakes: number, // Total mistake count
15 accuracy_score: number, // Overall accuracy (0-100)
16 efficiency_score: number, // Efficiency metric (0-100)
17 total_exercise: number, // Number of exercises
18 actual_hold_time_seconds: number, // Time in correct position
19 target_hold_time_seconds: number // Target hold time
20}Note: Use workout_duration_seconds to display or log the full session time (including rest periods). Use total_time_spent if you only need active exercise time.
1case .workout_overview(let data):
2 if let calories = data["calories_burned"] as? Double,
3 let completion = data["completion_percentage"] as? Double {
4 print("Burned \(calories) cal, \(completion)% complete")
5 }Exercise Events
Events for individual exercise tracking.
| Event | Description |
| exercise_completed | Individual exercise completed |
| exercise_overview | All exercises summary (array) |
exercise_completed Data Structure:
1{
2 exercise_title: string, // Exercise name
3 time_spent: number, // Seconds spent
4 repeats: number, // Reps completed
5 total_reps: number, // Required reps
6 total_duration: number, // Countdown time
7 perfect_hold_position: number, // Time in perfect hold position (seconds).
8 // 0 for non-hold exercises
9 calories: number, // Calories burned
10 exercise_id: string, // Exercise ID
11 exercise_index: number, // 1-based position of the completed exercise
12 total_exercises: number, // Total number of exercises in the workout
13 mistakes: Array<{ // Mistakes made
14 mistake: string,
15 count: number
16 }>,
17 average_accuracy?: number // Average accuracy (0-1, optional)
18}exercise_overview Item Structure:
1{
2 exercise_title: string, // Exercise name
3 exercise_id: string, // Unique exercise ID
4 time_spent: number, // Time on exercise (seconds)
5 perfect_hold_position: number, // Time in correct position (timer-based)
6 repeats: number, // Reps completed
7 total_required_reps: number, // Target reps
8 total_required_time: number, // Target time (seconds)
9 calories: number, // Calories (2 decimal places)
10 mistakes: Array<{ // Detailed mistake breakdown
11 mistake: string,
12 count: number
13 }>,
14 mistake_count: number, // Total mistakes for exercise
15 accuracy_reps?: number[], // Per-rep accuracy scores (optional)
16 average_accuracy?: number // Average accuracy 0-100 (optional)
17}Camera & Frame Events
Events for camera tracking and frame detection.
| Event | Data Fields | Description |
| left_camera_frame | date: string ("dd mm yyyy hh:mm:ss") | User left camera view |
| returned_camera_frame | date: string ("dd mm yyyy hh:mm:ss") | User returned to camera view |
| check_frame_completed | message: string ("Person stepped into frame") | Frame check completed |
| camera_selector_opened | message: array (available cameras) | Camera selector opened |
| camera_selected | id: string, label: string, isMirrorCamera: boolean | Camera selected by user |
Plans & Programs
Events for workout plans and programs.
| Event | Data Fields | Description |
| plan_unlocked | id: string, img: string, title: string, date: string | Plan unlocked/selected |
| plan_opened | id: string | Plan result screen rendered. Fires for both goal-based and personalized plans |
| plan_onboarding_plan_created | data: { plan_id: string, plan_type: string } | A new plan was created from onboarding/assessment. Does NOT fire on revisits to an existing personalized plan |
| plan_progression_saved | data: object | Plan day progression was saved successfully after a plan workout finished |
| plan_progression_failed | data: object | Plan progression save failed (network/server error) |
| personalized_plan_exit | workout: string, date: string | Exit from personalized plan |
| remind_me_later_clicked | - | User tapped "Remind me later" on the Assessment screen inside the plan-onboarding flow. Only fires from the plan-onboarding page |
Note on plan tracking: When you launch a plan workout directly via the SDK, you can pass planId, planType, and progressWorkoutId in the initial PostMessage configuration so the SDK associates the workout session with the correct plan. After the workout finishes, you'll receive either plan_progression_saved (success) or plan_progression_failed (error). See Plan Context configuration for details.
Challenge Events
Events for challenge mode.
| Event | Data Fields | Description |
| challenge_started | exerciseId: string | Challenge exercise started |
| challenge_completed | repCount: number, mistakes: number | Challenge completed |
| challenge_exit | workout: string, date: string | Exit from challenge |
Leaderboard Events
Events for leaderboard functionality.
| Event | Data Fields | Description |
| highlighted_user | data: object | User's leaderboard position |
highlighted_user Data Structure:
1{
2 username: string, // User's username
3 score: number, // User's score
4 position: number // Leaderboard position (1-based)
5}Feedback Events
Events dispatched when a user submits feedback.
| Event | Description |
| feedback_submitted | User submitted training rating or per-exercise feedback |
Training Feedback Payload (source: "training_feedback"):
1{
2 type: "feedback_submitted",
3 source: "training_feedback",
4 rating: number, // User rating (e.g., 1-5)
5 is_like: boolean, // Whether the user liked the workout
6 description: string, // Optional text feedback
7 workout_id: string, // Workout ID
8 workout_title: string // Workout name
9}Per-Exercise Feedback Payload (source: "exercise_feedback"):
1{
2 type: "feedback_submitted",
3 source: "exercise_feedback",
4 workout_id: string, // Workout ID
5 workout_title: string, // Workout name
6 feedbacks: Array<{ // Per-exercise feedback entries
7 exercise_id: string, // Exercise ID
8 exercise_title: string, // Exercise name
9 is_like: boolean, // Whether the user liked the exercise
10 description: string // Optional text feedback
11 }>
12}Session & Upload Events
Events related to workout session saving and motion recording uploads. These events are only dispatched when \shouldSendStats: true\ is passed in the SDK configuration.
| Event | Data Fields | Description |
| workout_session_saved | data: object | Workout session successfully saved to backend |
| session_save_complete | - | Motion recording uploads finished successfully |
| motion_upload_progress | data: { completed: number, total: number } | Motion recording upload progress |
| motion_upload_error | data: { error: string } | Motion recording upload failed or timed out |
| workout_completion_overlay_dismissed | - | User dismissed the workout completion celebration overlay |
workout_session_saved Data Structure:
1{
2 session_id: number, // Backend-assigned session ID
3 workout_title: string, // Name of the workout
4 accuracy_score: number, // Overall accuracy (0-100)
5 efficiency_score: number, // Efficiency score (0-100)
6 completion_percentage: number, // How much of the workout was completed (0-100)
7 completed_reps_count: number, // Total reps completed
8 calories_burned: number // Estimated calories burned
9}motion_upload_progress Data Structure:
1{
2 completed: number, // Number of exercise recordings uploaded so far
3 total: number // Total number of exercise recordings to upload
4}Error & Status Events
Events for errors, warnings, and active time tracking.
| Event | Data Fields | Description |
| error_occurred | data: string | General error message |
| error_occurred | message: string | Alternative error format |
| error_occurred | data: string, error: any | Error with details |
| warning | data: string | Warning message |
| total_active_seconds | number | Active workout time (sent every 5s, pauses when user leaves camera frame) |
| ios_video_fallback_activated | reason, videoUrl, readyState, userAgent | iOS detected a stuck video decoder and switched to image-based playback. The exercise still runs in a degraded-but-functional mode (no native video controls) |
ios_video_fallback_activated Payload:
1{
2 type: "ios_video_fallback_activated",
3 reason: string, // e.g. "video_stuck_at_metadata"
4 videoUrl: string, // URL of the affected video
5 readyState: number, // HTMLMediaElement readyState at the time of fallback
6 userAgent: string // Device user agent string
7}Use this event for analytics or to surface a notice in your UI when iOS playback degrades. Only listen for it if you need visibility into iOS playback issues — no integrator action is required.
Assessment Exit Events
Events dispatched when a user exits an assessment before completing it.
| Event | Data Fields | Description |
| assessment_exit | exerciseId: string | User exited the assessment early (before results) |
| assessment_exit_results | exerciseId: string | User exited the assessment from the results screen |
assessment_exit Payload:
1{
2 type: "assessment_exit",
3 data: {
4 exerciseId: string // The assessment exercise identifier
5 }
6}assessment_exit_results Payload:
1{
2 type: "assessment_exit_results",
3 data: {
4 exerciseId: string // The assessment exercise identifier
5 }
6}Use \assessment_exit\ to detect when users abandon an assessment mid-session, and \assessment_exit_results\ to detect when they leave after viewing their results.
Assessment Overview
AI-powered health assessments with two event types:
- assessment_overview: Sent when results page loads
- assessment_completed: Sent when user clicks restart or finish
Common Fields (All Assessments):
| Field | Type | Description |
| type | string | "assessment_overview" or "assessment_completed" |
| assessmentType | string | Assessment identifier (e.g., "tug", "sls") |
| date | Date | Timestamp when completed |
| time | number | Total assessment time (seconds) |
| steps | number? | Estimated step count (walking assessments) |
Assessment Types:
- Mobility: TUG (tug), Gait Speed Test (gaitspeedtest)
- Balance: SLS (sls), SBSS (sbss), STSS (stss), Full Tandem (fulltandem)
- Functional: STS (sts), Five Times STS (fivetimessts), FRT (frt)
- Range of Motion: Shoulder ROM (romshoulder)
- Games: Balloon Pop (balloonpop), Color Chase (colorchase), Alien Squat Shooter (aliensquatshooter)
Risk Levels:
| Value | Meaning |
| low | Good performance, minimal fall/balance risk |
| moderate | Some limitations, may benefit from training |
| high | Significant limitations, balance training recommended |
Mobility Assessments
TUG (Timed Up and Go) - assessmentType: "tug"
Stand-walk-turn-return-sit timing test.
| Field | Type | Description |
| time | number | Total completion time (seconds) |
| steps | number | Estimated step count |
| standingUpTime | number | Time to stand from seated (seconds) |
| sittingDownTime | number | Time to sit at end (seconds) |
| walkingForwardTime | number | Time walking to 3m marker (seconds) |
| walkingBackwardTime | number | Time walking back (seconds) |
| turningTime | number | Time spent turning (seconds) |
| backBendingAngleSitting | number[] | Back angles during sitting countdown (degrees) |
| backBendingAngleStanding | number[] | Back angles during movement (degrees) |
| averageSpeedMs_tug | number | Average walking speed. Formula: 6m / time |
| avgBackBendingSitting | number? | Average back angle sitting (degrees) |
| avgBackBendingStanding | number? | Average back angle standing (degrees) |
Gait Speed Test - assessmentType: "gaitspeedtest"
Walking speed measurement over 4 meters.
| Field | Type | Description |
| time | number | Total test time (seconds) |
| steps | number | Estimated step count |
| standingTime | number | Time in standing phase (seconds) |
| walkingTime | number | Active walking time (seconds) |
| averageGaitSpeed | number | Gait speed. Formula: 4m / time |
Balance Assessments
SLS (Single Leg Stand) - assessmentType: "sls"
| Field | Type | Description |
| rightTime | number | Duration on right leg (seconds) |
| leftTime | number | Duration on left leg (seconds) |
| symmetryScore_sls | number? | Leg symmetry % (0-100). Formula: (min/max) * 100 |
| riskLevel_sls | string | "low", "moderate", or "high" |
Risk Calculation:
- Low: Min time >=20s AND symmetry good (difference <=5s)
- Moderate: Min time >=10s AND average >=15s
- High: All other cases
SBSS (Side-by-Side Stand) - assessmentType: "sbss"
| Field | Type | Description |
| timeInProperPosition_sbss | number | Time in correct stance (max 10s) |
| maxShoulderShift_sbss | number | Max lateral shoulder shift (% of shoulder width) |
| maxHipShift_sbss | number | Max lateral hip shift (% of hip width) |
| feetMoved_sbss | boolean | Whether feet moved |
| riskLevel_sbss | string | "low", "moderate", or "high" |
Risk Calculation:
- High: Feet moved OR (time <7s AND sway >=30%)
- Moderate: Time >=7s AND sway <30%
- Low: Time >=9.5s AND sway <15%
STSS (Semi-Tandem Stand) - assessmentType: "stss"
| Field | Type | Description |
| timeInProperPosition_stss | number | Time in correct stance (max 10s) |
| maxShoulderShift_stss | number | Max shoulder shift (% of width) |
| maxHipShift_stss | number | Max hip shift (% of projection) |
| feetMoved_stss | boolean | Whether feet moved |
| riskLevel_stss | string | "low", "moderate", or "high" |
Risk calculation same as SBSS.
Full Tandem Stand - assessmentType: "fulltandem"
| Field | Type | Description |
| time | number | Total test time (seconds) |
| timeInProperPosition_fulltandem | number | Time in heel-to-toe stance (max 10s) |
| maxShoulderShift_fulltandem | number | Max shoulder shift (%) |
| maxHipShift_fulltandem | number | Max hip shift (%) |
| feetMoved_fulltandem | boolean | Whether feet moved |
| testFailed_fulltandem | boolean | Whether test was terminated early |
| terminationReason_fulltandem | string? | Reason for early termination |
| riskLevel_fulltandem | string | "low", "moderate", or "high" |
Risk Calculation:
- Low: Time >=10s AND no feet movement
- Moderate: Time >=5s
- High: Time <5s
Functional Assessments
STS (30-Second Sit-to-Stand) - assessmentType: "sts"
| Field | Type | Description |
| reps | number | Total reps completed in 30 seconds |
| averageSittingTime | number | Average time sitting per rep (seconds) |
| averageStandingTime | number | Average time standing per rep (seconds) |
| avgTimePerRep_sts | number? | Average seconds per rep. Formula: 30 / reps |
| repTimeVariance_minRepTime | number? | Fastest rep time (seconds) |
| repTimeVariance_maxRepTime | number? | Slowest rep time (seconds) |
| repTimeVariance_minRepIndex | number? | Which rep was fastest (1-indexed) |
| repTimeVariance_maxRepIndex | number? | Which rep was slowest (1-indexed) |
Five Times STS - assessmentType: "fivetimessts"
| Field | Type | Description |
| time | number | Total completion time for 5 reps (seconds) |
| averageSittingTime | number | Average time sitting (seconds) |
| averageStandingTime | number | Average time standing (seconds) |
FRT (Functional Reach Test) - assessmentType: "frt"
| Field | Type | Description |
| reach | number | Maximum forward reach (cm) |
| maxHeelLift | number | Maximum heel lift detected (cm) |
| heelLiftCount | number | Count of heel lift violations |
| legLiftCount | number | Count of leg lift violations |
| testCompleted | boolean | Whether test finished normally |
| endReason | string? | Reason for early termination |
| riskLevel_frt | string? | "low", "moderate", or "high" |
End Reason Values:
- "Feet moved out of zone"
- "User left zone"
- "User turned forward"
- "Arm dropped completely"
- "Reference lost"
- "Unhandled state"
Risk Calculation:
- High: Test not completed OR reach <=15cm
- Moderate: Reach 15-25cm
- Low: Reach >25cm
Range of Motion Assessments
Shoulder ROM - assessmentType: "romshoulder"
A quick range-of-motion check for the shoulders. The user stands facing the camera and lifts one arm at a time straight out to the side (shoulder abduction), as high as comfortably possible. The system tracks the peak abduction angle reached by each arm, compares left and right sides, and flags meaningful asymmetry.
Useful for tracking recovery, spotting asymmetry, and observing mobility improvements session over session.
| Field | Type | Description |
| romMovement | string | Type of ROM movement assessed. Primary value: "shoulder_abduction" |
| romMaxLeft | number | Maximum ROM achieved on the left side (degrees, rounded to 0 decimals, range 0-180+) |
| romMaxRight | number | Maximum ROM achieved on the right side (degrees, rounded to 0 decimals, range 0-180+) |
| romMinLeft | number | Minimum ROM recorded on the left side (degrees, rounded to 0 decimals, range 0-180+) |
| romMinRight | number | Minimum ROM recorded on the right side (degrees, rounded to 0 decimals, range 0-180+) |
| romSymmetryDelta | number | Absolute difference between max left and max right (degrees). Formula: abs(romMaxLeft - romMaxRight) |
| romSymmetryFlagDegrees | number | Asymmetry threshold (degrees). Defaults to 10 if not provided |
| romAsymmetric | boolean | true if romSymmetryDelta > romSymmetryFlagDegrees, else false |
Notes:
- All angle measurements are in degrees.
- Numeric values are rounded to 0 decimal places.
romAsymmetricis computed by comparingromSymmetryDeltaagainstromSymmetryFlagDegrees.
Game Assessments
Balloon Pop - assessmentType: "balloonpop"
| Field | Type | Description |
| gameScore | number | Total balloons popped |
| averageReactionTime | string | Average time to pop (seconds) |
| maxIdleTime | string | Max time without action (seconds) |
| averageSpeed_balloonpop | number | Balloons/second. Formula: gameScore / 30 |
| masteryTitle_balloonpop | string | Achievement tier |
Mastery Titles:
| Score | Title |
| >=30 | pop_tastic_hero |
| >=25 | magic_popper |
| >=20 | super_duper_popper |
| >=15 | sparkly_popper |
| >=10 | giggly_popper |
| >=5 | bouncy_bubbler |
| <5 | tiny_popper |
Color Chase - assessmentType: "colorchase"
| Field | Type | Description |
| gameScore | number | Total score achieved |
| levelReached | number | Highest level completed |
| totalDuration | string | Total game duration (seconds) |
| averageReactionTime | string | Average reaction time per tap (seconds) |
| maxIdleTime | string | Max time between taps (seconds) |
| masteryTitle_colorchase | string | Achievement tier |
Mastery Titles:
| Level | Title |
| >=10 | color_chase_legend |
| >=8 | magic_color_wizard |
| >=6 | super_color_star |
| >=4 | shiny_sequencer |
| >=2 | rainbow_chaser |
| >=1 | color_buddy |
| <1 | little_color_finder |
Alien Squat Shooter - assessmentType: "aliensquatshooter"
| Field | Type | Description |
| gameScore | number | Total aliens destroyed |
| squatsPerformed | number | Number of squats completed |
| totalDuration | string | Total game duration (seconds) |
| averageSquatRate | string | Squats per second |
| maxTimeBetweenSquats | string | Max idle between squats (seconds) |
| averageAlienDestroyTime | string | Average time to destroy alien (seconds) |
| masteryTitle_aliensquatshooter | string | Achievement tier |
Mastery Titles:
| Score | Title |
| >=25 | alien_annihilator |
| >=20 | cosmic_blaster |
| >=15 | star_shooter |
| >=10 | galactic_gunner |
| >=5 | space_squatter |
| <5 | rookie_defender |
Health Benefits (All Games)
Included in payload for all game types.
1healthBenefits: {
2 heartDiseaseReduction: number, // Estimated % reduction (max 15)
3 diabetesReduction: number, // Estimated % reduction (max 20)
4 obesityReduction: number, // Estimated % reduction (max 10)
5 depressionReduction: number // Estimated % reduction (max 15)
6}Health Benefit Calculation:
reduction = min((gameScore / 100) * maxReduction, maxReduction)
Event Flow Examples
Complete Workout Flow:
1. kinestex_launched - Application starts
2. workout_opened - User views workout details
3. workout_started - Workout begins
4. returned_camera_frame / left_camera_frame - Frame tracking
5. Multiple exercise_completed - Each exercise finished
6. workout_overview - Summary statistics
7. exercise_overview - All exercises summary
8. workout_completed - User exits statistics
9. exit_kinestex - Application closed
Challenge Flow:
1. challenge_started - Challenge begins
2. exercise_completed - Exercise finished
3. challenge_completed - Challenge complete
4. challenge_exit - Exit from challenge
Assessment Flow:
1. kinestex_launched - Application starts
2. Assessment performed (user follows on-screen instructions)
3. assessment_overview - Results page loads with all metrics
4. assessment_completed - User clicks restart or finish
5. assessment_exit_results - User exits from results screen (or assessment_exit if they exit early)
6. exit_kinestex - Application closed
Need Help?
Our team is ready to assist with your integration.