The big picture
HydraDB organizes its work into three logical planes. You interact only with the API; everything else stays behind the service boundary.
Two details to notice in the diagram:
- Two vector stores, one ingest endpoint.
POST /context/ingestroutes to the Knowledge store whentype=knowledgeand to the Memories store whentype=memory. Same endpoint, different bucket. - One query endpoint, every retrieval method.
POST /queryis the only retrieval entry point. Thetypeandquery_byparameters decide what gets queried and how - see Query for the full picture.
Ingestion lifecycle
Ingestion is asynchronous. A successful upload means HydraDB accepted the work and queued it; it does not mean the content is immediately queryable. Each source moves through a status pipeline before it becomes fully queryable: PollGET /context/status with the returned id to follow each item through the pipeline. Two practical notes:
graph_creationis already queryable. Chunks become retrievable as soon as embedding finishes; you only need to wait forcompletedwhen you specifically need full graph context (graph_context: trueon query).- Failures surface with detail. An
erroredstatus comes back with anerror_codeandmessageso you can distinguish parse failures from validation problems from infrastructure issues.
From upload to query
Here’s the canonical end-to-end flow. Each step links to the endpoint that owns it:- Create a database with
POST /databases- your isolated workspace, optionally with a metadata schema declared up front. - Wait for provisioning by polling
GET /databases/statusuntilvectorstore_status.knowledge,vectorstore_status.memories, andgraph_statusare alltrue. - Ingest content with
POST /context/ingest- picktype=knowledgefor shared documents ortype=memoryfor per-user context. See Knowledge and Memories for the content models. - Watch indexing finish by polling
GET /context/statusuntil eachidreachescompleted(orgraph_creationif you don’t need graph traversal). - Query with
POST /query. Picktype: "knowledge"for Knowledge,type: "memory"for Memories, ortype: "all"for both. Pair withquery_by: "hybrid"(default) or"text"(BM25, withoperator). The mechanics live in Query.
type and query_by combination fits the task.
Database isolation
Adatabase (formerly tenant_id, still accepted as a deprecated alias) is the top-level isolation boundary - no database can read another database’s data. Within a database, collection (formerly sub_tenant_id) carves out logical partitions: users, teams, workspaces, or projects. Omitting collection on any call resolves to the database’s default collection, which is created on the first write - no collection exists until then.
The right mapping depends on your product shape:
The deeper trade-offs - when to spin up a new database vs. a new collection, how scoping interacts with metadata filters, and how this affects Memories - are covered in Multi-Tenant Support.
Retrieval pipeline
POST /query is the single retrieval endpoint. Two parameters describe the request: type picks the collection, query_by picks the method. From there, every call goes through the same pipeline:
- Authenticate and scope. Validate
database, resolve the database, and apply the requestedcollection. - Filter before ranking. Apply
metadata_filtersto narrow the candidate set (see Metadata). - Retrieve. Run hybrid retrieval over the semantic vector store and the keyword bm25 index, or BM25-only retrieval when
query_by: "text". - Blend. Use
alphato weight semantic vs. keyword bm25 contributions (1.0= pure semantic,0.0= pure BM25). - Enrich. When
graph_context: true, traverse the context graph and attach related paths. Whenmode: "thinking", expand the query, rerank, and pull in author-declared forceful relations. - Shape the response. Return ranked
chunks, deduplicatedsources, optionalgraph_context, and anyadditional_context.
Key controls
A short cheat sheet for the parameters you’ll touch most often, and where each one lives:Operational mental model
HydraDB separates write-time work from query-time work. Uploads return quickly and run in the background; query stays synchronous and reads only indexed content. When results look incomplete, walk the chain in order:- Status first. Did every
idreachcompleted(or at leastgraph_creation)? Check Ingestion Status. - Scope second. Is the
databasecorrect? Did you write under onecollectionand read under another? See Multi-Tenant. - Filters third. Are you using the right namespace? Top-level
metadata_filterskeys matchmetadata; free-form fields belong underadditional_metadata. For hot top-level filters, declare the field indatabase_metadata_schemawithenable_match: true. See Metadata.
Related
- Core Concepts - the five primitives: Memories, Knowledge, Query, Databases, Metadata
- Quickstart - build your first integration in five minutes
- Knowledge and Memories - the two content models
- Query - deep dive on
POST /query - Multi-Tenant Support - scoping patterns and pitfalls
- Context Graphs - how the graph layer enriches retrieval
- Metadata - designing filterable fields