Loading documentation

Access required

Your account doesn't have access to the documentation. Contact your administrator.

Sign out
Skip to main content

Oswestry Disability Index

Status: stable Category: function Added: 2026-04-20 Last reviewed: 2026-04-21

Summary

The Oswestry Disability Index (ODI) is Trinity's lumbar-specific functional disability measure. Ten items, each scored 05, converted to a 0–100% disability score and mapped to five bands from minimal to bed_bound. Higher score means more disability.

⚠ Scoring-formula note

Trinity's ODI score is computed as:

score = mean_of_responded_items × 20

where the mean is taken across the items actually present in the request body (all ten are required in the current rubric). With the response scale of 0–5 per item, this produces 0–100%.

Some legacy implementations compute ODI as sum × 2 (over ten items scored 0–5, producing 0–100) or as (sum / responded_items) × 10 (which yields 0–50, half the conventional scale). Trinity uses mean × 20. Callers migrating from another ODI implementation should confirm the formula before comparing scores, or bands may appear to shift even when the underlying responses have not.

Resource identity

FieldValue
Categoryfunction
Resourceoswestry
Instrument IDoswestry
Rubric version1.0.0
Path prefix/api/function/oswestry

Operations

OperationMethodPathContract
QuestionsGET/api/function/oswestry/questionspatterns-questions.md
ScorePOST/api/function/oswestry/scorepatterns-score.md

Items

Ten items, each on a 05 scale.

IDPrompt (paraphrased)
item_1Pain intensity.
item_2Personal care (washing, dressing).
item_3Lifting.
item_4Walking.
item_5Sitting.
item_6Standing.
item_7Sleeping.
item_8Sex life (if applicable).
item_9Social life.
item_10Traveling.

Answer choices per item:

ValueLabel
0No problem
1Mild problem
2Moderate problem
3Fairly severe problem
4Very severe problem
5Complete disability

Scoring

FieldValue
Methodresponse_mean_scaled with multiplier = 20, offset = 0. Formula: (mean_of_items + 0) × 20.
Score range0100 (percentage).

Bands

BandRange (inclusive)Clinical meaning
minimal020Minimal disability.
moderate2140Moderate disability.
severe4160Severe disability.
crippled6180Crippled — pain is the main issue.
bed_bound81100Bed-bound or condition-exaggerating.

Required items

All ten items are required for a strict /score call.

Worked example

Every item answered with 3. See quickstart.md for per-language scaffolding and patterns-score.md for the full /score contract.

Send:

POST /api/function/oswestry/score HTTP/1.1
Host: engine.tripod-health.com
apikey: $ENGINE_API_KEY
Content-Type: application/json
X-Request-ID: docs-oswestry-score-basic

{
"responses": {
"item_1": 3, "item_2": 3, "item_3": 3, "item_4": 3, "item_5": 3,
"item_6": 3, "item_7": 3, "item_8": 3, "item_9": 3, "item_10": 3
}
}

Receive (200 OK):

{
"instrument": "oswestry",
"category": "function",
"finding": {
"algorithm_id": "oswestry",
"algorithm_version": "1.0.0",
"score": 60,
"band": "severe",
"raw": {
"rubric_version": "1.0.0",
"responded_items": 10
},
"context": null,
"imputed": false,
"sd": null,
"prior_source": null
},
"confidence": {
"overall": 1,
"tier": "high",
"breakdown": {
"input_completeness": 1,
"imputation_variance": null,
"model_certainty": null
}
},
"recommendations": null,
"depth": "basic",
"catalog_version": "0.13.0",
"request_id": "docs-oswestry-score-basic",
"timestamp": "2026-04-21T23:14:54.245147+00:00"
}

Computation: mean of responses = 3.0 × 20 = 60.0 → upper edge of the severe band (41–60). If every item were 5, the mean would be 5.0 × 20 = 100.0 (bed_bound band, 81–100).

Calling in your language

curl

curl -sS -X POST "https://engine.tripod-health.com/api/function/oswestry/score" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"responses":{"item_1":3,"item_2":3,"item_3":3,"item_4":3,"item_5":3,"item_6":3,"item_7":3,"item_8":3,"item_9":3,"item_10":3}}'

Python (requests)

