Skip to main content
An ExoBrain is a small neural model trained on one organization’s knowledge graph. It is what makes POST /v1/retrieve return a cognition block instead of a ranked list. Without one, retrieval still works and says so honestly. With one, you get focal nodes, gate confidence and a fast-versus-slow reasoning tier.

Before you start

An admin key

POST /v1/brain/train requires the admin scope. Reads do not.

A graph with content

A brain trains on the graph. Too few nodes and the train is refused.

Patience for the job

Training runs on GPU hardware as a queued job, not inline.

Check what you have now

Start here, because the answer is often “nothing yet, and that is fine”.
GET /v1/brain/info reports which artifact is loaded for your organization, how big it is in model parameters and in graph nodes and edges, which backend is serving it, and a training block describing the most recent or in-flight train. When the organization has never trained, it degrades to a training status of none rather than failing, so this call is always safe to make.
The response shape for this route is not pinned in the OpenAPI contract, so treat the field names above as the documented contents rather than a fixed schema, and read defensively. Everything else on this page is schema-pinned.

Training

Enqueue the train

202 Accepted
Both body fields are optional. reason defaults to "manual" and is there so your audit log says why. epochsScale defaults to 1.0; raise it for a longer train, lower it for a cheaper one.

Watch it

Poll GET /v1/brain/info and read the training block. Only one train may be in flight per organization, so a second request while one is queued or running returns 409. That is a guard, not a failure: read it as “already training”.
You can also subscribe to brain.trained, an organization-scoped event that reaches every listener. See Reacting to change.

Confirm it is serving

A successful train does not silently change your reads. Confirm by looking at path on a retrieval:
Before the train this reads {"path": "hybrid", "degraded": true, "degradationReason": "no_brain"}. The flip is the proof.
A failed train leaves the previous brain serving. The new artifact is published only after it passes a numerical parity gate, so a bad train degrades nothing. There is no window where your organization is running on a half-trained model.

Querying the brain directly

POST /v1/brain/query runs the model and hands back its internals rather than an answer. This is what you build a “what did it attend to” view on.
200 OK
tier and system_used are two different measurements and are easy to confuse. tier describes how much graph the brain has to work with, and its values are seed, sprout, growing, mature and deep, assigned by node count. system_used describes how it thought about this one query, and its values are system1 and system2. A tier of "system1" is not a value the API produces.
The brain routes use snake_case, unlike the rest of the API, which is camelCase. seed_k, focal_display, drift_rate, use_system2, latency_ms, model_params and cosine_in_seed are all correct as written. Do not camelCase them.
The field worth understanding is cosine_in_seed. It tells you whether a focal node was also in the plain cosine top-K head. A focal node with cosine_in_seed: false is one the brain reached by propagating through the graph, not by similarity. That gap is the difference between search and reasoning, and it is the interesting thing to visualize. seed_k controls the cosine seed set size, from 10 to 2000, and drives the reasoning tier. focal_display caps how many focal nodes come back, from 1 to 20.
POST /v1/brain/query and POST /v1/brain/answer read the API key owner’s own content. The X-Exo-Subject selector is not accepted on either route. To reason over a subject’s data, use POST /v1/retrieve with the header instead.

Generating a conditioned answer

POST /v1/brain/answer produces text. question and arm are both required; k defaults to 8 retrieval chunks. With arm set to "brain" the forward pass runs first, and tercile_boundaries decides what happens next: That two-step design exists so you can collect signals across a batch of questions, compute your own cut points from the distribution, then generate with boundaries that mean something for your data rather than arbitrary thresholds.
confidence and drift_rate each take two cut points, [lowMax, midMax], splitting the range into low, middle and high bands. The response carries answer, prompt_used, retrieval_chunk_ids and a brain_signals block with confidence, drift_rate, use_system2, tier, contradictions and appendix_lines.

Keeping a brain fresh

A brain trains on a snapshot. As the graph grows, the snapshot ages, and retrieval tells you:
brain_stale means the brain is still answering, and answering well, but the graph has moved on. It is a signal to schedule a retrain, not an incident. Two other reasons appear on the hybrid path: no_brain when none has been trained, and cold_start when there is not yet enough content to do better. Retrain when:
  • degradationReason has been brain_stale for a while.
  • You imported a large corpus.
  • You erased a subject. DELETE /v1/subjects/{id} marks the brain stale rather than deleting it, because it was trained on every subject. Retraining is what removes that person’s influence from the model. See Forgetting and portability.

When it goes wrong

Next

ExoBrain

What the per-organization model is, when it serves, and when it is stale.

Brain path and hybrid path

What path, degraded and each degradationReason actually mean.