Loading documentation

Access required

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

Sign out
Skip to main content

Phenotype Classify

Status: stable Category: composite Added: 2026-04-20 Last reviewed: 2026-10-11

Summary​

A pattern-first path for callers that want the phenotype classification and its recommendations without the scoring envelope. The body is the same flat answers array /cdri/compute takes; the response is phenotype, confidence and recommendations only — no cdri score block, no phenotypes channel readings, no breadth, no acuity.

This is the home of recommendations. /cdri/compute publishes a measurement and nothing derived from it, so if you want suggested next steps — including escalations — this is the endpoint that produces them.

⚠ Not a clinical diagnosis​

The phenotype is a statistical summary, not a diagnosis. See composite-cdri-compute.md.

Endpoint​

FieldValue
MethodPOST
Path/api/phenotype/classify
Full URLhttps://engine.tripod-health.com/api/phenotype/classify
AuthenticationAPI key (required)
Request bodyapplication/json
Rate-limitedYes

There is no ?depth= parameter on this endpoint.

Request​

Same headers and body shape as /cdri/compute — a flat answers array of {item_id, value} objects, plus optional demographics and role. This endpoint does not take case, because it publishes no acuity.

It also takes an optional assist_context: the persona and instructions for the audience-framed ai_summary and per-item message text (on-demand references are rejected). Both texts pass the engine's outbound identifier scan; a summary that fails it comes back null, and a message that fails it leaves that item's message null.

Query parameters​

ParamDefaultValuesDescription
recommendrichrich | simple | rules | offControls the recommendations layer. See Recommendation modes.
audience(unset)provider | employee | employerSteers the audience-framed narrative text. When unset, narrative output stays null.

Recommendation modes​

ModeWhat runsai_summaryPer-item message
rich (default)Rules, then an AI summary and per-item humanization.PresentPresent
simpleRules, then an AI summary only. Items stay templated.Presentnull
rulesRules only. No model call, so it is deterministic and cheaper in latency.nullnull
offNo recommendations block on the response at all.——

Use rules when you render the action and rationale text yourself, and rich when you want prose a person can read directly. rules is the right default for a machine consumer.

Response​

Success — 200 OK​

A real capture under ?recommend=rules, from the ten-answer body in /cdri/compute:

{
"phenotype": {
"backend": "deterministic",
"model_version": "2026-09-15-standard-ladder",
"phenotype": "rtw_barrier",
"distribution": {
"pain_dominant": 0.1521,
"psychosocial_dominant": 0.1539,
"fear_avoidance_dominant": 0.152,
"rtw_barrier": 0.1847,
"multi_domain_catastrophic": 0.1304,
"iatrogenic_escalation": 0.0547,
"established_chronicity": 0.1722
},
"model_certainty": 0.1847,
"overall_level": 0.7951,
"trajectory": null,
"similar_cases": null,
"anomalies": null
},
"confidence": {
"overall": 0.4587,
"tier": "medium",
"breakdown": {
"evidence": 0.6332847231817376,
"input_completeness": null,
"imputation_variance": 0.5,
"model_certainty": 0.1847
}
},
"recommendations": {
"engine_version": "1.0.0",
"ruleset_version": "1.0.0",
"disclaimer": "The Trinity Engine is a decision-support tool. Output is not medical advice, not a diagnosis, not a prescription, and not a benefits determination. The calling organization is responsible for clinical governance and for the interpretation and use of these suggestions.",
"ai_summary": null,
"items": [
{
"id": "r_033d0ad2bdb35966",
"rule_id": "rec.data_acquisition.phenotype_top2_ambiguity",
"rule_version": "1.0.0",
"priority": "high",
"category": "data_acquisition",
"item_disclaimer": "Consider, not prescribe.",
"clinical_source": null,
"fired_under": {
"confidence_tier": "medium",
"phenotype_certainty": 0.1847
},
"action_type": "ask_questions",
"action": "Ask more about 'rtw_barrier' before acting on the pattern. POST /api/cdri/questions?phenotype=rtw_barrier&order=voi returns the bank questions that channel leads, ranked by how much confidence each one buys, and answering them is what widens the top-two gap.",
"target": {
"phenotype": "rtw_barrier",
"questions_url": "/api/cdri/questions?phenotype=rtw_barrier&order=voi"
},
"rationale": "Top phenotype 'rtw_barrier' at 0.18 is close to the second class at 0.17 (gap 0.01); certainty 0.18 is below the 0.45 threshold. Two patterns this close are not separable from the answers given so far.",
"triggers": {
"phenotype.model_certainty": 0.1847,
"phenotype.top_name": "rtw_barrier",
"phenotype.top_gap": 0.013
},
"expected_impact": {
"metric": "phenotype.model_certainty",
"direction": "increase"
},
"followup": {
"type": "recompute",
"endpoint": "/api/phenotype/classify",
"guidance": "Re-classify once the new answers are added to answers."
},
"message": null
}
],
"suppressed": [
{
"rule_id": "rec.clinical_action.rtw_barrier_fce_graduated",
"reason": "threshold_not_met",
"details": "Confidence tier 'medium' is blocked for clinical-action emission."
}
],
"cardinality_cap": null
},
"depth": "full",
"catalog_version": "0.36.0",
"request_id": "b1f2c3d4-5678-90ab-cdef-1234567890ab",
"timestamp": "2026-09-16T01:05:31.402118+00:00"
}

