---
title: "Query Memory"
method: POST
path: "/api/v1/memory/query"
tags: ["memory-v1"]
---

# Query Memory

`POST /api/v1/memory/query`

## Request

- Base URL: `https://core.mnemoverse.com`
- URL: `https://core.mnemoverse.com/api/v1/memory/query`
- Auth: one of:
  - API key in header `X-Api-Key`
  - HTTP bearer

Advanced query: multi-domain, metadata filters, same response shape as /memory/read.

## Request body

- QueryRequestSchema: Advanced query with multi-domain and metadata filtering.
  - `query` string, required: Natural language query.
  - `domains` string[], nullable: Filter by multiple domains (null = all).
  - `metadata_filter` MetadataFilterSchema[], nullable: JSONB metadata filter conditions.
    - `key` string, required: Metadata key to filter on.
    - `op` string: Operator: eq, contains, in.
    - `value` unknown, required
  - `top_k` integer: Max items to return. Cap aligned with ReadRequestSchema (500).
  - `min_relevance` number: Min relevance threshold.
  - `include_associations` boolean: Expand via Hebbian associations.
  - `concepts` string[]: Concept hints.
  - `include_history` boolean: Return superseded revisions alongside live ones; each carries `superseded_by`, and every item carries `supersedes` when it replaced something. History is returned in the domain where each revision is stored: a read scoped to the successor's domain does not include a cross-domain predecessor — use an unscoped read or `GET /memory/atoms/{id}`. History items compete under normal ranking, `min_relevance` and `top_k`/`limit` — `include_history` grants eligibility, not chain completeness; for the chain itself use `GET /memory/atoms/{id}/chain`, which spends a 64-LOOKUP budget per call (resolved revisions AND dangling-pointer misses both count) and sets `truncated` when the budget ran out — so `truncated` means the walk stopped early, not that the chain necessarily holds more than 64 revisions. One exception to the domain rule above: when a fingerprint matches a revision that has been replaced, the live tip is returned alongside it even if that tip lives in another domain — the episodic index is domain-blind, and this makes it two atoms rather than one. No effect until the read-side supersession filter is enabled (nothing is hidden before then, so nothing needs unhiding), and inert for `xroom:<room_id>` domains, whose atoms cannot be superseded at all.
  - `diversity` number: 0 (default) leaves the ranking as it is: the ranked candidates are cut to `top_k`. A value above 0 turns the cut into a maximal marginal relevance selection: items are picked one at a time, each the one that best trades its relevance against its cosine similarity to the items already picked (weight `diversity` on the similarity, `1 - diversity` on relevance), so a near-copy of something already in the answer loses its slot to the next distinct item. 1 means similarity alone decides after the first pick. Applied after outcome feedback and recency have re-ranked, on the ranked pool of up to 200 candidates that cleared `min_relevance`, and only when `top_k` is below 200 (at 200 or more the plain cut applies); pinned fingerprint revisions and the association-reserved slots are unchanged. It changes which items are returned, not their scores.

## Response `200`

Successful Response

- ReadResponseSchema: Response from a memory read query.
  - `items` MemoryItemSchema[], required: List of matching memory items, ordered by relevance.
    - `atom_id` string, uuid, required: Unique identifier of the atom.
    - `content` string, required: Stored text content of the memory.
    - `relevance` number, required: Final score after valence modulation: score * (1 + alpha * v).
    - `similarity` number, required: Raw cosine similarity from pgvector search.
    - `valence` number, required: Outcome polarity [-1, +1]: positive = successful, negative = failed.
    - `importance` number, required: Importance score in [0, 1] from L4 gate.
    - `source` string, required: Retrieval stage that found this item. Production reads return semantic, concept_scoped (found under a concept extracted from the query) and hebbian_retrieval (missed by the direct stages and reached through learned associations, via a concept the query did not name); episodic marks an exact fingerprint match. Other stage names can appear: treat an unknown value as one more stage.
    - `concepts` string[], required: Concepts associated with this atom.
    - `domain` string, required: Domain/namespace of the atom.
    - `metadata` object: Arbitrary key-value metadata.
    - `provenance` ProvenanceSchema: Server-stamped authorship of an atom (CN-001). Returned (as the optional `provenance` object on a read item) only when at least one field is non-null; an atom with no recorded authorship omits the whole object. Stamped from VERIFIED JWT claims at write time — never client-supplied.
      - `principal` string, nullable: The person/principal who wrote it.
      - `agent` string, nullable: Stable agent identifier, if any.
      - `agent_name` string, nullable: Human-readable agent name, if any.
      - `client_env` string, nullable: Calling client environment: cursor·claude·chatgpt·chat·api·unknown.
      - `is_external` boolean: True when the principal is external to the org.
    - `created_at` string, date-time, nullable: UTC creation instant of the atom, ISO-8601 (#404 R1). OMITTED for legacy atoms that predate timestamping — same omission pattern as `provenance`, so their payload shape is unchanged.
    - `supersedes` string[]: Ids of the revisions this item replaced. OMITTED when this item replaced nothing.
    - `superseded_by` string, uuid, nullable: Id of the revision that replaced this one. OMITTED while this item is the live tip. Present means the item is history — reported as a fact of the data regardless of server settings: while the read-side supersession filter is off, ordinary reads still return replaced revisions and this field is how you tell. Once the filter is on, history reaches a read only via `include_history`. The id names the IMMEDIATE successor as of the moment of replacement and carries no FK — if that successor was later destroyed, a GET on it is a documented 404, and `GET /memory/atoms/{id}/chain` reports the break rather than failing.
  - `episodic_hit` boolean, required: True if an exact episodic (fingerprint) match was found.
  - `query_concepts` string[], required: Concepts extracted or used for the query.
  - `expanded_concepts` string[], required: Concepts expanded via Hebbian associations.
  - `search_time_ms` number, required: Search duration in milliseconds.
  - `timings` object, nullable: Per-phase wall times in ms + call counters (TRACING_SPEC §2). Present only when the request set include_timings=true; an absent phase key means the phase was skipped.

## Other responses

- `400`: Validation error
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `422`: Validation Error
- `429`: Rate limited
- `500`: Internal server error
- `503`: Service unavailable

---

[API](https://skmtc.dev/mnemoverse/apis/mnemoverse-core.md) · [All operations](https://skmtc.dev/mnemoverse/apis/mnemoverse-core/llms.txt) · [OpenAPI document](https://skmtc.dev/mnemoverse/apis/mnemoverse-core/revisions/1f5e0048f017?raw)
