Skip to main content
POST
GraphRAG retrieving (MKF 0.1.3, LangGraph 2-paths)

Authorizations

Authorization
string
header
required

Locus API key — paste the raw lsk_… value (no 'Bearer ' prefix) — or a B2B session token minted by POST /v2/session-token.

Headers

accept
string
default:application/json
X-Locus-User-Ref
string | null

Le compte, tel que l'intégrateur le nomme — pour l'app Locus, l'identifiant Clerk. REQUIS quand le quota de crédits est actif (LOCUS_CREDITS_ENABLED) ; ignoré sinon, comme aujourd'hui.

Inutile avec un jeton de session B2B : le jeton porte déjà le compte, SIGNÉ — c'est alors lui qui fait foi (cf. resolve_user_ref).

Required string length: 1 - 200

Body

application/json
query
string
required
include_usage
boolean
default:false

Rendre le bloc usage : tokens consommés et coût estimé de CET échange. Le comptage a lieu de toute façon — il part dans la trace serveur quoi qu'il arrive ; ce drapeau ne décide que de l'exposer au client, qui n'a pas toujours de quoi l'afficher.

Coût d'une CONVERSATION : la réponse ne porte que le delta du dernier échange, jamais un cumul. Le serveur ne conserve pas la conversation, et un cumul qu'il calculerait sur la seule history reçue serait faux dès qu'un client tronque ses tours. Au client d'additionner ce qu'il stocke.

patient_ehr
string | null

Dossier patient libre (EHR)

history
RetrieveTurn · object[]

Tours précédents, du plus ancien au plus récent. Sert UNIQUEMENT au query-maker, pour qualifier ce que le dernier message apporte : une nouvelle question, une précision, ou un fait patient. Les réponses antérieures ne sont jamais données au modèle de rédaction — elles n'ont pas de règle derrière elles et ne peuvent pas faire source.

concept_k
integer
default:5
Required range: 1 <= x <= 20
chunk_k
integer
default:10

0 = pas de chemin documentaire

Required range: 0 <= x <= 50
mku_k
integer
default:12

Top-k MKU vectoriel ; 0 = pas de chemin MKU

Required range: 0 <= x <= 50
logic_min_similarity
number
default:0.6

