Skip to main content
HydraDB accepts content, processes it in the background, and makes it searchable. Add content means sending the content; indexing makes it searchable; retrieval finds relevant passages when you query. This page follows that sequence and shows what to check when results are empty.

The big picture

The API has three jobs: Two details to notice in the diagram:
  • Two vector stores, one ingest endpoint: POST /context/ingest routes to the Knowledge store when type=knowledge and to the Memories store when type=memory. Same endpoint, different bucket.
  • One query endpoint, every retrieval method: POST /query is the only retrieval entry point. The type and query_by parameters 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: Poll GET /context/status with the returned id to follow each item through the pipeline. Two practical notes:
  • graph_creation is already queryable: Chunks become retrievable as soon as embedding finishes; you only need to wait for completed when you specifically need full graph context (graph_context: true on query).
  • Failures surface with detail: An errored status comes back with an error_code and error_message so you can distinguish parse failures from validation problems from infrastructure issues.
The full status table and polling pattern lives at Ingestion Status.

From upload to query

Here is the end-to-end flow. Each step links to the endpoint that owns it:
  1. Create a database with POST /databases (your isolated workspace, optionally with a metadata schema declared up front).
  2. Wait for the database to be ready by polling GET /databases/status until infra.ready_for_ingestion is true, so it can accept content.
  3. Ingest content with POST /context/ingest: pick type=knowledge for shared documents or type=memory for per-user context. See Knowledge and Memories for the content models.
  4. Watch indexing finish by polling GET /context/status until each id reaches completed (or graph_creation if you don’t need graph traversal).
  5. Query with POST /query. Pick type: "knowledge" for Knowledge, type: "memory" for Memories, or type: "all" for both. Pair with query_by: "hybrid" (default) or "text" (BM25, with operator). The mechanics live in Query.

Database isolation

A database (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 store, query_by picks the method. From there, every call goes through the same pipeline:
  1. Authenticate and scope: Validate database, resolve the database, and apply the requested collection or collections (the default collection when neither is sent).
  2. Filter before ranking: Apply metadata_filters to narrow the candidate set (see Metadata).
  3. Retrieve: Run hybrid retrieval over the semantic vector store and the BM25 keyword index, or BM25-only retrieval when query_by: "text".
  4. Blend: Use alpha to weight semantic vs. BM25 keyword contributions (1.0 = pure semantic, 0.0 = pure BM25).
  5. Enrich: When graph_context: true (the default), traverse the context graph and attach related paths; thinking mode always does, so graph_context: false takes effect only in fast mode. When mode: "thinking", expand the query, rerank, and pull in author-declared forceful relations. mode: "auto" (the default) picks fast or thinking per query.
  6. Shape the response: Return ranked chunks, deduplicated sources, optional graph_context, and any additional_context.
The response is retrieved context, not a final LLM answer. You pass the chunks (and any graph context) into your own agent or model prompt. See How to Use API Results for the helper that formats it.

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:
  1. Status first: Did every id reach completed (or at least graph_creation)? Check Ingestion Status.
  2. Scope second: Is the database correct? Did you write under one collection and read under another? See Multi-Tenant.
  3. Filters third: Are you using the right namespace? Top-level metadata_filters keys match metadata; free-form fields belong under additional_metadata. For hot top-level filters, declare the field in database_metadata_schema. See Metadata.