The two types work the same way. Both go to
POST /context/ingest, both are saved in a collection, both are indexed in the background, and both come back from POST /query. Each item you ingest is a source; HydraDB splits it into searchable passages called chunks and builds a context graph from it.
They are stored separately, so a query chooses what to read: type: "knowledge", type: "memory", or type: "all" for both in one ranked list. A support agent, for example, answers from the help center (knowledge) and from the fact that this customer already tried restarting (a memory).
1. Ingest knowledge
There are three ways to ingest knowledge:- Files: upload PDF, DOCX, Markdown, CSV, or TXT files, and HydraDB reads them for you.
- App sources: send records your application already holds 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.
Upload files
The request is multipart/form-data with these fields:Upload files: Python, TypeScript, or cURL
Upload files: Python, TypeScript, or cURL
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:document_metadata item takes these properties:
The key list is closed. Any other key, including
title, type, url, and timestamp, returns 400. Ingest Context lists the supported file formats.
Send 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 records. The request goes to the same endpoint, withapp_knowledge in place of documents. One request can carry both. kind says what the record is (email, message, ticket, knowledge_base, comment, meeting, or custom), and fields carries its content. An app source can also carry an acl, the list of principals allowed to retrieve it. The field reference lists the keys each kind takes in fields.
Ingest a Slack message: Python, TypeScript, or cURL
Ingest a Slack message: Python, TypeScript, or cURL
data.results.2. Save memories
HydraDB does not capture memories on its own: your application saves one when a user states a preference, makes a decision, finishes a task, or corrects the agent. Give each user their own collection, such asuser_john_123, and send it on every ingest, status check, and query. Your backend picks it from the signed-in session; the name itself does not authenticate anyone.
The request is the same as for knowledge, with type=memory and a memories list in place of files:
Save a memory: Python, TypeScript, or cURL
Save a memory: Python, TypeScript, or cURL
Set up your SDK client before running the Python or TypeScript example.The response lists each memory 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:Let HydraDB infer the memory
infer controls whether HydraDB extracts the memory from what you send or stores it as written.
custom_instructions takes effect only when infer: true. Use it to guide extraction, for example: "Focus on UI and notification preferences only".
Infer a preference from a behavior log: Python, TypeScript, or cURL
Infer a preference from a behavior log: Python, TypeScript, or cURL
A user has been toggling dark mode in your application. Instead of extracting the preference yourself, send the raw behavior log and let HydraDB infer the memory.Later, when
POST /query runs with type: "memory" and a query like "what UI settings does the user prefer?", HydraDB can return the inferred preference (for example, "prefers dark mode") rather than the raw event log.If you sent the same input with infer: false, HydraDB would index the event log verbatim. That is useful only when you want to retrieve the log itself.Send text or a conversation
Each memory item takes eithertext or user_assistant_pairs, not both (sending both returns 400).
text: prose of any kind, such as observations, captured facts, meeting notes, or semi-structured records. Setis_markdown: truewhen the content uses Markdown (headings, lists, code blocks) so HydraDB keeps that structure during chunking and embedding.user_assistant_pairs: dialogue, especially when the preference is implied rather than stated. Each pair is{ "user": "...", "assistant": "..." }.
Input shapes: text, Markdown, and user-assistant pairs
Input shapes: text, Markdown, and user-assistant pairs
Markdown notes, stored as written:A plain statement, with the preference extracted:A conversation, with the preference extracted:
3. Wait for indexing
Knowledge and memories are indexed the same way, in the background: HydraDB parses each source, splits it into chunks, infers the memory if you asked it to, finds the people, teams, and topics it mentions and how they relate, and builds the search indexes. The ingest request returns202 Accepted with each source’s id.
Poll GET /context/status with those ids and the same collection every few seconds. A source’s indexing_status moves forward through queued, processing, graph_creation, and completed, or lands in errored on failure:
- At
graph_creationthe source becomes searchable within a few seconds, while its graph is still building. A query sent the moment this status appears can miss the source, and a collection that is new can still be reported as not existing. - At
completedthe source and its graph are ready. Wait forcompletedwhen you query straight after ingesting. Most documents complete in 1 to 5 minutes.
Poll until indexed: Python, TypeScript, or cURL
Poll until indexed: Python, TypeScript, or cURL
data payload looks like this:4. Query knowledge and memories together
POST /query reaches each type through the type parameter:
type: "knowledge"(the default) searches files and app sources.type: "memory"searches memories.type: "all"searches both and returns one merged, ranked list.
collections. If some sources carry an acl, also send the caller’s identity as acl. Query covers the other parameters and how to pass the result to a model.
5. Update or delete context
To change a source or a memory, send it again with the sameid. upsert defaults to true, so the saved one is replaced; include everything you want to keep. Wait for the previous ingestion to reach completed or errored before sending the next update for the same id.
To remove one, call DELETE /context with its id and the same collection.
6. Link sources that belong together
Forceful relations are links you declare between knowledge sources when you ingest them. When a query matches a source that has forceful relations, HydraDB returns the linked sources in theadditional_context field of the response, alongside the primary chunks.
This is separate from the context graph HydraDB builds on its own. Use forceful relations 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.
Link a runbook to its troubleshooting guide: Python, TypeScript, or cURL
Link a runbook to its troubleshooting guide: Python, TypeScript, or cURL
This Notion guide links to a troubleshooting page already ingested with the HydraDB
id auth-troubleshooting. Ingest that page first and wait for completed.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
Ingest request fields
Ingest request fields
App source fields by kind
App source fields by kind
Set
kind on the app source and repeat it as fields.kind. Every other key in fields is optional.Memory item fields
Memory item fields
memories is a JSON string. Inside each item, metadata and additional_metadata are plain objects; do not stringify them again.Common mistakes
Related
- Query: search context and pass the result to a model
- Databases and Collections: where context is saved, and how to keep users apart
- Metadata Filters: fields to filter on
- Connectors: keep an app’s knowledge in sync
- Ingest Context: API Reference
