CortexDB Docs
API Reference

POST /v1/recall

Read a stratified pack — layers, context block, provenance, and diagnostics.

POST
/v1/recall
AuthorizationBearer <token>

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

viewtraversalnotes
rawsingle scopefull event payloads
granular (alias local)single scopeall layers, exact scope only
holistic (default)scope + ancestorsrequires scope.read.holistic
descendscope + descendantsrequires scope.read.descend
lineagesupported (was undocumented in v1)
structuredsingle scopefacts + 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 attributes observed_actor, caller, modality, labels, intent (ANDed; values ORed). Unknown attributes → 422. No confidence filter.
  • exclude_content: true nulls large content/summary strings.
  • budgets.per_layer_limits hard-caps each layer (events: 0 drops the layer).
  • diagnostics = none / summary / full; full returns { policy, time_ms, knapsack_evictions } (phase-named time_ms keys, e.g. coordinator_recall, wal_hydrate, recall_total).
  • provenance.trail entries are { phase, elapsed_ms } (+ a context_contributors list).
  • A body field easy to miss: prefer_exhaustive (exhaustive candidate sweep). The order field has its own section below.
  • Streaming: POST /v1/recall/stream emits plan → layer(×N) → context_block → provenance → diagnostics → done (the done event carries pack_id).
  • pack_id can be reused by POST /v1/answer via use_pack_id (same-scope only; cross-scope → 404).

Ordering: relevance vs recency

The order field switches how the events layer is selected and rendered:

orderSelectionRendering
relevance (default)ranked retrieval (BM25 + vector + RRF), scored against the queryranked order
recencythe scope's newest eligible events by observed_at — a timeline tailnewest-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.

On this page