The phenotype and confidence blocks are identical in shape to their counterparts on /cdri/compute:

recommendations​

FieldTypeAlways presentDescription
engine_versionstringYesVersion of the recommendation engine.
ruleset_versionstringYesVersion of the rule set that ran.
disclaimerstringYesApplies to the whole block. Surface it wherever you surface items.
ai_summarystring | nullYesProse across the items. null under rules.
itemsarrayYesThe recommendations that fired. Empty is a valid result.
suppressedarrayYesRules that matched their domain and then declined to fire. See below.
cardinality_capinteger | nullYesSet when items were trimmed to a cap.

A recommendation item​

FieldTypeAlways presentDescription
idstringYesStable per firing. Use it to de-duplicate in a UI.
rule_idstringYesWhich rule produced it. Safe to branch on.
rule_versionstringYesVersion of that rule.
prioritystringYesurgent, high, or routine. The ordering signal for a UI.
categorystringYesescalation, clinical_action, data_acquisition, caution, or monitoring.
item_disclaimerstringYesPer-item qualifier, for example "Consider, not prescribe."
clinical_sourceobject | nullYesA citation when the rule rests on published guidance; null for an internal heuristic.
fired_underobjectYesThe confidence state at firing, so you can filter on your side.
action_typestringYesA short machine token for the kind of action.
actionstringYesWhat to do, in prose.
targetobjectYesThe specific subject of the action. Shape varies by action_type.
rationalestringYesWhy it fired, with the numbers it fired on.
triggersobjectYesThe exact values that satisfied the rule.
expected_impactobjectYesWhich metric the action should move, and in which direction.
followupobject | nullYesHow to close the loop — endpoint and guidance.
messagestring | nullYesHumanized text under rich; null otherwise.

suppressed is not an error list. A rule appears there when it matched the situation but declined to emit — most often because confidence was too low to responsibly suggest a clinical action. reason is one of threshold_not_met, data_unavailable, or overridden_by_higher_priority. Reading it tells you what would have fired with better evidence, which is usually more useful than the empty space.

Escalations are items, not a separate array​

There is no red_flags array. A safety escalation is a recommendation item with category: "escalation" and priority: "urgent". Filter for those two rather than looking for a dedicated field.

const urgent = result.recommendations.items.filter(
(item) => item.category === "escalation" && item.priority === "urgent",
);

Degraded phenotype — 200 OK with backend: "none"​

When the classifier cannot produce a phenotype, the shape is identical but every inner phenotype field is null:

