Skip to main content
Knowledge is what your AI reasons over: product docs, policy PDFs, runbooks, wiki pages, Slack threads, tickets, and emails. There are three ways to add it:
  • Files: upload PDF, DOCX, Markdown, CSV, or TXT files, and HydraDB reads them for you.
  • App sources: send records your application already parsed from an app, such as a Slack message or a Jira ticket.
  • Connectors: connect an app such as Slack, Google Drive, Notion, or GitHub once, and HydraDB keeps it in sync. There are 70 to choose from.
Files and app sources go to POST /context/ingest with type=knowledge. Each file or record is a source. HydraDB splits it into searchable passages called chunks, builds a context graph from it, and returns the relevant chunks through POST /query. Preferences, decisions, and past conversations are memories, not knowledge. For a company brain, ingest everything into one collection and use metadata filters to narrow results. In this guide:
  1. Upload files: PDFs, Word documents, Markdown, CSV, and text.
  2. Ingest app sources: records from Slack, Jira, Notion, Gmail, and other apps.
  3. Wait for indexing: polling until a source is searchable.
  4. Retrieve knowledge: querying what you ingested.
  5. Add metadata for filtering.
  6. Link documents that belong together.
  7. Field reference and common mistakes.

1. Upload files

This request uploads two PDFs. HydraDB accepts PDF, DOCX, Markdown, CSV, and TXT files. The request is multipart/form-data with these fields:
Set up your SDK client before running the Python or TypeScript example.
The response lists each file in data.results with its id and a status of queued. The payload is wrapped in the standard envelope, so read it from response.data:

What each property in document_metadata means

The key list is closed. Any other key, including title, type, url, and timestamp, returns 400.

2. Ingest app sources

When your application already holds the text and fields of a Slack message, a Jira ticket, a Notion page, or a CRM record, send it as an app source instead of a file. HydraDB keeps the app’s structure: the author, the thread, the ticket’s status, and the links between items. See App Sources for every class and a ready-to-use pattern for each app. The request goes to the same endpoint, with app_knowledge in place of documents. One request can carry both. An app source can also carry an acl, the list of people allowed to retrieve it; see Access Control.
The response has the same shape as a file upload, with one entry per app source in data.results.

3. Wait for indexing

Ingestion runs in the background: HydraDB parses each source, splits it into chunks, finds the people, teams, and topics it mentions and how they relate (see Context Graphs), and builds the search indexes. The response returns 202 Accepted with each source’s id. Poll GET /context/status with those ids and the same collection until every source reaches completed or errored.
Each status in the data payload looks like this:
Status values move forward through queued, processing, graph_creation, and completed, or land in errored on failure. A source is already searchable at graph_creation; wait for completed only when you need full graph traversal. Poll every few seconds; most documents complete in 1 to 5 minutes. The full table is on Ingestion Status. If you would rather not poll, register a webhook.

4. Retrieve knowledge

Search with POST /query, using type: "knowledge". Use type: "all" to search a user’s memories in the same call. Both stores are read from the same collection, so if the documents live in their own collection, list it next to the user’s in collections. App sources are searched too; query_apps (on by default) adds thread and link expansion for them. If some documents carry an acl, from a connector or an app source, send the caller’s identity as acl on every query. A query without it ignores those permissions, and a metadata filter does not replace it. See Access Control.
Matching chunks come back in data.chunks, ranked by relevance, each with its source_title and text. See How to Use API Results to turn the response into a prompt, and Query for mode, alpha, and recency_bias.

5. Add metadata for filtering

Metadata is how you bridge structured filters and semantic search. Attach metadata at ingestion, and narrow a query to matching sources with metadata_filters.
On the document_metadata item or app source:
Then at query time:
Declare the metadata keys you filter on in the database metadata schema. A database with a schema rejects undeclared keys at ingest, so a filter on one returns nothing. To filter on additional_metadata, nest the keys under additional_metadata in metadata_filters, for example {"metadata_filters": {"additional_metadata": {"author": "Alice"}}}. document_metadata is accepted only as a legacy alias for that nested filter namespace. See Metadata for schema design, filter examples, and the metadata vs additional_metadata decision rule. See Create Database for the schema field configuration (enable_dense_embedding, enable_sparse_embedding). Forceful relations let you declare links between knowledge sources at ingestion time. When a query matches a source that has forceful relations attached, HydraDB pulls the linked sources into the additional_context field of the query response alongside the primary chunks. This is separate from the context graph HydraDB builds on its own. Forceful relations are declared by you, for documents that belong together when the text does not say so: a contract and its addendum, or a runbook and its troubleshooting guide. They link whole sources. To declare the entity and relation graph within one document, replacing extraction for it, use Bring Your Own Graph. On a file, set relations.ids on its document_metadata item. On an app source, set relations.ids the same way, and name the relationship in app_relations so the link also carries a predicate. relations.ids is what makes the linked text come back with query results; a named relationship alone connects the sources without requesting their text. App Sources covers typed targets in full.
query_forceful_relations defaults to true; set it to false to skip the linked sources.
Knowledge sources, thinking mode only: Forceful relations stay within one store, so pointing a knowledge source at a memory ID silently returns nothing. Linked context is fetched only when mode: "thinking" is set on the query, or when mode: "auto" routes to thinking. In fast mode, query_forceful_relations is ignored even if set to true.

Field reference

App sources accept title, url, and timestamp.

Common mistakes