---
title: "POST /api/v1/{context_id}/query"
method: POST
path: "/api/v1/{context_id}/query"
---

# POST /api/v1/{context_id}/query

`POST /api/v1/{context_id}/query`

Phase 7 unified query: four-tier router + fused ranker over the substrate

## Path parameters

- `context_id` string, required

## Request body

- QueryMemoryRequestJson
  - `asOf` string, nullable — Phase 11.5 — historical query timestamp (known time). When set the retrieval path walks the supersession chain to surface the row that was current as-of this instant.
  - `atInstant` string, nullable — Phase 11.5 — system-time query. Prepends `VERSION d'…'` to the underlying `SELECT` so SurrealDB MVCC returns the substrate state at the supplied instant.
  - `include` string[], nullable — Phase 7 — which families of result to include. Defaults to `["facts", "passages"]` (both). Pass either alone to scope the response.
  - `includeDuplicates` boolean, nullable — When `false` (the default), document chunks and memory turns flagged as near-duplicates of an older row are excluded from the fused ranker's recall so the same text does not occupy several ranks. Set `true` to include them (parity with the documents `/query` opt-in).
  - `k` integer — Max hits to return (default 10, max 50).
  - `labels` string[] — Label filter (design §4): `key=value` strings the result rows must **all** carry. Applied after the scope predicate — labels never widen access, only narrow the already-authorised result set. Empty = no label filter.
  - `lens` array[] — A DNF scope selector: an OR of conjunctive clauses. Each clause is an array of scope paths, ALL of which a reader must cover (AND); the outer array is the OR. E.g. [["team/a"],["team/b","clearance/secret"]] means team/a OR (team/b AND clearance/secret). Empty means unscoped (the caller's default region). A bare string is also accepted as a singleton clause.
    - string[]
  - `location` GeoFilterJson — Wire shape for the Phase 6.5 geo filter on `/query`. Mirrors the in-process [`crate::memory::types::GeoFilter`] enum.
    - `near` GeoNearJson
      - `lat` number, double, required
      - `lng` number, double, required
      - `radiusKm` number, double, required
    - `within` string, nullable — Inside a WKT polygon. Mutually exclusive with `near`.
  - `mode` 'hybrid' | 'vector' | 'bm25' | 'graph' — Retrieval mode hint. The default is `Hybrid`, which engages the full fused ranker. The other modes are kept as escape hatches so callers can debug a single signal in isolation.
  - `query` string, required
  - `scopeView` string, nullable — Scope read breadth: `strict` (default) | `merged` | `crossTeam`. Only `strict` is enforced pre-launch; `merged` / `crossTeam` are accepted and behave as `strict` until their region logic ships (design §7.1).
  - `sessionId` string, nullable
  - `source` string, nullable — Phase 7 — free-form source label. Recorded on the trace for audit replay; doesn't affect retrieval today.
  - `validFrom` string, nullable — Phase 11.5 — valid-time (world-time) lower bound. Filters rows whose `valid_from` is ≥ this timestamp.
  - `validUntil` string, nullable — Phase 11.5 — valid-time (world-time) upper bound. Filters rows whose `valid_until` is ≤ this timestamp.

## Response `200`

- QueryMemoryResponseJson
  - `classificationKind` 'direct_lookup' | 'hybrid' | 'full_context', required — What kind of question the query represents. Drives tier selection.
  - `contextHits` MemoryHitJson[] — Synthesis-context rows, **separate from `hits`** and **not** counted against `k`: `hits` is the ranked answer set, these are the extra rows the synthesis layer reads alongside it. Sources: same-section sibling chunks from section expansion, the neighbouring conversation chunks of ranked memory hits from turn expansion, structured attribute/relation rows gathered by the tier-1 seed reads for direct-lookup queries, and (opt-in) entity fact cards summarising a ranked entity's attributes and relationships, and - when the ranked-overflow depth is configured - the fused candidates at ranks `k+1..k+N` that the answer truncation would otherwise discard. Each row's `source` names its family. Empty when no expansion contributed. A UI can render them as an "expanded context" group distinct from the ranked hits.
    - `dateNotes` string, nullable — Day-precise relative-date notes stored beside a memory chunk at write time ("last friday = Friday 2023-05-19"): deterministic resolutions of the chunk text's own relative expressions against its source timestamp. Absent for non-chunk rows and text with no day-precise mentions.
    - `id` string, required
    - `occurredAt` string, nullable — Known-time the hit's fact/turn carries (ISO string), so a caller can date the evidence and resolve relative time in the source text. Absent when the row carries no resolvable date.
    - `resource` union — Typed pointer to the row behind a hit's [`ResultHit::id`], so a caller can resolve the underlying document, entity, or session without parsing raw record-id strings. The `kind` tag names the payload family; entity halves carry the normalised name, which the entity read endpoints re-normalise, so every ref resolves via the corresponding read surface.
      - object — A graph entity: resolve via `GET /entities/{type}/{name}`.
        - `entityType` string, required
        - `kind` 'entity', required
        - `name` string, required
      - object — One attribute of an entity: resolve the chain via `GET /entities/{type}/{name}/history/{key}`.
        - `entityType` string, required
        - `key` string, required
        - `kind` 'attribute', required
        - `name` string, required
      - object — A `relates_to` edge between two entities; either endpoint resolves via `GET /entities/{type}/{name}`.
        - `kind` 'relation', required
        - `label` string, required
        - `objectName` string, required
        - `objectType` string, required
        - `subjectName` string, required
        - `subjectType` string, required
      - object — A dated `action` row; the actor (and the object, when it resolved to a graph entity) resolve via `GET /entities/{type}/{name}`.
        - `actorName` string, required
        - `actorType` string, required
        - `kind` 'action', required
        - `objectName` string, nullable
        - `objectType` string, nullable
      - object — A document passage (`chunk`, `knowledge_section`, or a multimodal chunk): `document_id` resolves via `GET /documents/{id}`; `position` is the row's ordering within the document.
        - `documentId` string, required
        - `kind` 'document', required
        - `position` integer, nullable
      - object — A conversational memory chunk: `session_id` resolves via `GET /sessions/{id}/turns`; `turn_id` / `position` locate the chunk within the session when the row carries the link.
        - `kind` 'session', required
        - `position` integer, nullable
        - `sessionId` string, required
        - `turnId` string, nullable
    - `score` number, float, required
    - `source` 'attribute' | 'entity' | 'action' | 'chunk' | 'memory_chunk' | 'turn' | 'section', required — Coarse-grained result type. Mirrors the row table the hit lives in.
    - `text` string, required
  - `hits` MemoryHitJson[], required
    - `dateNotes` string, nullable — Day-precise relative-date notes stored beside a memory chunk at write time ("last friday = Friday 2023-05-19"): deterministic resolutions of the chunk text's own relative expressions against its source timestamp. Absent for non-chunk rows and text with no day-precise mentions.
    - `id` string, required
    - `occurredAt` string, nullable — Known-time the hit's fact/turn carries (ISO string), so a caller can date the evidence and resolve relative time in the source text. Absent when the row carries no resolvable date.
    - `resource` union — Typed pointer to the row behind a hit's [`ResultHit::id`], so a caller can resolve the underlying document, entity, or session without parsing raw record-id strings. The `kind` tag names the payload family; entity halves carry the normalised name, which the entity read endpoints re-normalise, so every ref resolves via the corresponding read surface.
      - object — A graph entity: resolve via `GET /entities/{type}/{name}`.
        - `entityType` string, required
        - `kind` 'entity', required
        - `name` string, required
      - object — One attribute of an entity: resolve the chain via `GET /entities/{type}/{name}/history/{key}`.
        - `entityType` string, required
        - `key` string, required
        - `kind` 'attribute', required
        - `name` string, required
      - object — A `relates_to` edge between two entities; either endpoint resolves via `GET /entities/{type}/{name}`.
        - `kind` 'relation', required
        - `label` string, required
        - `objectName` string, required
        - `objectType` string, required
        - `subjectName` string, required
        - `subjectType` string, required
      - object — A dated `action` row; the actor (and the object, when it resolved to a graph entity) resolve via `GET /entities/{type}/{name}`.
        - `actorName` string, required
        - `actorType` string, required
        - `kind` 'action', required
        - `objectName` string, nullable
        - `objectType` string, nullable
      - object — A document passage (`chunk`, `knowledge_section`, or a multimodal chunk): `document_id` resolves via `GET /documents/{id}`; `position` is the row's ordering within the document.
        - `documentId` string, required
        - `kind` 'document', required
        - `position` integer, nullable
      - object — A conversational memory chunk: `session_id` resolves via `GET /sessions/{id}/turns`; `turn_id` / `position` locate the chunk within the session when the row carries the link.
        - `kind` 'session', required
        - `position` integer, nullable
        - `sessionId` string, required
        - `turnId` string, nullable
    - `score` number, float, required
    - `source` 'attribute' | 'entity' | 'action' | 'chunk' | 'memory_chunk' | 'turn' | 'section', required — Coarse-grained result type. Mirrors the row table the hit lives in.
    - `text` string, required
  - `queryMs` integer, required
  - `queryWindow` QueryWindowJson — Wire echo of the derived query window: RFC3339 bounds, the resolver's precision label (`day`/`week`/`month`/`season`/`year`), and the phrase it matched.
    - `end` string, required
    - `phrase` string, required
    - `precision` string, required
    - `start` string, required
  - `seedEntities` string[], required
  - `tier` 'direct' | 'cache' | 'hybrid' | 'escalated', required — Which tier resolved the query. Exposed on the response for the CLI's `--tier` flag (Phase 8) and so callers can tell when their query went all the way to tier 4.
  - `trace` QueryTraceJson, required
    - `latencyMs` integer, required
    - `resolutionTier` 'direct' | 'cache' | 'hybrid' | 'escalated', required — Which tier resolved the query. Exposed on the response for the CLI's `--tier` flag (Phase 8) and so callers can tell when their query went all the way to tier 4.
    - `retrievedCount` integer, required
    - `tierReason` string, required
    - `topScores` number[], required
    - `traceId` string, required

## Other responses

- `400` — Invalid request
- `401` — Unauthorized
- `422` — Invalid context id
- `503` — Server too busy: the per-pod in-flight request cap was exceeded. Retry per the `Retry-After` header.

## Changes

- **2026-08-24** `9f1598713067` — 4 warning, 8 info
  - added the new `action` enum value to the `hits/items/source` response property for the response status `200`
  - added the new `escalated` enum value to the `tier` response property for the response status `200`
  - added the new `escalated` enum value to the `trace/resolutionTier` response property for the response status `200`
  - added the new `turn` enum value to the `hits/items/source` response property for the response status `200`
  - …8 more
- **2026-06-16** `52b41ab517b6` — 2 breaking, 4 warning, 2 info
  - the request property `mode` became not nullable
  - the `mode` request property type/format changed from `string, null`/`` to ``/``
  - added the new `cache` enum value to the `trace/resolutionTier` response property for the response status `200`
  - added the new `direct` enum value to the `trace/resolutionTier` response property for the response status `200`
  - …4 more
- **2026-06-16** `6ad06b1fefc4` — 1 breaking
  - the `lens/items/` request property type/format changed from `string`/`` to `array`/``
- …earlier changes not shown

[Full history](https://skmtc.dev/surrealdb/apis/spectron/changes/api/v1/:context_id/query/post.md)

---

[API](https://skmtc.dev/surrealdb/apis/spectron.md) · [All operations](https://skmtc.dev/surrealdb/apis/spectron/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/surrealdb/spectron/revisions/9f1598713067/schema)