{
"phenotype": {
"backend": "none",
"model_version": null,
"phenotype": null,
"distribution": null,
"model_certainty": null,
"overall_level": null,
"trajectory": null,
"similar_cases": null,
"anomalies": null
},
"confidence": {
"overall": 0.5,
"tier": "medium",
"breakdown": {
"evidence": null,
"input_completeness": null,
"imputation_variance": 0.5,
"model_certainty": null
}
},
"recommendations": {
"engine_version": "1.0.0",
"ruleset_version": "1.0.0",
"disclaimer": "The Trinity Engine is a decision-support tool. Output is not medical advice, not a diagnosis, not a prescription, and not a benefits determination. The calling organization is responsible for clinical governance and for the interpretation and use of these suggestions.",
"ai_summary": null,
"items": [],
"suppressed": [],
"cardinality_cap": null
},
"depth": "full",
"catalog_version": "0.36.0",
"request_id": "docs-phenotype-degraded",
"timestamp": "2026-09-16T00:00:00.000000+00:00"
}

The status stays 200. Most phenotype-conditional rules cannot fire without a phenotype, so items is usually empty here.

Status codes​

Same as /cdri/compute.

Examples​

The snippets assume the call() helper from quickstart.md.

curl​

curl -sS -X POST "https://engine.tripod-health.com/api/phenotype/classify?recommend=rules" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"answers": [{"item_id": "pain_intensity_now", "value": 5}, {"item_id": "expect_usual_work_6_months", "value": 4}, {"item_id": "modified_duty_available", "value": 6}]}'

Python (requests)​

# Uses the call() helper from quickstart.md.
result = call("POST", "/api/phenotype/classify?recommend=rules", {"answers": answers})

ph = result["phenotype"]
print(f"phenotype: {ph['phenotype']} (certainty {ph['model_certainty']})"
if ph["phenotype"] else "phenotype: unavailable")

for item in result["recommendations"]["items"]:
marker = "URGENT" if item["priority"] == "urgent" else item["category"]
print(f" [{marker}] {item['action']}")

Node.js (native fetch)​

// Uses the call() helper from quickstart.md.
const result = await call(
"POST", "/api/phenotype/classify?recommend=rules", { answers },
);

const ph = result.phenotype;
console.log(ph?.phenotype
? `phenotype: ${ph.phenotype} (certainty ${ph.model_certainty})`
: "phenotype: unavailable");

TypeScript​

// CdriResponse from composite-cdri-compute.md is a superset of this
// endpoint's response — reuse it minus the scoring blocks, plus
// recommendations, which /cdri/compute does not return.
type PhenotypeResponse = Omit<
CdriResponse,
"composite_id" | "cdri" | "phenotypes" | "breadth" | "acuity"
> & {
recommendations: RecommendationSet | null;
};

Intended use​

  • Getting suggested next steps. This is the only endpoint that returns them.
  • A lean pattern read. When a UI renders the phenotype label and an action list and nothing else, this skips the scoring blocks.
  • Closing the ambiguity loop. A low model_certainty produces a data_acquisition item naming the exact /cdri/questions call that would sharpen it; follow it and re-classify.
  • Mobile or low-bandwidth callers where payload size matters.

Mistaken use​

  • Do not use this for a severity readout — it carries no cdri score and no per-channel levels. Use /cdri/compute.
  • Do not look for red_flags. Escalations are items; filter on category and priority.
  • Do not treat phenotype.phenotype as a diagnosis — display it alongside model_certainty, which is frequently low.
  • Do not treat an empty items array as "nothing to do". Read suppressed: a clinical action withheld for low confidence is a prompt to gather more, not an all-clear.
  • Do not cache by request-body hash under rich or simple — those modes make a model call and the prose can vary across identical calls.
  • Do not submit an instrument's responses. The body is bank answers. To score a published instrument, use its own /score endpoint.

Change history​

DateChange
2026-04-20Initial publication.
2026-06-03Documented the degraded phenotype shape.
2026-09-16Body is a flat answers array of bank questions; instruments is gone. red_flags removed — escalations are recommendation items. overall_magnitude renamed overall_level, and confidence.breakdown now reports evidence with input_completeness always null. This page now owns the recommendation-mode and item documentation, which /cdri/compute no longer returns.
2026-10-11Accepts assist_context for the audience narrative text, which now passes the outbound identifier scan.