Skip to main content
POST /v2/retrieve is the main path. In one call it runs:
  1. query maker — classifies what the last message adds (new question, refinement, patient fact) and reformulates it;
  2. two-path retrieval — semantic ‖ concepts + graph, in parallel;
  3. context — the knowledge units retained, their decision tables, their documents;
  4. synthesis — a Markdown answer, cited on those units and nothing else.
No judge, no safety sweep: both are asked for explicitly (see deliberate).

Minimal request

The fields that matter

The retrieval knobs (concept_k, chunk_k, mku_k, mku_weight, table_k, use_cross_refs) are exposed, but their defaults are the measured operating point. Changing them steps outside what the evaluations cover. Each is detailed in the API Reference tab.

What comes back

Logic units: scores and trees

Not every knowledge unit is a flat rule. Two shapes carry an executable logic:
  • a score — weighted questions, a total, interpretation bands;
  • a tree — nodes, branches, terminal courses of action.
The server never lets the model compute them. It enumerates bounded choices (elicitations[].steps[]), the client displays them, the clinician answers, and the next turn passes those answers back in logic_answers: the computation is then done by a deterministic engine, and it is its result (computed) that enters the synthesis context.
A unit is addressed by mku_id (the citable identity) or by mku_key (the readable key): the latter survives a re-extraction, which matters when a form stays open across turns. Depending on the score’s shape, you answer with answers (question → option), checked (the ticked labels) or level (a band of an ordinal scale); a tree answers with answers, node to chosen branch. Each step carries a kind: question, items, niveau (a band to pick) or branchement (a tree branch). A client that ignores elicitations gets the same written answer as before — the unit is then cited without being run.

Only one unit is expanded

One answer can retrieve several logic units. A clinician fills in only one: the one they came for. So only one carries its steps — expanded: true — the best-ranked one, or the one the question names if it names any. The others stay in elicitations with expanded: false and steps: []. They keep everything else: identity, title, total_max, bands, graph. Enough to offer them without displaying them, and to open one client-side without a second call. A unit the request carried logic_answers for is always expanded, whatever its rank: an open form does not close because another score ranks higher.

A score carries its interpretation — bands

bands gives a score’s interpretation bands: what a total means, as the source publishes it next to the scale. The client can therefore show a conclusion as soon as the clinician ticks a box, with no round trip.
Order is the meaning. These bands are an if / else if chain: each one is bounded by those before it. Evaluate them by ascending rang, first match wins, and stop there. Reading them as independent intervals produces gaps and overlaps — measured on 43 scores out of 85.And a pur_total: false band depends on something other than the total: the engine refuses to conclude on it. Show its condition, never a conclusion.
computed.outcome remains the only binding conclusion — it comes from the engine. bands is for displaying the scale and situating a total, not for deciding.

A tree carries its graph — graph

steps only contains nodes that require a decision. Pass-through nodes and terminal actions are not steps — yet the engine walks the former on its own and concludes on the latter. graph returns the whole tree and removes the asymmetry: what the engine walks, the client can see. On options, to carries the id of the destination node; leads_to carries its label. Navigate by to: two nodes can share a label, and a pass-through node appears in no steps[].key. computed.path_ids gives the walked path as ids, computed.path the same nodes as labels — one for one.

Computing without searching again

For the intermediate turns of an open form — ticking a box, picking a branch — use /v2/logic/compute rather than calling /v2/retrieve again. It is faster, and above all deterministic: the unit is designated by its key, not re-ranked.

Three formats, one answer

Negotiation happens on Accept rather than a ?format= parameter: the client states what it can read. In JSON, answer’s newlines are escaped as \n: read it with jq -r '.answer'.

Errors