Loading documentation

Access required

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

Sign out
Skip to main content

Claim-Cost Classification

Status: beta Category: claimcost Added: 2026-07-06 Last reviewed: 2026-07-06

Summary​

Classify the likely cost of a workers' compensation claim from three de-identified inputs — the injury, the body part, and the worker's age. One call returns two independent classifications: a binary cost tier (High / Low) and a three-band cost band (High / Medium / Low). Each carries a confidence and the full probability distribution, so you can apply your own threshold instead of taking the top label as final.

This is a statistical model, not clinical or actuarial advice. It does not set a reserve, price a policy, or make a claim decision — it estimates a cost category from a narrow feature set. Treat the output as one signal among many.

Endpoint​

FieldValue
MethodPOST
Path/api/claimcost/classify
Full URLhttps://engine.tripod-health.com/api/claimcost/classify
AuthenticationAPI key (required)
Request bodyapplication/json
Response bodyapplication/json
IdempotentYes (deterministic classifier — the same input yields the same output)
Rate-limitedYes

Purpose​

Use this endpoint when you have a coded injury, a coded body part, and an age, and you want a fast cost-category read. It is built to triage or prioritize — to separate the claims likely to run expensive from the ones likely to stay cheap — not to produce a dollar figure.

The two valid input vocabularies are fixed and case-sensitive at the word level. Fetch them from GET /api/claimcost/categories and validate or populate your inputs against that list; an unrecognized value returns 400.

Authentication​

Send a valid API key in the apikey header. A missing or unknown key returns 401 Unauthenticated at the gateway before the request reaches the engine. See authentication.

Request​

Headers​

HeaderRequiredDescription
apikeyYesConsumer API key.
Content-TypeYesMust be application/json.

Path parameters​

None.

Query parameters​

None.

Body​

{
"injury": "strain or tear",
"bodyPart": "low back area",
"age": 47
}

Body fields​

FieldTypeRequiredConstraintsDescription
injurystringYesnon-empty, ≤ 200 chars, must match a known categoryThe injury cause/nature. Case-insensitive, but the words must match one of the accepted injuries values verbatim.
bodyPartstringYesnon-empty, ≤ 200 chars, must match a known categoryThe affected body part. Case-insensitive, but the words must match one of the accepted bodyParts values verbatim. Maps to the model's body_part.
ageintegerYes0 ≤ age ≤ 120The worker's age as a whole number of years.

Category matching is exact after case-folding and trimming: "low back area", "Low Back Area", and "LOW BACK AREA" are equivalent, but "lower back" is not a known value and returns 400. Unknown top-level fields are ignored.

De-identification requirement​

Like every endpoint, the body is scanned for identifiers inbound. age must be a whole number of years — never a date of birth. A date-shaped value is both wrong for the model and an identifier shape that returns 400 DeIdentificationViolation. Do not add names, dates, record numbers, or free-text notes to the body. See conventions.md.

Response​

Success — 200 OK​

{
"model": "claimcost",
"version": "0.2.0",
"costTier": {
"prediction": "High",
"confidence": 0.82,
"probabilities": {
"High": 0.82,
"Low": 0.18
}
},
"costBand": {
"prediction": "Medium",
"confidence": 0.54,
"probabilities": {
"High": 0.3,
"Medium": 0.54,
"Low": 0.16
}
}
}

Response fields​

FieldTypeAlways presentDescription
modelstringYesThe model that answered (claimcost).
versionstringYesThe model version that produced this result. Reported by the model; expect it to advance as the model is retrained.
costTierobjectYesThe binary cost classification (High / Low).
costTier.predictionstringYesThe winning label: High or Low.
costTier.confidencenumberYesProbability of the winning label, 0.0–1.0.
costTier.probabilitiesobjectYesFull probability map keyed by label (High, Low); values sum to ~1.0.
costBandobjectYesThe three-band cost classification (High / Medium / Low).
costBand.predictionstringYesThe winning label: High, Medium, or Low.
costBand.confidencenumberYesProbability of the winning label, 0.0–1.0.
costBand.probabilitiesobjectYesFull probability map keyed by label (High, Medium, Low); values sum to ~1.0.

costTier and costBand are independent classifications from the same inputs, not two views of one score. They can disagree (a Low tier with a Medium band is possible); use whichever granularity fits your use, or both.

There is no request_id or timestamp in the success body. To correlate a successful call, read the X-Request-ID response header: it is the gateway's trace ID for the request (it does not match an engine request_id), and support can find the call from it. Error responses carry both in the envelope.

Status codes​

CodeMeaningWhen
200OKClassification succeeded.
400ValidationErrorMissing or empty injury / bodyPart, a value over 200 characters, a non-integer or out-of-range age, or an unrecognized injury / bodyPart category. The field extra names the offender for field-shape errors; an unknown-category message quotes the offending value.
400DeIdentificationViolationThe body contained an identifier shape (e.g. a date supplied for age).
401UnauthenticatedMissing or invalid API key.
402PaymentRequiredInsufficient credits or an exhausted budget. See credits.md.
413PayloadTooLargeBody exceeds the 512 KB limit.
415UnsupportedMediaTypeContent-Type is not application/json.
429RateLimitedPer-consumer rate limit exceeded. See Retry-After.
500InternalErrorUnexpected server-side failure. Include request_id when reporting.
502UpstreamErrorThe model service was unreachable or returned an unexpected shape.
503ServiceUnavailableA required dependency is temporarily unhealthy.
504UpstreamTimeoutThe model call exceeded the engine's budget.

