Fall Risk Results API
Endpoints
GET /api/fall-risk-results— Fetch all fall risk results for a client/user.GET /api/fall-risk-results/[fallRiskResultId]— Fetch a fall risk result by its unique ID.
GET /api/fall-risk-results
Fetch all fall risk results for a client/user, ordered by creation date (newest first).
Query Parameters:
clientId: string (optional) — The client identifier. If not provided, uses the inferred client ID from the request context.userId: string (optional) — The user identifier. If provided, filters results for this specific user only.
Headers:
Authorization: Bearer <JWT>(currently disabled for testing)
Response:
-
200 OK:{
"data": [
{
"id": "string",
"clientId": "string",
"userId": "string (optional)",
"createdAt": "string (ISO date)",
"quizResults": {
/* FallRiskResultQuizResult object */
},
"sitToStand": {
/* FallRiskResultSitToStandResult object */
},
"singleLegStance": {
/* FallRiskResultSingleLegStanceResult object */
},
"tandemStance": {
/* FallRiskResultTandemStanceResult object */
},
"tandemWalk": {
/* FallRiskResultTandemWalkResult object */
},
"riskLevel": "LOW | INTERMEDIATE | HIGH",
"riskProbability": "number (0-1, nullable)",
"riskProbabilityCalculations": ["string array, nullable"]
}
],
"count": "number"
} -
500 Internal Server Error:{ error: "Client ID not found" | string }
Notes:
- Results are ordered by
createdAtin descending order (newest first). - If
userIdis not provided, returns up to 20 fall risk results for the client. - If
userIdis provided, returns up to 5 fall risk results for that specific user within the client. - Result sets are limited for performance reasons.
- Authentication is currently disabled for testing purposes.
- The response includes a
countfield indicating the total number of results returned.
Example Usage
Get all fall risk results for a client:
GET /api/fall-risk-results?clientId=gofa
Get all fall risk results for a specific user:
GET /api/fall-risk-results?clientId=gofa&userId=user123
Get all fall risk results using inferred client ID:
GET /api/fall-risk-results
GET /api/fall-risk-results/[fallRiskResultId]
Fetch a fall risk result by its unique ID with intelligent calculation and recalculation logic.
Query Parameters:
recalculate: boolean (optional) — If set to "true", forces recalculation of risk assessment even if results already exist.
Headers:
Authorization: Bearer <JWT>(currently disabled for testing)
Path Parameters:
fallRiskResultId: string (required) — The unique result identifier
Assessment Requirements:
- Minimum for calculation: Complete quiz + sit-to-stand assessment (with at least
thirtySecondscount) - Progressive enhancement: Additional assessments (single leg stance, tandem stance, tandem walk) improve calculation accuracy
- Smart recalculation: Automatically recalculates when new assessments are detected
Response:
-
200 OK:{
"data": {
"id": "string",
"clientId": "string",
"userId": "string (optional)",
"createdAt": "string (ISO date)",
"quizResults": { /* FallRiskResultQuizResult object */ },
"sitToStand": { /* FallRiskResultSitToStandResult object */ },
"singleLegStance": { /* FallRiskResultSingleLegStanceResult object */ },
"tandemStance": { /* FallRiskResultTandemStanceResult object */ },
"tandemWalk": { /* FallRiskResultTandemWalkResult object */ },
"riskLevel": "LOW | INTERMEDIATE | HIGH",
"riskProbability": "number (0-1, nullable)",
"riskProbabilityCalculations": ["string array, nullable"],
"calculationMetadata": {
"assessmentsUsed": ["quiz", "sitToStand", "singleLegStance", ...],
"calculatedAt": "string (ISO date)",
"version": "string"
},
"quizUrl": "string",
"sitToStandTestUrl": "string",
"tandemStanceTestUrl": "string",
"singleLegStanceTestUrl": "string",
"tandemWalkTestUrl": "string",
"message": "string (status message)",
"availableAssessments": ["quiz", "sitToStand", ...],
"missingInitial": "string[] (when missing quiz data)",
"missingAI": "string[] (when missing assessment data)"
}
} -
404 Not Found:{ error: string } -
401 Unauthorized:{ error: string } -
500 Internal Server Error:{ error: 'Client ID not found' | string }
Behavior & Logic:
- Smart Recalculation: Automatically detects new assessments and recalculates for improved accuracy
- Progressive Assessment: Can calculate risk with just quiz + sit-to-stand, improves with additional tests
- Calculation Tracking: Records which assessments were used and when calculation was performed
- Backward Compatible: Existing data continues to work without modification
Response Messages:
"Risk assessment calculated successfully"— New calculation completed"Recalculated with new assessments: [assessment names]"— Automatic recalculation due to new data"Using existing calculation. No changes detected."— Returning cached results"Missing required data for fall risk assessment..."— Insufficient data for calculation"Calculation failed: [error details]"— Calculation error occurred
Notes:
- Minimum requirement: Complete quiz (all 10 questions) + sit-to-stand test (at least
thirtySecondscount) - Optional assessments: Single leg stance, tandem stance, tandem walk improve accuracy but are not required
- Assessment URLs guide users to complete missing or additional tests
calculationMetadatatracks which assessments contributed to the current calculationavailableAssessmentsshows what test data is currently present- Use
recalculate=trueto force recalculation regardless of existing results - Authentication is currently disabled for testing purposes
FallRiskResult Object Schema
id: string — Unique result IDclientId: string — Client IDuserId: string (optional) — User IDcreatedAt: string (ISO date or Firestore timestamp)quizResults: object (optional) — See Quiz Results schema belowsitToStand: object (optional) — See SitToStand schema belowsingleLegStance: object (optional) — See SingleLegStance schema belowtandemStance: object (optional) — See TandemStance schema belowtandemWalk: object (optional) — See TandemWalk schema belowriskLevel: string (optional) — Calculated risk level (LOW,INTERMEDIATE,HIGH)riskProbability: number (optional, nullable) — Calculated risk probability (0-1)riskProbabilityCalculations: string[] (optional, nullable) — Detailed calculation stepscalculationMetadata: object (optional) — Calculation tracking informationassessmentsUsed: string[] — List of assessments used (e.g.,["quiz", "sitToStand", "singleLegStance"])calculatedAt: string (ISO date) — When the calculation was performedversion: string — Calculation algorithm version (default: "1.0")
message: string (optional) — Status message about calculation stateavailableAssessments: string[] (optional) — List of currently available assessment datamissingInitial: string[] (optional) — Missing quiz questions (when incomplete)missingAI: string[] (optional) — Missing AI assessment data (when incomplete)
Quiz Results (quizResults)
ageGroup: string (nullable) — Age group selection:"under60","60to69","70to79", or"80plus"fallenLastYear: boolean (nullable)takingPsychoactiveMeds: boolean (nullable)difficultyWithADL: boolean (nullable)fearfulOfFalling: boolean (nullable)useAssistiveDevice: boolean (nullable)gotInjuryFromFall: boolean (nullable)multipleLastYear: boolean (nullable)unableToGetUp: boolean (nullable)lostConsciousness: boolean (nullable)hasFrailty: boolean (nullable)
SitToStand (sitToStand)
count: number — Number of sit-to-stand reps in 30 secondsfiveRepsTimeTaken: number (nullable) — Time taken in seconds to complete 5 repsshoulderTilts: number[] — Shoulder tilt measurements in degrees for each rep
SingleLegStance (singleLegStance)
elapsedSeconds: number — Elapsed seconds within 10 secondsshoulderTilts: number[] — Shoulder tilt measurements in degrees, collected every second during the assessment
TandemStance (tandemStance)
elapsedSeconds: number — Elapsed seconds within 30 secondsshoulderTilts: number[] — Shoulder tilt measurements in degrees, collected every second during the assessment
TandemWalk (tandemWalk)
steps: number — Number of steps taken during the 30-second testassessment: string (optional) — Assessment of the user's performancedescription: string (optional) — Description of the test performancebodySwayScore: number (optional) — Body sway score from 0-100 (0 is worst, 100 is best)elapsedSeconds: number — Elapsed seconds within 30 secondsshoulderTilts: number[] — Shoulder tilt measurements in degrees, collected every second during the assessment
Sample FallRiskResult Objects
Complete Assessment (All Tests Completed)
{
"id": "fallrisk123",
"clientId": "gofa",
"userId": "user456",
"createdAt": "2025-07-19T10:00:00.000Z",
"quizResults": {
"ageGroup": "60to69",
"fallenLastYear": false,
"takingPsychoactiveMeds": false,
"difficultyWithADL": false,
"fearfulOfFalling": false,
"useAssistiveDevice": false,
"gotInjuryFromFall": false,
"multipleLastYear": false,
"unableToGetUp": false,
"lostConsciousness": false,
"hasFrailty": false
},
"sitToStand": {
"count": 18,
"fiveRepsTimeTaken": 8.5,
"shoulderTilts": [2.1, 1.8, 2.0, 2.2, 1.9]
},
"singleLegStance": {
"elapsedSeconds": 9.2,
"shoulderTilts": [1.5, 1.8, 2.1, 1.9, 2.3, 2.0, 1.7, 2.2, 1.6]
},
"tandemStance": {
"elapsedSeconds": 28.5,
"shoulderTilts": [
1.2, 1.5, 1.8, 1.3, 1.6, 1.9, 1.4, 1.7, 2.0, 1.5, 1.8, 1.2, 1.6, 1.9, 1.3,
1.7, 2.1, 1.4, 1.8, 1.5, 1.9, 1.2, 1.6, 1.8, 1.4, 1.7, 2.0, 1.3, 1.6
]
},
"tandemWalk": {
"steps": 12,
"assessment": "Good",
"description": "Completed successfully with minor wobbling",
"bodySwayScore": 85,
"elapsedSeconds": 30.0,
"shoulderTilts": [
2.1, 2.5, 2.8, 2.3, 2.6, 2.9, 2.4, 2.7, 3.0, 2.5, 2.8, 2.2, 2.6, 2.9, 2.3,
2.7, 3.1, 2.4, 2.8, 2.5, 2.9, 2.2, 2.6, 2.8, 2.4, 2.7, 3.0, 2.3, 2.6, 2.9
]
},
"riskLevel": "LOW",
"riskProbability": 0.08,
"riskProbabilityCalculations": [
"Pretest probability: 0.3",
"Initial screening LR product: 0.6561",
"AI assessment LR product: 0.4536",
"Posttest probability = 0.0832"
],
"calculationMetadata": {
"assessmentsUsed": [
"quiz",
"sitToStand",
"sitToStand.fiveTimes",
"singleLegStance",
"tandemStance",
"tandemWalk"
],
"calculatedAt": "2025-07-19T10:15:00.000Z",
"version": "1.0"
},
"message": "Risk assessment calculated successfully",
"availableAssessments": [
"quiz",
"sitToStand",
"sitToStand.fiveTimes",
"singleLegStance",
"tandemStance",
"tandemWalk"
],
"quizUrl": "/fall-risk/fallrisk123/quiz",
"sitToStandTestUrl": "/fall-risk/fallrisk123/sit-to-stand",
"tandemStanceTestUrl": "/fall-risk/fallrisk123/tandem-stance",
"singleLegStanceTestUrl": "/fall-risk/fallrisk123/single-leg-stance",
"tandemWalkTestUrl": "/fall-risk/fallrisk123/tandem-walk-vlm"
}
Minimum Assessment (Quiz + Sit-to-Stand Only)
{
"id": "fallrisk124",
"clientId": "gofa",
"userId": "user789",
"createdAt": "2025-07-19T11:00:00.000Z",
"quizResults": {
"ageGroup": "under60",
"fallenLastYear": true,
"takingPsychoactiveMeds": false,
"difficultyWithADL": false,
"fearfulOfFalling": true,
"useAssistiveDevice": false,
"gotInjuryFromFall": false,
"multipleLastYear": false,
"unableToGetUp": false,
"lostConsciousness": false,
"hasFrailty": false
},
"sitToStand": {
"count": 12,
"fiveRepsTimeTaken": null,
"shoulderTilts": [
3.2, 2.8, 3.1, 2.9, 3.0, 3.3, 2.7, 3.2, 2.8, 3.1, 2.9, 3.0
]
},
"riskLevel": "INTERMEDIATE",
"riskProbability": 0.42,
"riskProbabilityCalculations": [
"Pretest probability: 0.3",
"Initial screening LR product: 2.016",
"AI assessment LR product: 3.9",
"Posttest probability = 0.4186"
],
"calculationMetadata": {
"assessmentsUsed": ["quiz", "sitToStand"],
"calculatedAt": "2025-07-19T11:05:00.000Z",
"version": "1.0"
},
"message": "Risk assessment calculated successfully",
"availableAssessments": ["quiz", "sitToStand"],
"quizUrl": "/fall-risk/fallrisk124/quiz",
"sitToStandTestUrl": "/fall-risk/fallrisk124/sit-to-stand",
"tandemStanceTestUrl": "/fall-risk/fallrisk124/tandem-stance",
"singleLegStanceTestUrl": "/fall-risk/fallrisk124/single-leg-stance",
"tandemWalkTestUrl": "/fall-risk/fallrisk124/tandem-walk-vlm"
}
Insufficient Data (Missing Sit-to-Stand)
{
"id": "fallrisk125",
"clientId": "gofa",
"userId": "user101",
"createdAt": "2025-07-19T12:00:00.000Z",
"quizResults": {
"ageGroup": "70to79",
"fallenLastYear": true,
"takingPsychoactiveMeds": true,
"difficultyWithADL": true,
"fearfulOfFalling": true,
"useAssistiveDevice": true,
"gotInjuryFromFall": null,
"multipleLastYear": null,
"unableToGetUp": null,
"lostConsciousness": null,
"hasFrailty": null
},
"message": "Missing required data for fall risk assessment. Minimum required: complete quiz + sit-to-stand assessment.",
"missingInitial": [
"gotInjuryFromFall",
"multipleLastYear",
"unableToGetUp",
"lostConsciousness",
"hasFrailty"
],
"missingAI": ["sitToStand.thirtySeconds"],
"availableAssessments": [],
"quizUrl": "/fall-risk/fallrisk125/quiz",
"sitToStandTestUrl": "/fall-risk/fallrisk125/sit-to-stand",
"tandemStanceTestUrl": "/fall-risk/fallrisk125/tandem-stance",
"singleLegStanceTestUrl": "/fall-risk/fallrisk125/single-leg-stance",
"tandemWalkTestUrl": "/fall-risk/fallrisk125/tandem-walk-vlm"
}
Progressive Assessment Approach: The API now supports calculating fall risk with minimum data and progressively improving accuracy as more assessments are completed.
Minimum Requirements: Complete quiz (all 10 questions answered) + sit-to-stand assessment (at least the 30-second count).
Smart Recalculation: The system automatically detects when new assessment data is available and recalculates for improved accuracy.
Backward Compatibility: All existing data and API responses continue to work without modification.
Assessment URLs guide users through the complete fall risk evaluation process.
Authentication is currently disabled for testing purposes.