POST /v1/recall
Read a stratified pack — layers, context block, provenance, and diagnostics.
Authorization
bearer PASETO v4 public token (or deployment gate key). Auth-disabled dev instances accept any caller.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X POST "https://example.com/v1/recall" \ -H "Content-Type: application/json" \ -d '{ "scope": "string" }'{ "pack_id": "string", "scope": "string", "context_block": "string", "layers": { "events": [], "facts": [], "beliefs": [], "episodes": [], "understanding": [] }, "provenance": {}}Views
| view | traversal | notes |
|---|---|---|
raw | single scope | full event payloads |
granular (alias local) | single scope | all layers, exact scope only |
holistic (default) | scope + ancestors | requires scope.read.holistic |
descend | scope + descendants | requires scope.read.descend |
lineage | — | supported (was undocumented in v1) |
structured | single scope | facts + beliefs only |
local IS a recall view
view: "local" is accepted and normalizes to granular — verified live. (v1 docs claimed recall
had no local view; it does.)
Behavior notes (v0.9.9)
idempotency_key does not cache on recall
The idempotency_key field is accepted but is a no-op on this endpoint — repeated calls with the
same key return different pack_ids. (The v1 docs' "same pack within 60 s" is not true self-hosted.)
- Filters take exactly one field,
metadata, with attributesobserved_actor,caller,modality,labels,intent(ANDed; values ORed). Unknown attributes →422. No confidence filter. exclude_content: truenulls largecontent/summarystrings.budgets.per_layer_limitshard-caps each layer (events: 0drops the layer).diagnostics=none/summary/full;fullreturns{ policy, time_ms, knapsack_evictions }(phase-namedtime_mskeys, e.g.coordinator_recall,wal_hydrate,recall_total).provenance.trailentries are{ phase, elapsed_ms }(+ acontext_contributorslist).- A body field easy to miss:
prefer_exhaustive(exhaustive candidate sweep). Theorderfield has its own section below. - Streaming:
POST /v1/recall/streamemitsplan → layer(×N) → context_block → provenance → diagnostics → done(thedoneevent carriespack_id). pack_idcan be reused byPOST /v1/answerviause_pack_id(same-scope only; cross-scope →404).
Ordering: relevance vs recency
The order field switches how the events layer is selected and rendered:
order | Selection | Rendering |
|---|---|---|
relevance (default) | ranked retrieval (BM25 + vector + RRF), scored against the query | ranked order |
recency | the scope's newest eligible events by observed_at — a timeline tail | newest-first |
recency replaces ranked retrieval for the events layer with a timeline tail: the newest eligible
events by observed_at, capped by budgets.per_layer_limits.events (else CORTEX_RECENCY_TAIL_EVENTS,
default 100). Eligibility (scope/tenant, filters, temporal) is identical to ranked mode — only
selection changes. It's built for "recent/latest X" questions, where relevance ranking surfaces the
most-repeated items and can drop the newest ones. An unknown order value → 422.
recency applies in holistic view only (verified v0.9.9)
order: "recency" takes effect in holistic view (the recall default). In granular / raw
views it is a no-op: the events layer comes back in ascending observed_at order and a
per_layer_limits.events cap keeps the oldest N, not the newest. Verified live on v0.9.9 —
holistic + recency + { events: 3 } returns the three newest events newest-first, while
granular + recency returns the same set as relevance. Keep the default holistic view for
"latest / most-recent" reads.
/v1/answer forwards order and auto-infers recency for recency-shaped questions — see
POST /v1/answer. The tuning knobs
(CORTEX_RECENCY_TAIL_EVENTS / _ORDER / _INFERENCE) live in
Recall Tuning.
Self-hosted default retrieval
On a default self-hosted instance recall runs BM25 + vector + RRF fusion only. Graph traversal
needs a knowledge graph (CORTEX_ENTITY_GRAPH=1 + enrichment); cross-encoder rerank needs a Cohere key.
See Self-hosting defaults.