POST /v1/retrieve is the flagship call. One request returns evidence, contradictions and a reasoning trace, and tells you which engine served it.
Before you start
- A key with the
readscope. See Authentication. - Content in the graph. A fresh organization returns an empty
sourcesarray. See Ingesting content. - If you serve many end users, a provisioned subject to scope the call to. See One memory per end user.
The shortest call that works
contradictions on a retrieval is an open object in the contract, and the keys above are the ones this route emits today. They are the mining shape, in snake_case, not the canonical Contradiction object. The stable, listable form with id, a, b, status and detectedAt comes from GET /v1/contradictions.Reading the response
sources
Ranked evidence. Each entry names the graph node it came from, so you can drill in withGET /v1/recall/graph/node/{nodeId} or link a citation.
snippet is capped at 280 characters. To get the full stored text of every source, ask for it, which adds a content key alongside the snippet:
expand also works as a body field. sources.content is the only value defined in v1. The default is lean on purpose: full content multiplies the payload for a response most callers only rank and cite.
contradictions
Where this person’s own beliefs conflict.a and b are the two poles: for a reversal, the concept they moved from and to, and for a retraction, the belief before and after. tension is a 0 to 1 salience.
Every contradiction comes back with status: "open", because v1 stores no resolution state. To close one, supersede the side that lost. See Surfacing contradictions in review.
Set includeContradictions: false to skip the detection pass if you do not use them.
cognition
The brain’s reasoning trace:confidence is how strongly it settled, driftRate is how far the activated region has moved from what the brain trained on, focalNodeIds are the nodes it settled on as the centre of the answer, and useSystem2 is true when it escalated from a fast associative lookup to slow deliberate reasoning.
path, degraded and degradationReason
These three exist so a quality drop is never silent.
Read Brain path and hybrid path for the mechanism, and Train and serve an ExoBrain to get off the fallback.
usage
readUnits is the number of sources returned, which is the billable read unit. embedTokens is a documented estimate of the tokens spent embedding your query, at roughly 3.5 characters per token, not a metered figure. brainInference says whether the brain actually ran.
Scoping the call
scope decides whose content is searched.
To retrieve as one of your end users, provision them once and then send the header on every call:
Streaming
Setstream: true and the same result arrives as text/event-stream, so a UI can render evidence while the reasoning is still resolving. Events arrive in a fixed order:
- Every frame is a wrapped object, not a bare value.
cognitionarrives as{"cognition": {...}}, the same nesting assourcesandcontradictions. ReadJSON.parse(data).cognition, notJSON.parse(data). donecarries the whole envelope, not a summary. It repeatssources,contradictionsandcognitionalongsidepath,degraded,latencyMs,traceIdandusage. If you only want the final object, ignore the first three events and parsedone.- There is no
[DONE]sentinel. Thedoneevent is the terminator. The result is computed before the first frame is sent, so the events are ordered rather than incremental.
sources always arrives first, so you can paint the evidence list before the model has finished settling. Wait for done before reading path and degraded.
Choosing between retrieve and search
POST /v1/search is the same hybrid vector plus keyword retrieval with the cognition layer removed. No brain inference, no contradiction detection, no reasoning trace.
topK on search is coerced into 1 to 50 rather than rejected. On retrieve, a topK outside 1 to 50 is a validation error.
When it goes wrong
`cognition` is null and `degraded` is true
`cognition` is null and `degraded` is true
Not an error. The organization has no trained brain, so the hybrid path served the call and reported that honestly in
degradationReason. The sources are real and usable. Train a brain to get the reasoning block. See Train and serve an ExoBrain.403 permission_denied
403 permission_denied
Either the key lacks the
read scope, or you sent an X-Exo-Subject value that has never been provisioned. The subject seam refuses an unknown selector before the handler runs, so this fails fast rather than silently reading the wrong partition. Provision it with PUT /v1/subjects/{id} first. See permission_denied and subject_not_found.422 validation_error
422 validation_error
query must be 1 to 10,000 characters and topK must be 1 to 50. The errors[] array in the problem body names the offending field and a JSON pointer to it. See validation_error.503 service_degraded
503 service_degraded
A dependency, usually the embedder or the connection pool, is temporarily unavailable. Retrieve degrades to 503 rather than 500 by design, which means it is safe to retry with backoff. See
service_degraded.Next
Cognition
The reasoning block, field by field, and when it is null.
Conditioning your own agent
Turn the same graph into a prompt for a model you host.