Plancher de similarité d'une UNITÉ LOGIQUE proposée sous la réponse — cosinus normalisé dans [0,1], 0,5 = orthogonal. Le tri principal est fait par l'ANCRAGE (l'unité ne sort que si la réponse cite son document) ; ce plancher n'écarte que ce que l'ancrage laisserait passer par accident. Valeur NON MESURÉE, posée bas — c'est un axe de campagne.

Required range: 0 <= x <= 1
drug_k
integer
default:4

Passages de RCP versés au CONTEXTE de rédaction — la lane connaissance médicament. 4 par défaut (config promue, cf. REFERENCE_CONFIG) ; 0 coupe le chemin et redonne le point de fonctionnement d'avant promotion. À ne pas confondre avec drugs en réponse, qui est la CARTE : elle est collectée après la rédaction et ne l'alimente pas.

Required range: 0 <= x <= 12
mku_weight
number
default:0.75

Pondération hybride d'accès aux MKU : 0 = concepts seuls (un MKU n'est atteignable que par les termes de son propre verbatim), 1 = vecteurs seuls (sur l'embedding contextualisé doc+section), 0.5 = les deux. Défaut 0.75 : la config PROMUE par l'ajustement (run #50, hybrid·w0.75·x1·c10·m12·k5·t5). Voir REFERENCE_CONFIG.

Required range: 0 <= x <= 1
table_k
integer
default:5

Top-k tables de décision (vecteur) ; 0 = pas de tables directes

Required range: 0 <= x <= 20
deliberate
boolean
default:false

Seconde lecture : confronte les critères des règles au dossier, va chercher une définition manquante, et ne pose une question qu'en dernier recours. Hors du point de fonctionnement de référence — l'activer change le coût et n'est pas encore mesuré par les évals.

orchestrate
boolean
default:false

Orchestration : les unités logiques (score, arbre) sont résolues AVANT la rédaction — par ce que la question et le dossier écrivent, puis par évaluation partielle — et une ambiguïté de la question qui change les règles applicables est repérée. Quand une donnée manquante peut changer la conduite, la réponse est un FORMULAIRE (orchestration.form) et answer est vide : renvoyer la même question avec slot_answers remplis et elicitation_round incrémenté. Hors du point de fonctionnement de référence — non mesuré par les évals.

slot_answers
RetrieveSlotAnswer · object[]

Les réponses au formulaire du tour précédent (orchestration.form), par key. Sans état : le serveur ne garde pas le formulaire, le client le renvoie rempli.

elicitation_round
integer
default:0

Combien de formulaires ont DÉJÀ été posés dans ce fil. Tenu par le client : orchestration.round + 1 après un formulaire.

Required range: 0 <= x <= 10
contexte
RetrieveContexte · object | null

À la reprise d'un formulaire : le orchestration.contexte rendu avec lui, renvoyé tel quel. La reprise prolonge alors ce contexte — relu par identifiant, complété par une recherche ciblée sur les précisions — au lieu de refaire l'analyse et la recherche.

authority_min_similarity
number
default:0.8

Avec orchestrate : la similarité au-dessus de laquelle une source d'AUTORITÉ (Antibioclic) est dite couvrir la question. Ses unités de la pathologie la mieux classée passent alors en tête, l'arbre d'abord — rien n'est retiré. En dessous, la pipeline par défaut répond seule. Valeur non mesurée.

Required range: 0 <= x <= 1
max_elicitation_rounds
integer
default:1

Au-delà, on répond toujours — conditionnellement sur ce qui reste ouvert. 0 = jamais de formulaire (l'orchestration calcule et désambiguïse sans rien demander). UN par défaut : un formulaire pose tout le chemin d'un coup ; un second tour lassait le praticien.

Required range: 0 <= x <= 5
mode
enum<string> | null

Le mode de réponse. approfondi : raisonnement approfondi — avec orchestrate, questions de précision quand elles changent la conduite. rapide : réponse directe. Les moyens de chaque mode sont choisis par le serveur. Absent : le défaut du serveur.

Available options:
approfondi,
rapide
answer_system_prompt
string | null

Remplace INTÉGRALEMENT le prompt système de RÉDACTION pour CETTE requête — le chemin pour comparer deux formulations sur la même question et le même graphe, sans redéployer. Le prompt par défaut se lit sur GET /v2/answer-prompt, qui est le point de départ naturel d'une variante.

Remplacement, pas supplément : les consignes de citation, de rang des sources et d'interdits cliniques partent avec l'original si la variante ne les reprend pas. C'est voulu — on compare des prompts ENTIERS, pas des rustines — et c'est exactement pourquoi le champ n'est ouvert que HORS du canal prod (cf. LOCUS_CHANNEL) — 400 PROMPT_OVERRIDE_DISABLED ailleurs, jamais un silence. None = le prompt du serveur.

Maximum string length: 20000
use_cross_refs
boolean
default:false

Étendre le résultat aux MKU voisins par CROSS_REF. Défaut False : les arêtes du corpus portent trop de liens superflus et d'erreurs pour qu'on serve ce signal (2 septembre 2026). Passer à true réactive l'expansion — utile pour mesurer ce que la coupure coûte une fois la passe de cross-ref assainie.

concept_mku_k
integer
default:60

Top-k MKU du chemin CONCEPTUEL, classés par nombre de concepts touchés.

Required range: 1 <= x <= 400
cross_ref_hops
integer
default:1

Profondeur du voisinage CROSS_REF. Coût EXPONENTIEL : l'expansion énumère des chemins. 3 était le défaut servi, et c'est lui qui a bloqué la prod quand le graphe a grossi.

Required range: 1 <= x <= 3
cross_ref_seeds
integer
default:40

MKU primaires (les mieux classés) semant l'expansion CROSS_REF.

Required range: 1 <= x <= 200
cross_ref_k
integer
default:400

Arêtes CROSS_REF rendues au plus ; celles entre primaires d'abord.

Required range: 1 <= x <= 2000
logic_answers
RetrieveLogicAnswer · object[]

Ce que le praticien a répondu aux unités LOGIQUES (score, arbre) retrouvées au tour précédent (elicitations). Le serveur ne devine rien : sans réponses, un score est PROPOSÉ (ses questions sont rendues) ; avec elles, il est CALCULÉ par le moteur, et c'est le résultat calculé qui entre dans le contexte de rédaction — jamais une somme faite de tête par le modèle.

source_weights
Source Weights · object

Multiplicateur de score par ÉDITEUR ({"recomedicales": 1.2}), appliqué à TOUTES les lanes classantes : chunks, tables, et les deux chemins d'accès aux MKU. Une source absente vaut 1.0.

Un poids ≠ 1 déclenche un SUR-TIRAGE des recherches vectorielles (on demande plus que k, on pondère, puis on coupe à k) : sans lui, la pondération ne pourrait que réordonner ce que le cosinus a déjà laissé passer, jamais faire entrer ce qu'il avait écarté. À poids neutres, aucun sur-tirage et aucun changement de comportement.

À ne pas confondre avec sources / exclude_sources, qui décident ce que le corpus CONTIENT pour cette requête : un poids ne retire rien, il déplace dans le classement. Les deux se cumulent.

sources
string[] | null

Ne retenir que ces éditeurs (« HAS », « ebmfrance »… — cf. GET /v2/sources). Absent = tout le corpus. Une liste VIDE est refusée : « aucune source cochée » et « toutes les sources » sont deux intentions opposées, et les confondre servirait le corpus entier à un client qui croyait l'avoir restreint.

Required array length: 1 - 32 elements
exclude_sources
string[] | null

Écarter ces éditeurs. Appliqué APRÈS sources — utile pour retirer un éditeur sans avoir à énumérer tous les autres.

Required array length: 1 - 32 elements
app_version
string | null

Version publiée de l'app appelante (p.ex. 1.4.2).

Maximum string length: 64
app_build
string | null

Le build EXACT : SHA git court sur le web, numéro de build natif sur iOS/Android. C'est lui qui distingue deux binaires d'une même version publiée — sans lui, 1.4.2 désigne plusieurs binaires et un bug n'est pas rejouable.

Maximum string length: 64
app_platform
string | null

web | ios | android.

Maximum string length: 32
app_surface
string | null

D'OÙ la question est posée : app (l'app Locus), embed (un widget intégré chez un client), console (l'essai depuis une console partenaire), ou ce que vous voudrez.

À ne pas confondre avec app_platform, qui dit sur quel SOCLE le binaire tourne. Un widget intégré est du web comme l'app : sans ce champ, les deux sont indiscernables dans les traces, et « quelle part de l'usage passe par le widget » n'a pas de réponse — sinon en la déduisant du client, ce qui cesse de marcher le jour où un intégrateur appelle AUSSI l'API depuis son serveur.

Maximum string length: 32
conversation_id
string | null

Le FIL auquel cette question appartient, tel que le client le nomme. Déclaratif et journalisé tel quel, comme les champs ci-dessous : le serveur ne s'en sert pour rien, et surtout pas pour retrouver un contexte — l'historique qui alimente le query-maker voyage dans history, explicitement, à chaque requête.

Il existe pour la RELECTURE. Sans lui, la seule façon de rapprocher deux réponses d'un même échange était la session d'analytique (app_session_id), qui n'est pas un fil : elle en contient parfois deux, et un fil repris le lendemain est dans une autre session. C'est le même identifiant que celui de /v2/conversations — dont la payload, elle, reste opaque au serveur.

Maximum string length: 64
app_session_id
string | null

L'identifiant de SESSION de l'analytique du client ($session_id de PostHog), s'il y en a une. Déclaratif et journalisé tel quel, comme les trois champs ci-dessus : le serveur ne s'en sert pour rien.

Il existe pour une seule raison, et elle vaut la colonne : c'est ce qui relie une réponse notée à l'ENREGISTREMENT de la session où elle a été lue. Sans lui, un pouce baissé dit ce que le moteur a répondu mais pas ce que la personne faisait, ni ce qu'elle a vu avant de le baisser — et il faut alors retrouver la session à la main, par l'heure, ce que personne ne fait deux fois.

Jamais d'identité : l'identifiant de session est opaque et tournant. Le distinct_id, lui, ne passe pas.

Maximum string length: 128

Response

Successful Response

query
string
required
trace_id
string
default:""

L'identifiant de CETTE réponse, frappé par le serveur avant de la rendre. C'est la clé à renvoyer à POST /v2/feedback pour attacher un retour utilisateur — sans lui, un pouce levé ne désigne rien.

Vide quand la journalisation des traces est coupée (LOCUS_TRACES_ENABLED=false) : le client doit alors simplement ne pas proposer le retour, plutôt que de poster dans le vide.

usage
UsageReport · object | null

Consommation de cet échange. Présent uniquement si la requête portait include_usage: true — absent ne veut donc pas dire gratuit.

core_version
string
default:""

La version du core qui a produit cette réponse, lisible : 0.2.0+a1b2c3d (r:4f9e2b71) — version applicative, commit déployé, empreinte du chemin de lecture. Rendue AUSSI dans la payload (et pas seulement écrite en base) pour qu'un client puisse l'afficher dans un rapport de bug sans avoir à interroger /health.

reformulated
string
default:""
ehr_summary
string
default:""
turn_kind
string
default:""

nouvelle_question | precision_question | fait_patient

ehr_additions
string
default:""

Le fait clinique nouveau apporté par ce tour. À APPENDRE au dossier côté client : c'est là qu'il sera confronté aux critères des règles. Un fait resté dans la question ne change aucune recommandation.

answer
string
default:""

Réponse rédigée, en Markdown (titres, listes, tableaux, citations). En JSON les sauts de ligne sont échappés en \n : lire avec jq -r '.answer', ou demander Accept: text/markdown pour recevoir le Markdown brut, ou Accept: text/html pour une page lisible.

answer_short
string
default:""

La conduite à tenir en une phrase, DÉRIVÉE de answer (son titre de niveau 1). Champ de confort : answer reste le Markdown complet, titre compris, donc rien ne casse pour un client qui l'ignore.

answer_format
string
default:markdown

Format de answer. Déclaré pour qu'un client sache le rendre.

mkus
RetrieveMku · object[]
chunks
RetrieveChunk · object[]
tables
RetrieveTable · object[]
docs
RetrieveDoc · object[]

Documents mobilisés, dédupliqués — métadonnées et lien profond.

source_scope
RetrieveSourceScope · object | null

La restriction d'éditeurs sous laquelle CETTE réponse a été produite, en identifiants canoniques. null = tout le corpus, ce qui est le cas par défaut — rien ne change pour un client qui n'en demande pas.

drugs
RetrieveDrug · object[]

Médicaments rattachés aux règles citées — lane SÉPARÉE des MKU (contrat C4) : une rubrique de RCP n'est jamais promue en unité citable, et n'entre pas dans le contexte de rédaction.

elicitations
RetrieveElicitation · object[]

Les unités logiques retrouvées (score, tree) et ce qu'elles demandent. Vide quand aucune n'a remonté. Un client qui ignore ce champ ne casse pas : les mêmes unités restent dans mkus.

rcp
RetrieveRcp · object[]

Passages de RCP VERSÉS au contexte de rédaction, et donc citables sous [rcp:{id}]. Vide quand la lane est coupée (drug_k: 0, le défaut) ou quand la question n'appelle aucune donnée d'AMM. Distinct de drugs, qui est la carte et n'alimente pas la réponse.

cross_refs
RetrieveCrossRef · object[]
concepts
RetrieveConcept · object[]
deliberation
RetrieveDeliberation · object | null

Présent uniquement si deliberate était demandé.

orchestration
RetrieveOrchestration · object | null

Présent uniquement si orchestrate était demandé.