Loading documentation

Access required

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

Sign out
Skip to main content

Örebro Musculoskeletal Pain Screening

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

Summary​

The Örebro Musculoskeletal Pain Screening Questionnaire (OMPSQ) is Trinity's canonical yellow-flag screen for musculoskeletal pain. A 21-item self-report instrument covering pain intensity, function, mood, and work expectations — designed to flag psychosocial risk of delayed recovery, not to diagnose pain itself. Its presence is typically what triggers deeper assessment downstream.

Resource identity​

FieldValue
Categorypain
Resourceorebro
Instrument IDorebro
Rubric version1.0.0
Path prefix/api/pain/orebro

Operations​

OperationMethodPathContract
QuestionsPOST/api/cdri/questions?instruments=orebrocomposite-cdri-questions.md
ScorePOST/api/pain/orebro/scorepatterns-score.md

Items​

21 items, each on a 0–10 scale.

IDPrompt (paraphrased)
item_1Current pain intensity.
item_2Average pain in the last 3 months.
item_3Frequency of pain (never to always).
item_4Bother when trying to relax due to pain.
item_5Ability to walk.
item_6Ability to sleep normally.
item_7Ability to do usual activities.
item_8Ability to do light work for an hour.
item_9How anxious or tense you usually feel.
item_10Depressed or low mood.
item_11Perceived likelihood of working in 6 months.
item_12Expectation of returning to normal activities.
item_13Belief that increased pain indicates more damage.
item_14Belief that physical activity worsens pain.
item_15Avoidance of normal activities because of pain.
item_16Ability to self-manage the pain.
item_17Perceived fair chance of continuing to work.
item_18Support from co-workers / supervisor (reversed).
item_19Ability to control pain (reversed).
item_20Dedication to work duties (reversed).
item_21Fear-avoidance of physical activities.

Every item accepts integer values 0 through 10. Items marked "(reversed)" are worded so that higher numeric responses still contribute to a higher risk score under Trinity's scoring — no caller-side reversal is needed.

Authoritative item text comes from POST /api/cdri/questions?instruments=orebro. The text above is paraphrased for documentation; render the live response, not this document.

Scoring​

FieldValue
Methodweighted_sum with every weight equal to 1 (equivalent to a simple sum over the 21 items).
Score range0 – 210. Realistic clinical scores concentrate well below the upper bound.

The finding.raw.method field in the /score response confirms the method actually applied.

Bands​

BandRange (inclusive)Clinical meaning
low0 – 89Low psychosocial risk for delayed recovery.
medium90 – 105Elevated risk; consider further assessment.
high106 – 210High risk; further assessment indicated.

Thresholds follow widely-used OMPSQ cutoffs for distinguishing low versus elevated risk. Band names are scoring categories, not audience-facing display labels.

Required items​

Every item (item_1 through item_21) is required. A /score call missing any required item returns 400 ValidationError with a missing_items array. See patterns-score.md.

Worked example​

Every item answered with 5. For additional per-language scaffolding (retry handling, auth, error envelope), see quickstart.md; for the full shared /score contract see patterns-score.md.

Send:

POST /api/pain/orebro/score HTTP/1.1
Host: engine.tripod-health.com
apikey: $ENGINE_API_KEY
Content-Type: application/json

{
"responses": {
"item_1": 5, "item_2": 5, "item_3": 5, "item_4": 5, "item_5": 5,
"item_6": 5, "item_7": 5, "item_8": 5, "item_9": 5, "item_10": 5,
"item_11": 5, "item_12": 5, "item_13": 5, "item_14": 5, "item_15": 5,
"item_16": 5, "item_17": 5, "item_18": 5, "item_19": 5, "item_20": 5,
"item_21": 5
}
}

Receive (200 OK):

{
"instrument": "orebro",
"category": "pain",
"finding": {
"algorithm_id": "orebro",
"algorithm_version": "1.0.0",
"score": 105,
"band": "medium",
"raw": {
"rubric_version": "1.0.0",
"responded_items": 21
},
"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-orebro-score-basic",
"timestamp": "2026-04-21T23:14:52.684353+00:00"
}

Computation: the Örebro is a weighted sum; every item answered with 5 yields 105, which lands in the medium band (see the Bands table).

Calling in your language​

curl​

curl -sS -X POST "https://engine.tripod-health.com/api/pain/orebro/score" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"responses":{"item_1":5,"item_2":5,"item_3":5,"item_4":5,"item_5":5,"item_6":5,"item_7":5,"item_8":5,"item_9":5,"item_10":5,"item_11":5,"item_12":5,"item_13":5,"item_14":5,"item_15":5,"item_16":5,"item_17":5,"item_18":5,"item_19":5,"item_20":5,"item_21":5}}'

