> ## Documentation Index
> Fetch the complete documentation index at: https://cortex-e852fafe-t3code-rewrite-docs-declutter.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Query

> How HydraDB retrieves the right context for each query: Knowledge, Memories, and the context graph, all behind a single /query endpoint.

`POST /query` retrieves [Knowledge](/essentials/v2/knowledge) (documents and app sources), [Memories](/essentials/v2/memories) (user preferences, conversation history, inferred content), or both. The response contains matching passages (**chunks**) and their source details, which your application can put in a model prompt. Search combines meaning, keywords, and relationships between the content. It does not generate the answer.

For the full request and response schema, see [Query: API Reference](/api-reference/v2/endpoint/query-overview).

***

## 1. Use-case recipes

Pick the row that matches your goal and use the parameters as a starting point:

| I want to… | `type` | `query_by` | `mode` | Notes |
| - | - | - | - | - |
| Answer questions from documents | `"knowledge"` | `"hybrid"` | `"thinking"` | Keep `graph_context` on (the default) to include relationships between people, topics, or services mentioned in the content |
| Exact keyword match | `"knowledge"` | `"text"` | Not used | Optionally set `operator: "and"` or `"or"` to control BM25 term matching |
| Personalized response | `"memory"` | `"hybrid"` | `"thinking"` | |
| Personalized + grounded | `"all"` | `"hybrid"` | `"thinking"` | One call merges both stores from the same scope. If they live in different collections, list both in `collections` |
| Query over apps | `"knowledge"` | `"hybrid"` | `"thinking"` | Leave `query_apps` on (the default) to use the app search (IDs, people, reply threads, and linked records) while still querying the full selected knowledge scope |

***

## 2. Parameter reference

