---
title: "Recall"
method: POST
path: "/api/v1/memory/recall"
tags: ["memory"]
---

# Recall

`POST /api/v1/memory/recall`

## Request

- Base URL: `https://memory.kagura-ai.com` (the document declares no server; this is the origin it was published from)
- URL: `https://memory.kagura-ai.com/api/v1/memory/recall`
- Auth: none declared

Search memories with Hybrid Search.

Issue #1 specification:
- Semantic Search (OpenAI Embedding) 60%
- BM25/Full-text (Qdrant) 40%
- Cohere Reranking (optional)

``filters.context_id`` names the context to search. It is resolved for the
caller first — workspace membership, suspension, the context whitelist,
private-context ownership and the API key's workspace scope — with the
uniform ``404`` on any deny, the gate every other UUID-addressed read
(``/memory/list``, ``/memory/stats``, graph, the MCP ``recall`` tool)
applies. The search then runs against the context's own workspace.

Request:
    {
        "query": "認証エラーの解決方法",
        "k": 5,
        "use_rerank": false,
        "filters": {
            "context_id": "<context-uuid>",
            "scope": "persistent",
            "type": "code"
        }
    }

Example:
    POST /api/v1/memory/recall
    Authorization: Bearer <session_token>

## Headers

- `authorization` string, nullable

## Request body

