Skip to main content

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 fall risk results for a client/user, prioritizing the most recent result plus past results with calculated risk levels. Returns the 1 most recent result plus up to 10 additional results that have calculated risk levels (riskLevel field), 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 createdAt in descending order (newest first).
  • Returns the 1 most recent result (regardless of calculation status) plus up to 10 additional results that have calculated risk levels.
  • This ensures you always get the latest assessment data while also providing historical results with complete calculations.
  • Maximum total results returned: 11 (1 latest + up to 10 with risk levels).
  • Result sets are limited for performance reasons.
  • Authentication is currently disabled for testing purposes.
  • The response includes a count field 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 thirtySeconds count)
  • 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", ...],
    "missingAssessments": ["singleLegStance", "tandemStance", "tandemWalk"],
    "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:

  1. Smart Recalculation: Automatically detects new assessments and recalculates for improved accuracy
  2. Progressive Assessment: Can calculate risk with just quiz + sit-to-stand, improves with additional tests
  3. Calculation Tracking: Records which assessments were used and when calculation was performed
  4. 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 thirtySeconds count)
  • 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
  • calculationMetadata tracks which assessments contributed to the current calculation
  • availableAssessments shows what test data is currently present
  • Use recalculate=true to force recalculation regardless of existing results
  • Authentication is currently disabled for testing purposes

FallRiskResult Object Schema

  • id: string — Unique result ID
  • clientId: string — Client ID
  • userId: string (optional) — User ID
  • createdAt: string (ISO date or Firestore timestamp)
  • quizResults: object (optional) — See Quiz Results schema below
  • sitToStand: object (optional) — See SitToStand schema below
  • singleLegStance: object (optional) — See SingleLegStance schema below
  • tandemStance: object (optional) — See TandemStance schema below
  • tandemWalk: object (optional) — See TandemWalk schema below
  • riskLevel: string (optional) — Calculated risk level (LOW, INTERMEDIATE, HIGH)
  • riskProbability: number (optional, nullable) — Calculated risk probability (0-1)
  • riskProbabilityCalculations: string[] (optional, nullable) — Detailed calculation steps
  • calculationMetadata: object (optional) — Calculation tracking information
    • assessmentsUsed: string[] — List of assessments used (e.g., ["quiz", "sitToStand", "singleLegStance"])
    • calculatedAt: string (ISO date) — When the calculation was performed
    • version: string — Calculation algorithm version (default: "1.0")
  • message: string (optional) — Status message about calculation state
  • availableAssessments: string[] (optional) — List of currently available assessment data
  • missingAssessments: string[] (optional) — List of missing optional assessments for more accurate scoring (singleLegStance, tandemStance, tandemWalk)
  • missingInitial: 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 seconds
  • fiveRepsTimeTaken: number (nullable) — Time taken in seconds to complete 5 reps
  • shoulderTilts: number[] — Shoulder tilt measurements in degrees for each rep

SingleLegStance (singleLegStance)

  • elapsedSeconds: number — Elapsed seconds within 10 seconds
  • shoulderTilts: number[] — Shoulder tilt measurements in degrees, collected every second during the assessment

TandemStance (tandemStance)

  • elapsedSeconds: number — Elapsed seconds within 30 seconds
  • shoulderTilts: number[] — Shoulder tilt measurements in degrees, collected every second during the assessment

TandemWalk (tandemWalk)

  • steps: number — Number of steps taken during the 30-second test
  • assessment: string (optional) — Assessment of the user's performance
  • description: string (optional) — Description of the test performance
  • bodySwayScore: number (optional) — Body sway score from 0-100 (0 is worst, 100 is best)
  • elapsedSeconds: number — Elapsed seconds within 30 seconds
  • shoulderTilts: number[] — Shoulder tilt measurements in degrees, collected every second during the assessment

Sample FallRiskResult Objects

Complete Assessment (All Tests Completed)

Complete Assessment Example
{
"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)

Minimum Assessment Example
{
"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"],
"missingAssessments": ["singleLegStance", "tandemStance", "tandemWalk"],
"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)

Insufficient Data Example
{
"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": [],
"missingAssessments": ["sitToStand", "singleLegStance", "tandemStance", "tandemWalk"],
"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"
}

note

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.
Missing Assessments: The missingAssessments field lists optional assessments not yet completed, helping guide users to complete all assessments for the most accurate risk scoring.
Assessment URLs guide users through the complete fall risk evaluation process.
Authentication is currently disabled for testing purposes.