When to send `database` and `collection`: [Multi-tenant](/essentials/v2/multi-tenant#2-when-to-use-each). The older names `tenant_id` and `sub_tenant_id` still work as deprecated aliases.

### Retrieval

| Parameter | Type / values | Purpose |
| - | - | - |
| `type` | `"knowledge"`, `"memory"`, or `"all"` | Which store to query. `"all"` reads both stores from the same scope and ranks the results together. Default: `"knowledge"`. |
| `query_by` | `"hybrid"` or `"text"` | `"hybrid"` combines matching by meaning with BM25, the keyword-ranking method. `"text"` is BM25 only. Default: `"hybrid"`. |
| `operator` | `"or"`, `"and"`, or `"phrase"` | How BM25 matches query terms, with `query_by: "text"` only. `"and"` or `"phrase"` with any other `query_by` returns `400` ("operator is only valid with query\_by=text"). Default: `"or"`. |
| `alpha` | float `0.0` to `1.0`, or `"auto"` | Weights semantic against BM25 scores in `query_by: "hybrid"` (`1.0` is pure semantic). `"auto"` also resolves to `0.8`. Default: `0.8`. |
| `mode` | `"fast"`, `"thinking"`, or `"auto"` | How much work the query does. `"auto"` scores the query and routes it to `"fast"` or `"thinking"`, choosing `"thinking"` when unsure. Default: `"auto"`. |

### Scope

| Parameter | Type / values | Purpose |
| - | - | - |
| `collections` | `string[]` or `{ [collection]: positive number (max one decimal place) }` | Preferred query-time scope selector. Use a single-item list for one user/workspace, a longer list to search several collections with equal normalized weights, or an object to provide relative ranking weights with at most one decimal place. HydraDB runs the whole query in each collection and merges the results. Every listed collection must exist. Maximum 100 collections. |
| `collection` | string | Single-scope query selector; also used at ingest. Send one collection ID to scope the query to it. If you send neither field, the query reads the database's default collection. |

### Graph

| Parameter | Type / values | Purpose |
| - | - | - |
| `graph_context` | boolean | When `true` (default), includes the entity/relation graph slice in the response. Pair with `mode: "thinking"` for following several connected relationships. See [Context Graphs](/essentials/v2/context-graphs). Set to `false` to drop it when you only need ranked chunks; `false` takes effect only in fast mode (explicit, or `auto` routed to fast), since thinking always includes the graph slice. Default: `true`. |
| `query_forceful_relations` | boolean | Whether to fetch author-declared related sources (see [`relations` on ingest](/api-reference/v2/endpoint/ingest-context)) into `additional_context`. **Only takes effect in** `mode: "thinking"` (explicit, or `auto` routed to thinking)**.** Default: `true`. |

### Shaping results

| Parameter | Type / values | Purpose |
| - | - | - |
| `max_results` | integer | Maximum chunks to return. Default `10`; maximum `250`. Start with `10`, reduce for tight context windows, increase only when you rerank or summarize downstream. |
| `recency_bias` | float `0.0` to `1.0` | Boost for newer content. Omitted, it applies a mild `0.4` tilt; send `0` to turn it off. |
| `query_apps` | boolean | Enables the app-aware retrieval lane alongside normal retrieval (reconstructed threads, parent/child traversal, exact ID/actor lookups). This improves app-source query but does not restrict the query to only app sources; HydraDB still queries the full selected knowledge scope. Knowledge only. Send `false` to turn it off. See [App Sources](/essentials/v2/app-sources). Default: `true`. |
| `additional_context` | string | Request-time hint to guide retrieval (e.g., "user is on the billing page"). This is different from the response `additional_context`, which carries forceful-relation results. Default: `null`. |
| `metadata_filters` | object | Deterministic narrowing before ranking. See [Metadata](/essentials/v2/metadata). Default: `null`. |

### Access control

| Parameter | Type / values | Purpose |
| - | - | - |
| `acl` | `string[]` | Query on behalf of an identity: results are restricted to documents that identity may retrieve. Send the caller's email (`["grace@acme.com"]`); `__public__` and the caller's `domain:` principal are added automatically. Omitted, empty, or `["*"]` disables filtering entirely, which is the default. See [Access Control](/essentials/v2/access-control). Default: `null`. |

***

## 3. Tuning heuristics

Most of the time the defaults are right. When they aren't, here's where to start:

* `mode`: Pick `"fast"` or `"thinking"` explicitly when you need predictable retrieval behavior instead of automatic routing.
* `alpha`: Start at `0.8`. Lower toward `0.3` to `0.5` when the query contains literal tokens (error codes, SKUs, product names). Raise toward `0.9` for conceptual questions.
* `max_results`: Start at `10`. Drop to `5` for tight context windows; raise to `20` if you rerank downstream.
* `additional_context`: Use it when the query alone is ambiguous. Keep it short and factual.
* `graph_context`: Keep it on (the default) when answers depend on entity relationships (multi-hop questions, "how does X relate to Y"). Pair with `mode: "thinking"`, because in `"fast"` mode the graph slice is shallow.
* `query_apps`: Leave it on for app data (Slack, Gmail, Jira, and so on), and pair it with `mode: "thinking"` so relations and threads expand.

***

## 4. Minimal working example

A personalized-answer flow takes a single call: `POST /query` with `type: "all"` returns merged knowledge and per-user memory in one ranked result set. Both stores are read from the same scope, so if shared knowledge lives in its own collection, list it next to the user's in `collections`.

### Setup

<CodeGroup>
  ```bash cURL theme={"dark"}
  # Set your key once. Every request below sends it.
  export HYDRA_DB_API_KEY="your_api_key"
  # All requests: -H "Authorization: Bearer $HYDRA_DB_API_KEY" -H "API-Version: 2"
  ```

  ```typescript TypeScript SDK theme={"dark"}
  import { HydraDBClient } from "@hydradb/sdk";

  const client = new HydraDBClient({
    token: process.env.HYDRA_DB_API_KEY,
  });
  ```

  ```python Python SDK theme={"dark"}
  import os
  from hydra_db import HydraDB

  client = HydraDB(token=os.environ["HYDRA_DB_API_KEY"])
  ```
</CodeGroup>

### One call: Knowledge and Memories together

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl -X POST 'https://api.hydradb.com/query' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "API-Version: 2" \
    -H "Content-Type: application/json" \
    -d '{
      "database": "acme_corp",
      "collection": "user_john_123",
      "query": "How do I reset my password?",
      "type": "all",
      "query_by": "hybrid",
      "mode": "thinking",
      "max_results": 8,
      "graph_context": true
    }'
  ```

  ```typescript TypeScript SDK theme={"dark"}
  const result = await client.query({
    database: "acme_corp",
    collection: "user_john_123",
    query: "How do I reset my password?",
    type: "all",
    queryBy: "hybrid",
    mode: "thinking",
    maxResults: 8,
    graphContext: true,
  });
  ```

  ```python Python SDK theme={"dark"}
  result = client.query(
      database="acme_corp",
      collection="user_john_123",
      query="How do I reset my password?",
      type="all",
      query_by="hybrid",
      mode="thinking",
      max_results=8,
      graph_context=True,
  )
  ```
</CodeGroup>

### Merge into the LLM prompt

The response is a single `RetrievalResult` containing `chunks[]`, `sources[]`, and, when applicable, `graph_context` and `additional_context`. Chunks from Knowledge and Memories are already interleaved and ranked by relevance, so no manual merging is required. Pass the result through the helper in [How to Use API Results](/essentials/v2/api-results) to turn it into a context string for your prompt:

```typescript theme={"dark"}
const context = buildContextString(result);

