result = client.query(
database="acme_corp",
collection="user_alex",
query="What is our refund policy, and how should I explain it to this user?",
# What to query: "knowledge", "memory", or "all".
type="all",
# How to match: "hybrid" (default) or "text" (BM25).
query_by="hybrid",
# "thinking" improves quality; use "fast" for lowest latency.
mode="thinking",
# Ranking and response controls.
max_results=10,
alpha="auto",
recency_bias=0.2,
graph_context=True,
# Pull author-declared related sources into additional_context.
# Only applies when mode="thinking".
query_forceful_relations=True,
# Top-level keys match metadata; additional_metadata is per-source.
metadata_filters={
"department": "support",
"additional_metadata": {
"source": "policy",
},
},
# Short factual hint; not a hard filter.
additional_context="User is asking from the billing help center.",
)
const result = await client.query({
database: "acme_corp",
collection: "user_alex",
query: "What is our refund policy, and how should I explain it to this user?",
// What to query: "knowledge", "memory", or "all".
type: "all",
// How to match: "hybrid" (default) or "text" (BM25).
queryBy: "hybrid",
// "thinking" improves quality; use "fast" for lowest latency.
mode: "thinking",
// Ranking and response controls.
maxResults: 10,
alpha: "auto",
recencyBias: 0.2,
graphContext: true,
// Pull author-declared related sources into additional_context.
// Only applies when mode: "thinking".
queryForcefulRelations: true,
// Top-level keys match metadata; additional_metadata is per-source.
metadataFilters: {
department: "support",
additional_metadata: {
source: "policy",
},
},
// Short factual hint; not a hard filter.
additionalContext: "User is asking from the billing help center.",
});
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "user_alex",
"query": "What is our refund policy, and how should I explain it to this user?",
"type": "all",
"query_by": "hybrid",
"mode": "thinking",
"max_results": 10,
"alpha": "auto",
"recency_bias": 0.2,
"graph_context": true,
"query_forceful_relations": true,
"metadata_filters": {
"department": "support",
"additional_metadata": {
"source": "policy"
}
},
"additional_context": "User is asking from the billing help center."
}'
{
"success": true,
"data": {
"chunks": [
{
"chunk_uuid": "policy_main_chunk_3",
"id": "policy_main",
"chunk_content": "Refunds are issued within 30 days...",
"source_type": "pdf",
"source_title": "Compliance Policy",
"source_upload_time": "2026-05-12T08:14:00Z",
"source_last_updated_time": "2026-05-12T08:14:00Z",
"layout": "{\"offsets\":{\"document_level_start_index\":1024},\"page\":3}",
"relevancy_score": 0.91,
"extra_context_ids": ["pref-tone"],
"metadata": { "department": "legal" },
"additional_metadata": { "author": "Legal Team" }
}
],
"sources": [
{
"id": "policy_main",
"title": "Compliance Policy",
"type": "pdf",
"description": "",
"url": "",
"timestamp": "2026-05-12T08:14:00Z",
"metadata": { "department": "legal" },
"additional_metadata": { "author": "Legal Team" },
"app_kind": null,
"app_provider": null,
"app_external_id": null
}
],
"graph_context": {
"query_paths": [
{
"triplets": [
{
"source": {
"name": "Compliance Policy",
"type": "DOCUMENT",
"namespace": "default",
"entity_id": "entity_compliance_policy",
"identifier": "https://api.hydradb.com/docs/compliance_policy"
},
"relation": {
"canonical_predicate": "GOVERNS",
"raw_predicate": "governs and regulates",
"context": "The compliance policy governs the refund processing timeline of 30 days.",
"confidence": 0.95,
"temporal_details": null,
"timestamp": 1778573640.0,
"relationship_id": "rel_governs_refunds",
"chunk_id": "policy_main_chunk_3",
"source_entity_id": "entity_compliance_policy",
"target_entity_id": "entity_refund_processing"
},
"target": {
"name": "Refund Processing",
"type": "PROCESS",
"namespace": "default",
"entity_id": "entity_refund_processing",
"identifier": null
}
}
],
"relevancy_score": 0.89,
"combined_context": "The Compliance Policy governs the Refund Processing, which regulates refunds.",
"group_id": null,
"source_chunk_ids": ["policy_main_chunk_3"]
}
],
"chunk_relations": [
{
"triplets": [
{
"source": {
"name": "Refund Processing",
"type": "PROCESS",
"namespace": "default",
"entity_id": "entity_refund_processing",
"identifier": null
},
"relation": {
"canonical_predicate": "MANAGED_BY",
"raw_predicate": "is managed by",
"context": "Refund processing is managed by the Finance Department.",
"confidence": 0.9,
"temporal_details": "Q2 2026 onwards",
"timestamp": 1778573640.0,
"relationship_id": "rel_managed_by_finance",
"chunk_id": "policy_main_chunk_3",
"source_entity_id": "entity_refund_processing",
"target_entity_id": "entity_finance_dept"
},
"target": {
"name": "Finance Department",
"type": "ORGANIZATION",
"namespace": "default",
"entity_id": "entity_finance_dept",
"identifier": "[email protected]"
}
}
],
"relevancy_score": 0.82,
"combined_context": "Refund Processing is managed by the Finance Department.",
"group_id": "p_0",
"source_chunk_ids": ["policy_main_chunk_3"]
}
],
"chunk_id_to_group_ids": {
"policy_main_chunk_3": ["p_0"]
}
},
"additional_context": {
"pref-tone": {
"chunk_uuid": "pref-tone",
"id": "mem_user_alex_tone",
"chunk_content": "Prefers concise answers.",
"source_type": "memory",
"source_title": "User preferences",
"source_upload_time": "2026-05-12T08:14:00Z",
"source_last_updated_time": "2026-05-12T08:14:00Z"
}
}
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": true,
"data": {
"chunks": [],
"sources": [],
"graph_context": {
"query_paths": [],
"chunk_relations": [],
"chunk_id_to_group_ids": {}
},
"additional_context": {}
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": false,
"data": null,
"error": {
"code": "INVALID_PARAMETERS",
"message": "query must not be empty"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 4.8
}
}
Query
Unified retrieval over knowledge, memories, or both.
result = client.query(
database="acme_corp",
collection="user_alex",
query="What is our refund policy, and how should I explain it to this user?",
# What to query: "knowledge", "memory", or "all".
type="all",
# How to match: "hybrid" (default) or "text" (BM25).
query_by="hybrid",
# "thinking" improves quality; use "fast" for lowest latency.
mode="thinking",
# Ranking and response controls.
max_results=10,
alpha="auto",
recency_bias=0.2,
graph_context=True,
# Pull author-declared related sources into additional_context.
# Only applies when mode="thinking".
query_forceful_relations=True,
# Top-level keys match metadata; additional_metadata is per-source.
metadata_filters={
"department": "support",
"additional_metadata": {
"source": "policy",
},
},
# Short factual hint; not a hard filter.
additional_context="User is asking from the billing help center.",
)
const result = await client.query({
database: "acme_corp",
collection: "user_alex",
query: "What is our refund policy, and how should I explain it to this user?",
// What to query: "knowledge", "memory", or "all".
type: "all",
// How to match: "hybrid" (default) or "text" (BM25).
queryBy: "hybrid",
// "thinking" improves quality; use "fast" for lowest latency.
mode: "thinking",
// Ranking and response controls.
maxResults: 10,
alpha: "auto",
recencyBias: 0.2,
graphContext: true,
// Pull author-declared related sources into additional_context.
// Only applies when mode: "thinking".
queryForcefulRelations: true,
// Top-level keys match metadata; additional_metadata is per-source.
metadataFilters: {
department: "support",
additional_metadata: {
source: "policy",
},
},
// Short factual hint; not a hard filter.
additionalContext: "User is asking from the billing help center.",
});
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "user_alex",
"query": "What is our refund policy, and how should I explain it to this user?",
"type": "all",
"query_by": "hybrid",
"mode": "thinking",
"max_results": 10,
"alpha": "auto",
"recency_bias": 0.2,
"graph_context": true,
"query_forceful_relations": true,
"metadata_filters": {
"department": "support",
"additional_metadata": {
"source": "policy"
}
},
"additional_context": "User is asking from the billing help center."
}'
{
"success": true,
"data": {
"chunks": [
{
"chunk_uuid": "policy_main_chunk_3",
"id": "policy_main",
"chunk_content": "Refunds are issued within 30 days...",
"source_type": "pdf",
"source_title": "Compliance Policy",
"source_upload_time": "2026-05-12T08:14:00Z",
"source_last_updated_time": "2026-05-12T08:14:00Z",
"layout": "{\"offsets\":{\"document_level_start_index\":1024},\"page\":3}",
"relevancy_score": 0.91,
"extra_context_ids": ["pref-tone"],
"metadata": { "department": "legal" },
"additional_metadata": { "author": "Legal Team" }
}
],
"sources": [
{
"id": "policy_main",
"title": "Compliance Policy",
"type": "pdf",
"description": "",
"url": "",
"timestamp": "2026-05-12T08:14:00Z",
"metadata": { "department": "legal" },
"additional_metadata": { "author": "Legal Team" },
"app_kind": null,
"app_provider": null,
"app_external_id": null
}
],
"graph_context": {
"query_paths": [
{
"triplets": [
{
"source": {
"name": "Compliance Policy",
"type": "DOCUMENT",
"namespace": "default",
"entity_id": "entity_compliance_policy",
"identifier": "https://api.hydradb.com/docs/compliance_policy"
},
"relation": {
"canonical_predicate": "GOVERNS",
"raw_predicate": "governs and regulates",
"context": "The compliance policy governs the refund processing timeline of 30 days.",
"confidence": 0.95,
"temporal_details": null,
"timestamp": 1778573640.0,
"relationship_id": "rel_governs_refunds",
"chunk_id": "policy_main_chunk_3",
"source_entity_id": "entity_compliance_policy",
"target_entity_id": "entity_refund_processing"
},
"target": {
"name": "Refund Processing",
"type": "PROCESS",
"namespace": "default",
"entity_id": "entity_refund_processing",
"identifier": null
}
}
],
"relevancy_score": 0.89,
"combined_context": "The Compliance Policy governs the Refund Processing, which regulates refunds.",
"group_id": null,
"source_chunk_ids": ["policy_main_chunk_3"]
}
],
"chunk_relations": [
{
"triplets": [
{
"source": {
"name": "Refund Processing",
"type": "PROCESS",
"namespace": "default",
"entity_id": "entity_refund_processing",
"identifier": null
},
"relation": {
"canonical_predicate": "MANAGED_BY",
"raw_predicate": "is managed by",
"context": "Refund processing is managed by the Finance Department.",
"confidence": 0.9,
"temporal_details": "Q2 2026 onwards",
"timestamp": 1778573640.0,
"relationship_id": "rel_managed_by_finance",
"chunk_id": "policy_main_chunk_3",
"source_entity_id": "entity_refund_processing",
"target_entity_id": "entity_finance_dept"
},
"target": {
"name": "Finance Department",
"type": "ORGANIZATION",
"namespace": "default",
"entity_id": "entity_finance_dept",
"identifier": "[email protected]"
}
}
],
"relevancy_score": 0.82,
"combined_context": "Refund Processing is managed by the Finance Department.",
"group_id": "p_0",
"source_chunk_ids": ["policy_main_chunk_3"]
}
],
"chunk_id_to_group_ids": {
"policy_main_chunk_3": ["p_0"]
}
},
"additional_context": {
"pref-tone": {
"chunk_uuid": "pref-tone",
"id": "mem_user_alex_tone",
"chunk_content": "Prefers concise answers.",
"source_type": "memory",
"source_title": "User preferences",
"source_upload_time": "2026-05-12T08:14:00Z",
"source_last_updated_time": "2026-05-12T08:14:00Z"
}
}
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": true,
"data": {
"chunks": [],
"sources": [],
"graph_context": {
"query_paths": [],
"chunk_relations": [],
"chunk_id_to_group_ids": {}
},
"additional_context": {}
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": false,
"data": null,
"error": {
"code": "INVALID_PARAMETERS",
"message": "query must not be empty"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 4.8
}
}
typepicks what to query:"knowledge","memory", or"all"(both, merged and re-ranked together).query_bypicks how to match:"hybrid"(semantic + BM25, the default) or"text"(BM25 only - pair withoperator).modepicks how to rank results:"fast"(single-pass, low-latency),"thinking"(expands query, reranks, and can include forceful-relation context), or"auto"(scores the query and routes to"fast"or"thinking"automatically, defaulting to"thinking"when the signal is inconclusive - the default ifmodeis omitted).
database and collection are the current field names (formerly tenant_id and sub_tenant_id). The old names remain accepted as deprecated aliases for full backward compatibility.result = client.query(
database="acme_corp",
collection="user_alex",
query="What is our refund policy, and how should I explain it to this user?",
# What to query: "knowledge", "memory", or "all".
type="all",
# How to match: "hybrid" (default) or "text" (BM25).
query_by="hybrid",
# "thinking" improves quality; use "fast" for lowest latency.
mode="thinking",
# Ranking and response controls.
max_results=10,
alpha="auto",
recency_bias=0.2,
graph_context=True,
# Pull author-declared related sources into additional_context.
# Only applies when mode="thinking".
query_forceful_relations=True,
# Top-level keys match metadata; additional_metadata is per-source.
metadata_filters={
"department": "support",
"additional_metadata": {
"source": "policy",
},
},
# Short factual hint; not a hard filter.
additional_context="User is asking from the billing help center.",
)
const result = await client.query({
database: "acme_corp",
collection: "user_alex",
query: "What is our refund policy, and how should I explain it to this user?",
// What to query: "knowledge", "memory", or "all".
type: "all",
// How to match: "hybrid" (default) or "text" (BM25).
queryBy: "hybrid",
// "thinking" improves quality; use "fast" for lowest latency.
mode: "thinking",
// Ranking and response controls.
maxResults: 10,
alpha: "auto",
recencyBias: 0.2,
graphContext: true,
// Pull author-declared related sources into additional_context.
// Only applies when mode: "thinking".
queryForcefulRelations: true,
// Top-level keys match metadata; additional_metadata is per-source.
metadataFilters: {
department: "support",
additional_metadata: {
source: "policy",
},
},
// Short factual hint; not a hard filter.
additionalContext: "User is asking from the billing help center.",
});
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "user_alex",
"query": "What is our refund policy, and how should I explain it to this user?",
"type": "all",
"query_by": "hybrid",
"mode": "thinking",
"max_results": 10,
"alpha": "auto",
"recency_bias": 0.2,
"graph_context": true,
"query_forceful_relations": true,
"metadata_filters": {
"department": "support",
"additional_metadata": {
"source": "policy"
}
},
"additional_context": "User is asking from the billing help center."
}'
Querying multiple collections
Usecollections when one query should fan out across multiple user, workspace, or team scopes. The field accepts either a list or a weighted object:
{
"database": "acme_corp",
"collections": ["workspace_42", "user_alex"],
"query": "What renewal risks should I know about?",
"type": "all"
}
{
"database": "acme_corp",
"collections": {
"workspace_42": 2,
"user_alex": 1
},
"query": "What renewal risks should I know about?",
"type": "all"
}
max_results is omitted, HydraDB uses up to 10 results per collection, capped at 1000 fanout candidates before the final ranked response is shaped. When max_results is set, it is the final global response cap across the merged fanout result set.
Caching tip: collections list order is not semantically significant for fanout selection. Sort list values before constructing cache keys; for weighted objects, sort keys and keep weights at the documented one-decimal precision so equivalent calls share the same cache entry.
Transforming the response into LLM context
Usebuild_string / buildString from the SDK. It takes any POST /query result and returns a formatted plain string.
from hydra_db import HydraDB
from hydra_db.helpers import build_string
client = HydraDB(token="YOUR_API_KEY")
result = client.query(
database="your-database",
collection="your-collection",
query="How does authentication work?",
type="knowledge",
query_by="hybrid",
max_results=5,
mode="fast",
graph_context=True,
)
context = build_string(result)
import { HydraDBClient } from "@hydradb/sdk";
import { buildString } from "@hydradb/sdk/helpers";
const client = new HydraDBClient({ token: process.env.HYDRA_DB_API_KEY });
const result = await client.query({
database: "your-database",
collection: "your-collection",
query: "How does authentication work?",
type: "knowledge",
queryBy: "hybrid",
maxResults: 5,
mode: "fast",
graphContext: true,
});
const context = buildString(result);
Common use-cases and their configurations
1. Knowledge RAG - answer from shared documents
1. Knowledge RAG - answer from shared documents
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"query": "What is our refund policy?",
"type": "knowledge",
"query_by": "hybrid",
"mode": "thinking",
"max_results": 10,
"graph_context": true
}'
const result = await client.query({
database: "acme_corp",
query: "What is our refund policy?",
type: "knowledge",
queryBy: "hybrid",
mode: "thinking",
maxResults: 10,
graphContext: true,
});
result = client.query(
database="acme_corp",
query="What is our refund policy?",
type="knowledge",
query_by="hybrid",
mode="thinking",
max_results=10,
graph_context=True,
)
2. Personalized answer - combine knowledge with user memories
2. Personalized answer - combine knowledge with user memories
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "user_alex",
"query": "What is our refund policy, and how should I explain it to this user?",
"type": "all",
"query_by": "hybrid",
"mode": "thinking"
}'
const result = await client.query({
database: "acme_corp",
collection: "user_alex",
query: "What is our refund policy, and how should I explain it to this user?",
type: "all",
queryBy: "hybrid",
mode: "thinking",
});
result = client.query(
database="acme_corp",
collection="user_alex",
query="What is our refund policy, and how should I explain it to this user?",
type="all",
query_by="hybrid",
mode="thinking",
)
3. Retrieve user preferences - query only user memories
3. Retrieve user preferences - query only user memories
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "user_alex",
"query": "Does the user have any specific preferences for tone or response length?",
"type": "memory",
"query_by": "hybrid",
"query_apps": true
}'
const result = await client.query({
database: "acme_corp",
collection: "user_alex",
query: "Does the user have any specific preferences for tone or response length?",
type: "memory",
queryBy: "hybrid",
queryApps: true,
});
result = client.query(
database="acme_corp",
collection="user_alex",
query="Does the user have any specific preferences for tone or response length?",
type="memory",
query_by="hybrid",
query_apps=True,
)
4. Exact phrase lookup - BM25 for legal terms, SKUs, or IDs
4. Exact phrase lookup - BM25 for legal terms, SKUs, or IDs
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"query": "GDPR Article 17",
"type": "knowledge",
"query_by": "text",
"operator": "phrase"
}'
const result = await client.query({
database: "acme_corp",
query: "GDPR Article 17",
type: "knowledge",
queryBy: "text",
operator: "phrase",
});
result = client.query(
database="acme_corp",
query="GDPR Article 17",
type="knowledge",
query_by="text",
operator="phrase",
)
5. Let HydraDB decide - auto-route between fast and thinking
5. Let HydraDB decide - auto-route between fast and thinking
curl -X POST 'https://api.hydradb.com/query' \
-H "Authorization: Bearer <your_api_key>" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"query": "How does the Q2 partnership between Acme and Globex affect our SLA with Initech?",
"type": "knowledge",
"query_by": "hybrid",
"mode": "auto"
}'
const result = await client.query({
database: "acme_corp",
query: "How does the Q2 partnership between Acme and Globex affect our SLA with Initech?",
type: "knowledge",
queryBy: "hybrid",
mode: "auto",
});
result = client.query(
database="acme_corp",
query="How does the Q2 partnership between Acme and Globex affect our SLA with Initech?",
type="knowledge",
query_by="hybrid",
mode="auto",
)
"fast" or "thinking" - a query naming several distinct entities like this one is likely to route to "thinking". Use "auto" for traffic where query complexity varies call-to-call and you don’t want to hand-pick per request. This is also the default: an omitted mode field behaves exactly like mode: "auto". Set mode to "fast" or "thinking" explicitly if you want a deterministic pipeline instead.Request body
| Name | Description |
|---|---|
Owning database. Formerly tenant_id; the tenant_id alias is still accepted (deprecated). | |
Single collection scope. Required for per-user memory queries. Formerly sub_tenant_id; the sub_tenant_id alias is still accepted (deprecated). (default=default collection) | |
Multi-collection scope. Send a list of collection IDs for equal weighting, or an object mapping collection ID to a positive relative weight (at most one decimal place, e.g. {"finance": 1.5, "legal": 0.8}) to bias ranking. Up to 100 collections. Do not combine with collection/sub_tenant_id. Formerly sub_tenant_ids; the sub_tenant_ids alias is still accepted (deprecated since 2.0.1). | |
| Query terms or natural-language question. Cannot be empty. | |
What collection to query. "all" runs knowledge and memory in parallel and merges by relevancy_score. (default="knowledge") | |
Retrieval method. See Query methods. (default="hybrid") | |
Adds an app-aware retrieval lane for app sources while still querying the full selected knowledge scope. Set true for better app-source matching, thread/relation traversal, exact IDs, and actor/provider hints. It does not limit query to only app sources. (default=false) | |
BM25 operator for query_by: "text". Ignored for hybrid. (default="or") | |
Retrieval pipeline. Applies to hybrid only; ignored for text. "auto" scores the query before retrieval and resolves it to "fast" or "thinking", defaulting to "thinking" when the signal is inconclusive; it also overrides whatever graph_context you sent to match that resolved mode. (default="auto") | |
Maximum chunks to return. Default 10; maximum 50. Start with 10, use 5 for tight prompts, and increase only when reranking downstream. | |
Hybrid weight (1.0 = pure semantic, 0.0 = pure BM25). Applies to query_by: "hybrid" only. (default=0.8) | |
Boost newer content. (default=0.0) | |
When true, includes the entity/relation graph slice in the response under graph_context. Set to false when you only need ranked chunks. Relations you supplied via Bring Your Own Graph appear here identically to extracted ones. (default=true) - under mode: "auto", this value is overridden by the resolved mode regardless of what you send. | |
Pull author-declared related sources into additional_context. Only takes effect when mode resolves to "thinking" - silently ignored in fast mode, and under mode: "auto" whether it takes effect depends on the automatic routing decision. (default=true) | |
Request-time hint to guide retrieval (e.g., “user is on the billing page”). This is different from the response additional_context map. (default=null) | |
Deterministic narrowing before ranking. See Filters. Each list holds at most 500 values, and the whole object is capped at 64 KiB of compact JSON; over either returns 400. (default=null) |
alpha: start at0.8. Lower toward0.3–0.5when the query contains literal tokens (error codes, SKUs, product names). Raise toward0.9for conceptual questions. Use“auto”when query shape varies.recency_bias: leave at0for static reference material. Set0.2–0.4for mixed content,0.6–0.8for changelogs, news, or status updates.max_results: start at10. Drop to5for tight context windows; raise to20if you rerank downstream.
Decision matrix
Type selection
Type selection
| Value | Queries | Best for |
|---|---|---|
"knowledge" (default) | Knowledge documents, files, and app sources | Document Q&A, RAG context. |
"query_apps=true" | Full selected knowledge scope plus app-aware retrieval | App-specific Q&A that should still query non-app knowledge documents. |
"memory" | User memories | Personalization and user preferences. |
"all" | Both, merged in one ranked result set | Personalized answers grounded in both shared and user-specific context. |
Query methods
Query methods
| Method | Pipeline | Best for |
|---|---|---|
"hybrid" (default) | Dense vectors + BM25 keyword | General-purpose retrieval and RAG. |
"text" | BM25 only | Exact terms, compliance lookups, phrase query. Pair with operator. |
Modes
Modes
query_by: "hybrid":| Mode | Behavior | When to use |
|---|---|---|
"fast" | Single query pass | Real-time chat, autocomplete, simple lookups. |
"thinking" | Multi-query expansion + reranking + forceful-relation context | Complex queries, customer-facing answers, anything where quality matters. |
"auto" (default if mode is omitted) | Scores the query before retrieval and routes to "fast" or "thinking"; defaults to "thinking" when the signal is inconclusive. Also overrides graph_context to match whichever mode it picks. | Mixed or unpredictable query traffic where you don’t want to hand-pick per request. |
"auto"’s resolved pipeline isn’t reported back in the response, so budget latency as thinking-level in the worst case. Omitting mode behaves exactly like mode: "auto" - set it explicitly to "fast" or "thinking" if you want a deterministic pipeline instead.Filters
Filters
metadata_filters are hard exact-match constraints applied before ranking and re-checked after hydration. The shape combines two filter scopes:{
"metadata_filters": {
"department": "engineering",
"region": "us-east",
"additional_metadata": {
"source": "account_plan",
"author": "alex"
}
}
}
| Where | What it matches |
|---|---|
Top-level keys (department, region) | The source’s schema-backed metadata. Keys must be declared in the database’s database_metadata_schema with enable_match: true, otherwise they are silently ignored. |
Nested under additional_metadata | The source’s free-form per-document fields. No schema declaration required. document_metadata is accepted as a legacy alias. |
"department": ["finance", "legal"] returns sources from either - and there is no ALL/AND operator within a single key. Lists are supported on VARCHAR fields only: a list passed for a declared field of any other type is rejected with 400 VALIDATION_ERROR. Range, contains, and fuzzy operators are not supported; run multiple queries or post-process client-side for those cases.{
"success": true,
"data": {
"chunks": [
{
"chunk_uuid": "policy_main_chunk_3",
"id": "policy_main",
"chunk_content": "Refunds are issued within 30 days...",
"source_type": "pdf",
"source_title": "Compliance Policy",
"source_upload_time": "2026-05-12T08:14:00Z",
"source_last_updated_time": "2026-05-12T08:14:00Z",
"layout": "{\"offsets\":{\"document_level_start_index\":1024},\"page\":3}",
"relevancy_score": 0.91,
"extra_context_ids": ["pref-tone"],
"metadata": { "department": "legal" },
"additional_metadata": { "author": "Legal Team" }
}
],
"sources": [
{
"id": "policy_main",
"title": "Compliance Policy",
"type": "pdf",
"description": "",
"url": "",
"timestamp": "2026-05-12T08:14:00Z",
"metadata": { "department": "legal" },
"additional_metadata": { "author": "Legal Team" },
"app_kind": null,
"app_provider": null,
"app_external_id": null
}
],
"graph_context": {
"query_paths": [
{
"triplets": [
{
"source": {
"name": "Compliance Policy",
"type": "DOCUMENT",
"namespace": "default",
"entity_id": "entity_compliance_policy",
"identifier": "https://api.hydradb.com/docs/compliance_policy"
},
"relation": {
"canonical_predicate": "GOVERNS",
"raw_predicate": "governs and regulates",
"context": "The compliance policy governs the refund processing timeline of 30 days.",
"confidence": 0.95,
"temporal_details": null,
"timestamp": 1778573640.0,
"relationship_id": "rel_governs_refunds",
"chunk_id": "policy_main_chunk_3",
"source_entity_id": "entity_compliance_policy",
"target_entity_id": "entity_refund_processing"
},
"target": {
"name": "Refund Processing",
"type": "PROCESS",
"namespace": "default",
"entity_id": "entity_refund_processing",
"identifier": null
}
}
],
"relevancy_score": 0.89,
"combined_context": "The Compliance Policy governs the Refund Processing, which regulates refunds.",
"group_id": null,
"source_chunk_ids": ["policy_main_chunk_3"]
}
],
"chunk_relations": [
{
"triplets": [
{
"source": {
"name": "Refund Processing",
"type": "PROCESS",
"namespace": "default",
"entity_id": "entity_refund_processing",
"identifier": null
},
"relation": {
"canonical_predicate": "MANAGED_BY",
"raw_predicate": "is managed by",
"context": "Refund processing is managed by the Finance Department.",
"confidence": 0.9,
"temporal_details": "Q2 2026 onwards",
"timestamp": 1778573640.0,
"relationship_id": "rel_managed_by_finance",
"chunk_id": "policy_main_chunk_3",
"source_entity_id": "entity_refund_processing",
"target_entity_id": "entity_finance_dept"
},
"target": {
"name": "Finance Department",
"type": "ORGANIZATION",
"namespace": "default",
"entity_id": "entity_finance_dept",
"identifier": "[email protected]"
}
}
],
"relevancy_score": 0.82,
"combined_context": "Refund Processing is managed by the Finance Department.",
"group_id": "p_0",
"source_chunk_ids": ["policy_main_chunk_3"]
}
],
"chunk_id_to_group_ids": {
"policy_main_chunk_3": ["p_0"]
}
},
"additional_context": {
"pref-tone": {
"chunk_uuid": "pref-tone",
"id": "mem_user_alex_tone",
"chunk_content": "Prefers concise answers.",
"source_type": "memory",
"source_title": "User preferences",
"source_upload_time": "2026-05-12T08:14:00Z",
"source_last_updated_time": "2026-05-12T08:14:00Z"
}
}
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": true,
"data": {
"chunks": [],
"sources": [],
"graph_context": {
"query_paths": [],
"chunk_relations": [],
"chunk_id_to_group_ids": {}
},
"additional_context": {}
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": false,
"data": null,
"error": {
"code": "INVALID_PARAMETERS",
"message": "query must not be empty"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 4.8
}
}
Behavior notes
modedefaults to"auto". Omittingmodeentirely behaves exactly likemode: "auto"- set it explicitly to"fast"or"thinking"if you want a deterministic pipeline.graph_contextis on by default. Set it tofalseif you only need ranked chunks and want to drop the graph slice from the response.recency_biasis off by default. Defaults to0.0- no recency boost is applied unless you set it.
query_forceful_relationsrequiresmodeto resolve to"thinking". Infastmode the flag is silently ignored. The server does not error or warn - youradditional_contextwill simply be empty. Undermode: "auto"this depends on that request’s routing decision, not on what you asked for.mode: "auto"overridesgraph_context. Whatever you send forgraph_contextis replaced to match the resolved mode -trueif auto escalates tothinking,falseif it resolves tofast. This also applies whenmodeis omitted, since it defaults to"auto". Setgraph_contextexplicitly only when calling"fast"or"thinking"directly.- Want a deterministic pipeline instead of automatic routing? Set
modeexplicitly to"fast"or"thinking"- an omittedmodefield now defaults to"auto", not"fast". - Relation
timestampis a Unix epoch float here. In thegraph_contextslice returned by/query- and in the passthrough relations returned by List Documents withinclude_fields: ["relations"]- each relation’stimestampis a Unix epoch value in seconds (a float, e.g.1778573640.0). The dedicated Context Relations endpoint returns the same field as an ISO-8601 string instead. Normalize before comparing relation timestamps across endpoints. - Use the right metadata namespace. Top-level
metadata_filterskeys matchmetadata; free-form per-document fields must be nested underadditional_metadata(document_metadatais only a legacy alias). Declare hot top-level filter fields indatabase_metadata_schemawithenable_match: true. - Common mistakes. Check Ingestion Status for recently ingested documents before querying. If you omit
collection, HydraDB queries the default collection; use List Collections to discover available IDs.
Errors
Common codes:400 INVALID_PARAMETERS (empty query), 404 DATABASE_NOT_FOUND, 422 VALIDATION_ERROR, 500 INTERNAL_ERROR. See Error Responses for the full list.
400 also covers oversized filters: a metadata_filters list above 500 values, or
a metadata_filters object above 64 KiB of compact JSON. The message names the
offending key or reports the actual byte count. See
Filter size limits.
- Setup first: Ingest Context - content must be indexed
- Confirm indexing: Ingestion Status - wait for
completed(orgraph_creation) - Graph follow-up: Context Relations - inspect relationships in detail
- Concepts: Usage → Query
- Concepts: Concepts → Semantic Search
- Concepts: Concepts → Context Graphs
- Response handling: Usage → How to Use API Results
- Read more: Query - Overview
Authorizations
API key sent as a Bearer token: "Bearer prefix.secret"
Body
Unified query request
ACL scopes retrieval to documents the given principals may access (PRO-1684 document ACLs): a document matches when its stored ACL is empty (unrestricted, pre-RBAC content and connectors without permission support), contains public, or intersects these principals. Entries are bare emails or prefixed principals (user_email:/group:/domain:). Omitted, empty, or ["*"] disables ACL filtering entirely, today's behavior. Like IDs, the resulting clause survives the metadata zero-result retry. An entry that is not a known principal fails CLOSED: it matches only public and unrestricted documents, never restricted.
Optional context string prepended to the query to improve retrieval relevance.
"The user is a senior engineer onboarding to the platform."
Weighting balance between dense and sparse retrieval in hybrid mode. "auto" lets HydraDB choose; a number from 0 (full BM25) to 1 (full dense) sets it explicitly.
Collection scope. Defaults to the default collection when omitted. Formerly sub_tenant_id; the sub_tenant_id alias is still accepted (deprecated).
"team_docs"
Preferred /query scope selector. Send either a list of collection IDs for equal normalized weighting, or an object mapping collection ID to a positive relative ranking weight with at most one decimal place. Do not send together with the deprecated sub_tenant_ids or sub_tenant_id.
1 - 100 elements["team_docs", "engineering"]
Database is the canonical v2 name for the tenant scope. TenantID is its deprecated alias and remains fully accepted. The TenantAliases middleware reconciles the two before binding, so TenantID is always populated and the handler reads it; Database/Collection are carried only for docs/OpenAPI.
"acme_corp"
Whether to include graph context in the response. Defaults to true for /query when omitted.
true
GraphVectorPrune switches the graph-connected-chunks lane from "fetch graph-selected chunks and let the fusion reranker sort them out" to "fetch a wider graph-selected candidate pool, then rank that pool by Milvus vector similarity, fully replacing the final chunk list." Works in either fast or thinking mode. Default false preserves existing behavior. Also gated server-side by a repo-level config flag (SearchService's graphVectorPruneEnabled) — if that flag is off, this is forced to false regardless of what the request sets, so a deployment can disable the mechanism without any client-side change.
true
GraphVectorPruneSpacyEntities: when GraphVectorPrune is also set, swaps the graph lane's entity-extraction source from the default LLM-based extractor to a local spaCy subprocess (faster, no network round trip, but a narrower/mismatched entity vocabulary versus the graph's own LLM-extracted node names). No-op if GraphVectorPrune is false (including when forced false by the server-level flag) or no spaCy extractor was configured at startup.
true
IDs optionally scopes retrieval to specific source ids. The v2 wire field is
ids (matching /context/list); empty means search the whole corpus. Applied
as a Milvus source_id in [...] pre-filter that is preserved across the
metadata zero-result retry, so a source-scoped search that matches nothing
returns nothing rather than silently widening to the whole corpus.
["HydraDoc1234", "HydraDoc4567"]
Maximum number of chunks to return.
10
Filters results by source metadata. Top-level keys target tenant metadata (for example department, priority, active, or tags). Nested additional_metadata keys target document metadata. Separate keys are ANDed. A scalar value is an exact match; an array means match ANY one of the listed values (OR) - there is no ALL/AND operator within a single key. Arrays are supported on VARCHAR fields only: an array passed for a declared field of any other type is rejected with 400 VALIDATION_ERROR. Size limits: each list may hold at most 500 values, and the whole metadata_filters object is capped at 64 KiB measured on its compact JSON encoding in UTF-8 bytes (keys and punctuation count). Exceeding either returns 400 naming the offending key or the actual byte count.
Show child attributes
Show child attributes
{
"active": true,
"additional_metadata": { "author": "ada" },
"department": "finance",
"priority": 7,
"tags": ["alpha", "beta"]
}
fast, thinking, auto "thinking"
Number of adjacent chunks to pull alongside each matched chunk for additional context.
3
or, and, phrase "and"
Natural-language search query.
"Which mode does the user prefer?"
Whether to include app-aware knowledge retrieval. Applies to knowledge hybrid queries.
true
Retrieval method to use for the query.
hybrid, text "hybrid"
Whether to force relation expansion for graph-aware query retrieval. Defaults to true when omitted.
true
Recency boost applied to ranking. 0 disables it; higher values favour more recent sources.
0.2
Deprecated for /query (since 2.0.1). Use collection for a single scope or collections for multiple. Backwards-compatible and will be removed in a future version. Do not send together with a multi-scope selector.
"sub_tenant_4567"
Deprecated for /query (since 2.0.1). Use collections instead; it accepts the same list or weighted-object shape. Backwards-compatible and will be removed in a future version. Do not send together with collections.
1 - 100 elements["sub_tenant_4567", "sub_tenant_8901"]
TemporalIntent (EXPERIMENTAL) lets the caller supply the classification (mode/window/phrases) directly, bypassing the regex classifier — for agents whose own LLM already understands the query, and for non-English queries. Invalid overrides fall back to the classifier.
Show child attributes
Show child attributes
{
"duration_to_now": true,
"mode": "thinking"
}
TemporalNow optionally anchors "now" for temporal reasoning (ISO-8601). Callers replaying past conversations (or backfilling) must supply it or to-now durations and recency windows resolve against the server's wall clock (LongMemEval measured 0 exact to-now durations from this alone).
TemporalReasoning activates the temporal read path: the query is classified into a temporal mode (current/as-of/range/upcoming...), matching edge-level temporal facts are resolved from the edge_temporal store and ride back on the response (temporal_facts / temporal_duration / temporal_filter). CONTRACT: chunk ranking is NEVER altered — ON returns the same chunks as OFF; the layer is additive payload + computed answers only (rank shaping measured net-negative on BEAM/LongMemEval/TEMPO; see temporal_filters.go). Optional; ON by default — pass temporal_reasoning:false to disable. Resolved by GetTemporalReasoningOrDefault (ownership rule).
true
deprecated: use database
"tenant_1234"
Corpus to query: knowledge, memory, or all.
knowledge, memory, all Response
OK
Show child attributes
Show child attributes
{
"additional_context": "The user is a senior engineer onboarding to the platform.",
"chunks": [
{
"additional_metadata": { "author": "ada", "doc_version": 3 },
"chunk_content": "HydraDB supports hybrid retrieval across knowledge and memories.",
"chunk_uuid": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"collection": "team_docs",
"extra_context_ids": [
"HydraEmbeddings123_2",
"HydraEmbeddings123_3"
],
"id": "HydraDoc1234",
"layout": "text",
"metadata": { "department": "finance", "priority": 7 },
"relevancy_score": 0.87,
"source_last_updated_time": "2026-07-02T12:30:00Z",
"source_title": "Project Phoenix Overview",
"source_type": "file",
"source_upload_time": "2026-07-02T10:00:00Z",
"sub_tenant_id": "sub_tenant_4567"
}
],
"graph_context": {
"chunk_id_to_group_ids": { "HydraEmbeddings123_0": ["grp_1234"] },
"chunk_relations": [
{
"combined_context": "Acme Corp deploys HydraDB in production for context retrieval.",
"group_id": "grp_1234",
"relevancy_score": 0.87,
"source_chunk_ids": [
"HydraEmbeddings123_0",
"HydraEmbeddings123_1"
],
"triplets": [
{
"relation": {
"confidence": 0.92,
"predicate": "works_at"
},
"source": {
"entity_id": "entity_1a2b",
"name": "Ada",
"type": "person"
},
"target": {
"entity_id": "entity_3c4d",
"name": "Acme Corp",
"type": "organization"
}
}
]
}
],
"query_paths": [
{
"combined_context": "Acme Corp deploys HydraDB in production for context retrieval.",
"group_id": "grp_1234",
"relevancy_score": 0.87,
"source_chunk_ids": [
"HydraEmbeddings123_0",
"HydraEmbeddings123_1"
],
"triplets": [
{
"relation": {
"confidence": 0.92,
"predicate": "works_at"
},
"source": {
"entity_id": "entity_1a2b",
"name": "Ada",
"type": "person"
},
"target": {
"entity_id": "entity_3c4d",
"name": "Acme Corp",
"type": "organization"
}
}
]
}
]
},
"source_facts": [
{
"app_kind": "slack",
"chunk_id": "HydraEmbeddings123_0",
"provider": "slack",
"relationship_id": "rel_1234",
"source_id": "HydraDoc1234",
"synced_at": 1
}
],
"source_filter": {
"applied": true,
"degraded": true,
"matched_facts": 1,
"mode": "thinking",
"provider": "slack",
"thread_scope": true,
"truncated": true
},
"sources": [
{
"additional_metadata": { "author": "ada", "doc_version": 3 },
"app_external_id": "C0123456789",
"app_kind": "slack",
"app_provider": "slack",
"collection": "team_docs",
"description": "Internal overview of the Project Phoenix rollout.",
"id": "HydraDoc1234",
"metadata": { "department": "finance", "priority": 7 },
"sub_tenant_id": "sub_tenant_4567",
"timestamp": "2026-07-02T10:00:00Z",
"title": "Project Phoenix Overview",
"type": "knowledge",
"url": "https://docs.hydradb.com/phoenix"
}
],
"temporal_duration": {
"approximate": true,
"days": 1,
"from": {
"chunk_id": "HydraEmbeddings123_0",
"event_end": 1,
"event_start": 1,
"relationship_id": "rel_1234",
"source_id": "HydraDoc1234",
"status": "completed"
},
"pairing_confidence": 0.5,
"to": {
"chunk_id": "HydraEmbeddings123_0",
"event_end": 1,
"event_start": 1,
"relationship_id": "rel_1234",
"source_id": "HydraDoc1234",
"status": "completed"
}
},
"temporal_facts": [
{
"chunk_id": "HydraEmbeddings123_0",
"event_end": 1,
"event_start": 1,
"relationship_id": "rel_1234",
"source_id": "HydraDoc1234",
"status": "completed"
}
],
"temporal_filter": {
"applied": true,
"chunk_scope": 1,
"degraded": true,
"matched_facts": 1,
"mode": "thinking",
"promoted": 1,
"truncated": true
}
}
Error message, empty string on success.
Show child attributes
Show child attributes
{
"code": "DATABASE_NOT_FOUND",
"message": "Database not found"
}
Show child attributes
Show child attributes
{
"collection": "team_docs",
"database": "acme_corp",
"latency_ms": 12.3,
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"source_type": "file",
"sub_tenant_id": "sub_tenant_4567",
"tenant_id": "tenant_1234"
}
Whether the request succeeded.
true
Was this page helpful?
