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 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 createdAt in descending order (newest first).
  • If userId is not provided, returns up to 20 fall risk results for the client.
  • If userId is 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 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", ...],
    "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
  • 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"],
"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": [],
"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.
Assessment URLs guide users through the complete fall risk evaluation process.
Authentication is currently disabled for testing purposes.