const completion = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [
    {
      role: "system",
      content: "Answer using only the provided context. Match the user's preferred style.",
    },
    {
      role: "user",
      content: `${context}\n\nQuestion: How do I reset my password?`,
    },
  ],
});
```

If you need to query several users, teams, or workspaces at once, pass `collections`. A list gives every scope equal normalized weight; an object applies relative ranking weights with at most one decimal place before the final merged ranking. When `max_results` is set, it caps the final merged response across all selected collections:

```json theme={"dark"}
{
  "database": "acme_corp",
  "collections": {
    "workspace_42": 2,
    "user_john_123": 1
  },
  "query": "What context matters for this renewal?",
  "type": "all"
}
```

If you need to keep Knowledge and Memories formatted differently in the prompt, call `/query` twice in parallel with `type: "knowledge"` and `type: "memory"`, then merge client-side.

### Production checklist

* **Set per-call timeouts:** Generous for `thinking` (3 to 5 s), tight for `fast` (500 ms or less). For `mode: "auto"`, size the timeout for the `thinking` case, since it can resolve to either pipeline and defaults toward `thinking` when the routing signal is inconclusive.
* **Pass** `additional_context` with known session state (page, feature, role). It sharpens retrieval without extra calls.

***

## 5. Common mistakes

| Symptom | Cause | Fix |
| - | - | - |
| Empty `query_paths` / `chunk_relations` | `graph_context` set to `false`, or no relations exist for the result set | Leave `graph_context` on (the default). Empty arrays are normal when there's nothing to return. See [Context Graphs](/essentials/v2/context-graphs). |
| Recent uploads don't appear in results | Indexing not finished | Poll `GET /context/status?ids=...&database=...`. Chunks are invisible until processing reaches at least `graph_creation`. |
| `metadata_filters` doesn't narrow results | Filter key is in the wrong namespace, the value doesn't match exactly, or the hot top-level field was not declared in the database schema | Top-level keys match `metadata`; free-form per-document fields must be nested under `additional_metadata`. Declare hot filter keys in `database_metadata_schema` before production ingest. |
| Memories missing from a `type: "knowledge"` query | Wrong store selected | Use `type: "memory"` or `type: "all"`. |
| Recency doesn't seem to matter | `recency_bias` was sent as `0`, or the default `0.4` tilt is too mild | Raise it toward `1.0`. |
| `operator: "phrase"` returns `400` | `query_by` not set to `"text"` | `"and"` and `"phrase"` only apply to BM25 text query: switch `query_by` to `"text"`. |
| `query_forceful_relations` ignored | Request uses `mode: "fast"` (or `auto` routed to fast) | Forceful-relation context is fetched only in thinking mode. Set `mode: "thinking"`. |
| `graph_context: false` ignored | Request runs in thinking mode (`mode: "thinking"`, or `auto` routed to thinking) | Thinking always includes the graph slice; `false` takes effect only in fast mode. Set `mode: "fast"` to drop it. |
| Expected a deterministic `fast`/`thinking` pipeline, got auto-routed instead | `mode` was omitted | Omitting `mode` defaults to `"auto"`: set `mode` explicitly to `"fast"` or `"thinking"` if you don't want automatic routing. |

***

## 6. Advanced patterns

**Hybrid + text in two parallel calls.** When a query mixes a literal token (error code, SKU, function name) with natural-language intent, run `query_by: "hybrid"` and `query_by: "text"` in parallel, dedupe by chunk ID, and treat text hits as a "must include" floor.

**Recall-then-rerank.** Ask for more chunks than you actually need (`max_results: 20`) and apply your own reranker (recency windows, compliance filters, business rules) before picking the final top-k for the prompt.

**Cache the prompt context:** Include the database, collection scopes, caller ACL, and all query parameters in the cache key. Expire cached results when content or permissions change.

***

## Related

* [Knowledge](/essentials/v2/knowledge): shared document context
* [Memories](/essentials/v2/memories): user-scoped dynamic context
* [Metadata](/essentials/v2/metadata): designing filterable fields
* [Context Graphs](/essentials/v2/context-graphs): how graph traversal enriches retrieval
* [How to Use API Results](/essentials/v2/api-results): turning `RetrievalResult` into an LLM prompt
* [Query: API Reference](/api-reference/v2/endpoint/query): full parameter and response schema


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.