# Uses the call() helper from quickstart.md.
responses = {f"item_{i}": 3 for i in range(1, 11)}
result = call("POST", "/api/function/oswestry/score", {"responses": responses})
print(result["finding"]["score"], result["finding"]["band"])

Node.js (native fetch)

// Uses the call() helper from quickstart.md.
const responses = Object.fromEntries(
Array.from({ length: 10 }, (_, i) => [`item_${i + 1}`, 3]),
);
const result = await call("POST", "/api/function/oswestry/score", { responses });
console.log(result.finding.score, result.finding.band);

TypeScript

// Uses the typed call<T>() helper from quickstart.md.
const responses = Object.fromEntries(
Array.from({ length: 10 }, (_, i) => [`item_${i + 1}`, 3]),
);
const result = await call<ScoreResponse>(
"POST",
"/api/function/oswestry/score",
{ responses },
);

Go

// Uses the call() helper from quickstart.md.
responses := make(map[string]int, 10)
for i := 1; i <= 10; i++ {
responses[fmt.Sprintf("item_%d", i)] = 3
}
result, err := call("POST", "/api/function/oswestry/score",
map[string]any{"responses": responses}, 3)
if err != nil {
panic(err)
}
finding := result["finding"].(map[string]any)
fmt.Printf("oswestry: %v (%v)\n", finding["score"], finding["band"])

Java

// Uses the call() helper from quickstart.md.
StringBuilder body = new StringBuilder("{\"responses\":{");
for (int i = 1; i <= 10; i++) {
if (i > 1) body.append(",");
body.append("\"item_").append(i).append("\":3");
}
body.append("}}");
String result = call("POST", "/api/function/oswestry/score", body.toString(), 3);
System.out.println(result);

C# (.NET HttpClient)

// Uses the Call() helper from quickstart.md.
var responses = Enumerable.Range(1, 10)
.ToDictionary(i => $"item_{i}", _ => 3);
var result = await Call(HttpMethod.Post, "/api/function/oswestry/score",
new { responses });
var finding = result.GetProperty("finding");
Console.WriteLine($"oswestry: {finding.GetProperty("score").GetDouble()} ({finding.GetProperty("band").GetString()})");

PowerShell

# Uses the Invoke-Engine helper from quickstart.md.
$responses = @{}
1..10 | ForEach-Object { $responses["item_$_"] = 3 }
$result = Invoke-Engine -Method Post -Path "/api/function/oswestry/score" -Body @{ responses = $responses }
"oswestry: $($result.finding.score) ($($result.finding.band))"

Clinical interpretation

  • What it measures. Self-reported functional disability attributed to low-back pain, across ten activities of daily living.
  • Higher is worse. Disability increases with score. This is the inverse of LEFS, where higher means better function — a common source of sign-flip bugs when clients consume both.
  • Rapid sensitivity. The ODI is responsive to change during acute low-back pain episodes, which makes it a reasonable time-series instrument in that context.

Intended use

  • Baseline and follow-up disability measurement in low-back pain workflows.
  • Outcome tracking for non-surgical and peri-surgical interventions.
  • Feeding the CDRI composite as the function-domain signal for lumbar complaints.

Mistaken use

  • Do not use for cervical or upper-extremity function. Use neck_disability or quick_dash instead.
  • Do not confuse the formula. mean × 20, not sum × 2, and not mean × 10. A 3 on every item yields 60%, not 30 and not 30%.
  • Do not omit item 8 for all subjects. The rubric today marks every item as required. A /score call that omits item_8 returns 400 ValidationError. In clinical practice, item 8 may be left blank when not applicable; your client should elicit an explicit response (even if symbolic) before submitting.
  • Do not compare ODI scores to QuickDASH scores. They both scale 0–100 but measure different regions and are not interchangeable.

Debugging

  1. Capture request_id. Present in every response body.
  2. Score unexpectedly halved or doubled. Confirm your client uses mean × 20 for comparisons, not sum × 2 or mean × 10. Compare against the worked example above (mean 3, score 60).
  3. 400 ValidationError with missing_items: ["item_8"]. Your form skipped the sex-life item. Add an explicit response path (the instrument's published wording permits "not applicable" which is conventionally coded to 0).

Change history

DateChange
2026-04-20Initial publication.