- RecallRequest: Request schema for recall() API (Hybrid Search). Example: { "query": "認証エラーの解決方法", "k": 5, "use_rerank": false, "filters": { "context_id": "my-context", "scope": "persistent", "type": "code" } }
  - `query` string, required: 検索クエリ
  - `k` integer: 返却結果数
  - `use_rerank` boolean, nullable: Reranking (Voyage/Cohere BYOK, or self_hosted). Omit to follow the context's search config; set false to force off.
  - `filters` object, nullable: オプショナルフィルタ
  - `search_mode` string, nullable: Search mode: hybrid (default when omitted), semantic (vector only), keyword (BM25 only). Omit to allow query-intent routing on contexts with routing_mode='active' (#1212).
  - `include_explore_hints` boolean: Include up to 3 explore_hints in response suggesting good seeds for explore()
  - `include_superseded` boolean: Include memories shadowed by a supersedes edge (annotated with superseded_by) and return folded older versions as their own rows
  - `full` integer, nullable: How many of the top results carry content, each cut at 1,500 characters (content_truncated / content_next_offset when cut). Omit or 0 for summaries only.

## Response `200`

Successful Response

- RecallResponse: Response schema for recall() API. Issue #104: Added related_tags to help LLMs understand tag context. Issue #216: Added explore_hints for graph discovery bridging. Issue #1047: Added confidence (relevance/staleness signal) — additive.
  - `results` MemoryResponse[], required
    - `memory_id` unknown, required
    - `summary` unknown, required
    - `context_summary` unknown, required
    - `type` unknown, required
    - `importance` unknown, required
    - `scope` unknown, required
    - `created_at` unknown, required
    - `updated_at` unknown
    - `client` unknown, required
    - `tags` unknown, required
    - `context` unknown, required
    - `score` unknown
    - `source_uri` unknown
    - `source_type` unknown
    - `superseded_by` unknown
    - `contradicts` unknown
    - `supersede_candidate` unknown
    - `folded` unknown
    - `version` unknown
    - `content` unknown
    - `content_truncated` unknown
    - `content_next_offset` unknown
    - `spans` unknown
  - `related_tags` RelatedTagItem[]
    - `tag` unknown, required
    - `count` unknown, required
    - `sample_summary` unknown
    - `last_used_at` unknown
  - `explore_hints` ExploreHint[], nullable
    - `memory_id` string, uuid, required
    - `reason` 'top_result' | 'high_centrality' | 'unexplored_neighbor', required
  - `tag_suggestions` object, nullable: Tags present in this context that resemble the ones filtered on, keyed by the requested tag. Present only when a tag filter matched no memories. Advisory: the filter itself was not widened.
  - `confidence` RecallConfidence: Issue #1047/#1052: a signal distinguishing "relevant results found" from "likely nothing relevant" (so an agent can stop probing / go external instead of trusting a weak hit), WITHOUT changing ranking. ``level`` is driven by **absolute semantic match strength**, made robust to embedding-model scale via ``prominence`` (#1052): - ``top_score`` — the RAW semantic cosine of the best hit (absolute match strength in [0, 1]). High ⇒ something closely matches the query. - ``prominence`` — ``(top_score - mean_background_cosine) / mean_background_cosine`` over the candidate pool. A *ratio*, so it is invariant to the overall cosine scale a given embedding model produces (text-embedding-3-small and qwen3-embedding sit at different absolute cosines, but a real match is proportionally far above its background in both). ``level`` thresholds on this; a near-duplicate ``top_score`` floors ``level`` to at least ``moderate``. How an agent should use it (it is a TRIAGE hint, not a correctness verdict): - ``none`` / ``low`` → likely nothing relevant; prefer an external source over forcing an answer out of these results. This is the high-value signal and is reliable without a reranker. - ``high`` / ``moderate`` → relevant memory is likely present; READ the returned summaries and judge from their content. ``level`` measures *topical match strength*, so a closely-related "near-miss" (an adjacent topic) can also read ``high`` — it does NOT guarantee the exact fact you asked for is stored. The returned content is the source of truth; ``level`` only says whether it is worth reading. Distinguishing near-miss from an exact match needs a cross-encoder (pass ``use_rerank=true``); plain bi-encoder cosine cannot. Why this supersedes the original #1047 z-score approach: that bucketed on ``relative_margin`` (background std-devs), but max-normalization in the hybrid merge erases absolute strength, and dividing by a flat off-topic tail's tiny std *inflated* the margin — so irrelevant queries scored ``high`` (benchmarked). ``relative_margin`` is retained for transparency but is NO LONGER the basis for ``level``; note it reads high even for off-topic queries. ``prominence`` / ``relative_margin`` are None for keyword-only searches (no semantic cosines) and single-candidate pools; there ``level`` falls back to the original z-score separation heuristic.
    - `level` 'high' | 'moderate' | 'low' | 'none', required
    - `top_score` number, nullable: Raw semantic cosine of the best hit (absolute match strength, 0-1). On keyword-only searches this is the normalized hybrid top instead.
    - `prominence` number, nullable: (top_score - mean_background_cosine) / mean_background_cosine — a model-scale-invariant match prominence and the primary basis for level. None when <2 candidates or keyword-only.
    - `relative_margin` number, nullable: Separation of the top hit from the candidate-pool background, in background std-devs. Informational only — it inflates on flat off-topic tails and is not used for level. None when <2 candidates.
    - `result_count` integer, required
    - `rationale` string, required
  - `degraded` boolean, nullable: True when this result set was produced without the semantic search arm. Absent when the search ran normally.
  - `degraded_reason` string, nullable: Why the search degraded: 'embedding_unavailable' (the embedding provider failed) or 'vector_search_unavailable' (the vector store failed). Absent when the search ran normally.
  - `selector` SelectorReport: #2144: what the recall LLM selector did to this page. ``applied: true`` carries ``model``, ``kept`` / ``dropped`` (results left and removed) and ``dropped_memory_ids`` (at most 20, page order); ``applied: false`` carries only ``reason`` and the page is the unselected one. Serialized without the unset keys.
    - `applied` boolean, required
    - `model` string, nullable
    - `kept` integer, nullable
    - `dropped` integer, nullable
    - `dropped_memory_ids` string[], nullable
    - `reason` 'timeout' | 'provider_error' | 'invalid_answer' | 'daily_cap' | 'too_large' | 'no_provider' | 'counter_unavailable' | 'inactive', nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kagura-ai/apis/kagura-memory-cloud.md) · [All operations](https://skmtc.dev/kagura-ai/apis/kagura-memory-cloud/llms.txt) · [OpenAPI document](https://skmtc.dev/kagura-ai/apis/kagura-memory-cloud/revisions/aa9df1a21db9?raw)