Error envelope​

All non-2xx responses use the uniform envelope:

{
"timestamp": "2026-10-14T00:59:06.842Z",
"error": "ValidationError",
"message": "Field 'age' must be between 0 and 120",
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b",
"field": "age"
}

See errors.md for the full code list.

What a call costs​

A successful classification is billed at a fixed per-call credit cost. Unlike /api/ask/run, the price does not vary with input size — this is a fixed-cost route like the analytics endpoints. The exact credits a call spent are returned in the X-Credits-Used header, and the dollar cost in X-Credits-Cost-USD; treat those as the source of truth for what you were charged. See credits.md for the credit model and where to find current per-route costs.

Validating inputs first with the cheap GET /api/claimcost/categories call avoids paying for a classify request that would only 400 on an unknown category.

Examples​

curl — success​

curl -sS -X POST "https://engine.tripod-health.com/api/claimcost/classify" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"injury":"strain or tear","bodyPart":"low back area","age":47}'

Expected response:

{
"model": "claimcost",
"version": "0.2.0",
"costTier": {
"prediction": "High",
"confidence": 0.82,
"probabilities": { "High": 0.82, "Low": 0.18 }
},
"costBand": {
"prediction": "Medium",
"confidence": 0.54,
"probabilities": { "High": 0.3, "Medium": 0.54, "Low": 0.16 }
}
}

curl — unknown category (400)​

curl -sS -X POST "https://engine.tripod-health.com/api/claimcost/classify" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-w "\nHTTP %{http_code}\n" \
-d '{"injury":"lower back","bodyPart":"low back area","age":47}'

Receive (400):

{
"timestamp": "2026-10-14T00:59:06.842Z",
"error": "ValidationError",
"message": "unknown injury: 'LOWER BACK'",
"request_id": "ec9e3458-bec0-4ccd-af33-8ba771912dd5"
}

Python (requests)​

# Uses the call() helper from quickstart.md.
result = call("POST", "/api/claimcost/classify", body={
"injury": "strain or tear",
"bodyPart": "low back area",
"age": 47,
})
print(result["costTier"]["prediction"], result["costTier"]["confidence"])
print(result["costBand"]["prediction"], result["costBand"]["confidence"])

Node.js (native fetch)​

// Uses the call() helper from quickstart.md.
const result = await call("POST", "/api/claimcost/classify", {
injury: "strain or tear",
bodyPart: "low back area",
age: 47,
});
console.log(result.costTier.prediction, result.costTier.confidence);
console.log(result.costBand.prediction, result.costBand.confidence);

TypeScript​

interface CostClass {
prediction: string;
confidence: number;
probabilities: Record<string, number>;
}

interface ClaimcostClassifyResponse {
model: string;
version: string;
costTier: CostClass;
costBand: CostClass;
}

const result = await call<ClaimcostClassifyResponse>(
"POST",
"/api/claimcost/classify",
{ injury: "strain or tear", bodyPart: "low back area", age: 47 },
);

Intended use​

  • Triage and prioritization — flag the claims most likely to run expensive so they get earlier attention.
  • Bulk scoring of coded injury records where you already hold a known injury cause, body part, and age.
  • Confidence-aware routing — read probabilities and apply your own threshold rather than trusting a narrow-margin top label.

Mistaken use​

  • Do not treat the output as a dollar amount or a reserve. It is a cost category, not a figure. Setting a reserve is a human, actuarial decision.
  • Do not guess at category strings. An unlisted value returns 400. Fetch the accepted values from /api/claimcost/categories and match against them.
  • Do not send a date of birth in age. Send a whole number of years. A date trips the de-identification scan (400).
  • Do not use this for free-text questions about a claim. That is /api/ask/run. This endpoint takes a fixed feature set and returns fixed labels.

Debugging​

  1. Capture the request_id from the error envelope before anything else. A successful call, or a response with no body from the engine, has no request_id; capture the X-Request-ID response header (the gateway's trace ID) instead.
  2. 400 ValidationError with a field. A field-shape problem — injury / bodyPart missing, empty, or too long, or age not a whole number in 0–120. Fix the named field.
  3. 400 ValidationError with no field, message unknown injury: / unknown body_part:. The value is not a recognized category. Pull the current list from /api/claimcost/categories.
  4. 400 DeIdentificationViolation. Something identifier-shaped is in the body — most often a date passed for age. Send an integer.
  5. 402 PaymentRequired. Out of credits or budget; see credits.md.
  6. 502 UpstreamError. The model service is unreachable or returned an unexpected shape. Retry with backoff; if it persists, check model-services-health.md and quote the request_id in a ticket.

Rate limits​

Per-consumer limits are enforced at the gateway; see rate-limits.md. Responses include the standard RateLimit-* headers.

Change history​

DateChange
2026-07-06Initial publication (beta).
2026-10-14The engine assigns every request ID; an X-Request-ID request header is not used. The X-Request-ID response header is the gateway's trace ID for the request and does not match request_id; quote request_id to support.