Retrieve

One-round-trip passages + memories + citations retrieval (T386)

The chatbot-facing retrieval primitive: given a natural-language query, returns ranked passages (chunk-level, never subject-scoped) and a separate memories array (subject-isolated when subjectId is given). Response shape is frozen — do not rely on undocumented fields disappearing being a breaking change; they are additive-only.

post/api/retrieve

Request

  • Base URL: http://localhost:38200
  • URL: http://localhost:38200/api/retrieve
  • Auth: one of:
    • HTTP bearer
    • API key in cookie token

Request body

querystring required
workspacestring

Workspace slug. Falls back to X-Workspace header, then the persisted active scope.

projectstring
tagsstring[]
top_kinteger
min_scorenumber
subjectIdstring

Scopes the memories array (not passages) to one end-user identity.

include_memoriesboolean
mmr_lambdanumber

T401: relevance/diversity tradeoff for the MMR pass over candidate passages. 1.0 = pure relevance, 0.0 = pure diversity. Omit for the unchanged v1 default.

max_passages_per_docinteger

T401: caps how many of the returned passages may come from the same document. Omit for the unchanged v1 default (2); set to 1 to force one-passage-per-document diversity.

as_ofstring date-time

T690: point in VALID time (bi-temporal valid_from/ valid_to) to retrieve as of, instead of the current moment. Omit for "now". Mirrors POST /api/search's as_of -- see that param's own description.

token_budgetinteger

T697: ceiling on the response's tokens_total. Omit for no budget (the default; nothing is trimmed). top_k alone does NOT bound payload size -- an unchunked context is returned as one whole-content passage and chunk size is configurable per tenant -- so this is the only field that does.

Enforcement is POST-RANKING and deterministic: the lowest-scored passages are dropped until the total fits, survivors keep their original relative order, and ranking itself is never recomputed. memories and groupMemories are COUNTED toward the total but are NEVER trimmed -- they are subject-scoped personalization, so a budget smaller than they alone occupy drops every passage and still returns tokens_total above the budget rather than truncating them. The number of passages removed is always reported in dropped_count.

latency_budget_msinteger

T700: cross-stage wall-clock budget for the WHOLE request. Omit for unchanged behaviour -- this is strictly opt-in and nothing pays for it by default.

Distinct from the per-stage timeouts (SEARCH_QUERY_REWRITE_TIMEOUT_MS default 6000, SEARCH_RERANKING_TIMEOUT_MS default 8000), which are independent and ADDITIVE -- 14 s of stage timeout alone, before PG/ES/vector run -- so no combination of them can express "answer within a second".

Before each optional heavy stage (query-rewrite, graph-assist, cross-encoder rerank) the elapsed time is compared against the budget; a stage with too little room left is SKIPPED WITHOUT BEING ENTERED (no network call at all) and named in searchMeta.degradedStages[]. A stage that IS admitted has its own timeout clamped down to the remainder. The mandatory legs are never skipped -- a budget shapes which optional quality stages run, it is not a request-abort deadline, so the response is always well-formed.

Response

Passages, memories, group memories, and a retrieval trace id for the query.

traceIdstring nullable

Retrieval-trace row id, or null when RETRIEVAL_TRACE_ENABLED is off (the default).

tokens_totalinteger

T697: sum of every entry's tokens across passages, memories and groupMemories, as actually returned (i.e. after any token_budget trim). Lets a caller size its prompt without re-tokenising the payload.

dropped_countinteger

T697: how many passages a token_budget removed. Always present; 0 when no budget was supplied or nothing had to go. Never counts memories/ groupMemories, which are never dropped.

Changes

No recorded changes to this operation across all 1 revision of this API.