Python (requests)​

# Uses the call() helper from quickstart.md.
responses = {f"item_{i}": 5 for i in range(1, 22)}
result = call("POST", "/api/pain/orebro/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: 21 }, (_, i) => [`item_${i + 1}`, 5]),
);
const result = await call("POST", "/api/pain/orebro/score", { responses });
console.log(result.finding.score, result.finding.band);

TypeScript​

// Uses the typed call<T>() helper from quickstart.md.
// ScoreResponse is the shared type from patterns-score.md.
const responses = Object.fromEntries(
Array.from({ length: 21 }, (_, i) => [`item_${i + 1}`, 5]),
);
const result = await call<ScoreResponse>(
"POST",
"/api/pain/orebro/score",
{ responses },
);

Go​

// Uses the call() helper from quickstart.md.
responses := make(map[string]int, 21)
for i := 1; i <= 21; i++ {
responses[fmt.Sprintf("item_%d", i)] = 5
}
result, err := call("POST", "/api/pain/orebro/score",
map[string]any{"responses": responses}, 3)
if err != nil {
panic(err)
}
finding := result["finding"].(map[string]any)
fmt.Printf("orebro: %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 <= 21; i++) {
if (i > 1) body.append(",");
body.append("\"item_").append(i).append("\":5");
}
body.append("}}");
String result = call("POST", "/api/pain/orebro/score", body.toString(), 3);
System.out.println(result);

C# (.NET HttpClient)​

// Uses the Call() helper from quickstart.md.
var responses = Enumerable.Range(1, 21)
.ToDictionary(i => $"item_{i}", _ => 5);
var result = await Call(HttpMethod.Post, "/api/pain/orebro/score",
new { responses });

var finding = result.GetProperty("finding");
Console.WriteLine($"orebro: {finding.GetProperty("score").GetDouble()} ({finding.GetProperty("band").GetString()})");

PowerShell​

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

Clinical interpretation​

  • What it screens. Psychosocial risk of delayed recovery from musculoskeletal pain. The Örebro is a screening tool, not a diagnostic one. A high band flags "look further," not "this is chronic pain."
  • Who it is for. Typically used early after onset of a work-related or new musculoskeletal complaint, to stratify who needs structured psychosocial intervention.
  • What it is not. Not a measure of pain intensity alone (use pain_scale for that), not a diagnosis of depression or anxiety (use depression_screen / anxiety_screen for those), not a determination of work capacity.

Trinity returns a score and a band; any clinical decision built on top of it belongs to the caller.

Intended use​

  • Early-onset screening for musculoskeletal complaints when the caller needs to decide whether to escalate to structured psychosocial assessment.
  • Feeding the CDRI composite as the canonical pain-domain yellow-flag signal.
  • Tracking change over time. A repeat Örebro weeks later can be compared to the first to see whether psychosocial risk is shifting; the score and band are stable contracts suitable for time-series.

Mistaken use​

  • Do not use this for acute pain intensity. It is a multi-domain screen; the score conflates pain, function, mood, and expectations. Use pain_scale for a pure intensity measure.
  • Do not interpret high as a diagnosis. It flags risk of delayed recovery. The clinical follow-up (depression, kinesiophobia, etc.) is determined by the caller, potentially with other Trinity instruments.
  • Do not pre-reverse any items. Trinity scores every item in its native orientation; sending reversed values changes the result incorrectly.
  • Do not compare scores across rubric versions. A bump to version can change item weights or band cutoffs. Pin your comparison analyses to a single rubric version and refresh when it bumps.

Debugging​

  1. Capture request_id. Present in every response body.
  2. 400 ValidationError with missing_items. Send all 21 items — all are required.
  3. Score seems too high or too low by exactly the score of one item. Confirm every id is in the response map; a missed item_N silently contributes 0 to the sum in the pipeline's internal math, but the strict /score gate catches this before scoring runs (raising ValidationError). If you still see an off-by-one-item score, double-check your client's body assembly.
  4. Band appears unknown in a response. The score fell outside every defined band range. Not possible under the current rubric (0–210 covers the whole range), but if you see it, report the request id.

Change history​

DateChange
2026-04-20Initial publication.
2026-10-14The engine assigns every request ID; an X-Request-ID request header is not used.