database, a separate workspace for a customer or an environment, and collection, an optional group inside a database. Most products need one database and one collection. Your backend sets both on every request; the end user never chooses them.
In this guide:
- Choose how to scope your data: one collection for a company brain, and when to split.
- Write and read with the same scope: one write and one read that name the same collection.
- How writes and reads scope: the default collection, reading several collections, and deleting one.
- Migrate from the legacy tenant and sub-tenant fields:
tenant_id,sub_tenant_id, and the deprecation signals. - Common mistakes and related pages.
1. Choose how to scope your data
Pick the scope by what must never meet in one search:Company brain
Put everything in one collection: connect all your connectors and ingest all your files and app sources there, so one query searches across all of it. When some results must stay out of reach for some people, keep the single collection and isolate inside it. Put a team, region, or user id in metadata and filter on it. Let access control, captured from the source app’s permissions or set by you, decide who may retrieve each document. HydraDB enforces both inside one search.B2C application
Use one database for the application. Keep shared knowledge in one collection, and give each end user a collection for their memories, for examplecollection = "user_123". Write each user’s preferences and conversation history with that collection, and query with the same one.
B2B SaaS
Use one database per customer organization, for exampledatabase = "acme_corp". Inside it, keep the organization’s knowledge in one collection and isolate teams with metadata filters and access control. Give each user a collection only for their memories.
Shared knowledge plus personal memories
For answers grounded in shared knowledge and personalized with the user’s memories, sendtype: "all" on POST /query. It reads both from the same collections and returns one ranked list, so name the knowledge collection and the user’s with collections: ["company_docs", "user_123"]. Every listed collection must already exist, and the list holds up to 100. When your prompt needs the two formatted differently, call POST /query twice, once with type: "knowledge" and once with type: "memory".
2. Write and read with the same scope
This example saves a memory foruser_123 and then runs a search for the same user. Both requests name the database acme_corp and the collection user_123. That is the whole mechanism: data written under a collection is read back only by requests that name that collection.
Save a memory and query it with the same scope: Python, TypeScript, or cURL
Save a memory and query it with the same scope: Python, TypeScript, or cURL
Set up your SDK client before running the Python or TypeScript example.Wait for
GET /context/status to report completed for the returned memory id in user_123, then run the query.What each property means
Use stable internal IDs for both fields, such as
user_123, workspace_42, or org_acme. Display names, emails, and user-typed labels change, and a changed scope name orphans the data written under the old one.
3. How writes and reads scope
Every write and read names adatabase, and may name a collection.
Writes: Send the collection you will query the data from. Omit it to use the database’s default collection. John’s memories go in John’s collection; shared knowledge goes in the shared one.
Reads: A query that names one collection reads only that collection. It does not read the default collection or any other collection. To read several at once, send collections as a list, or as an object that maps each collection to a relative ranking weight, as in {"company_docs": 1.5, "user_123": 0.8}.
Deleting a collection: DELETE /databases/collections permanently removes one collection and everything in it. The parent database and its other collections stay. Confirm the name with List Collections first. On the dashboard, open a database to see its collections and delete from the list.
4. Migrate from the legacy tenant and sub-tenant fields
database and collection are the current names for the fields that were called tenant_id and sub_tenant_id. The rename is user-facing only. Nothing about your stored data changes, the old names still work as deprecated aliases, and migration is optional and non-breaking.
Both names work on every surface:
Both route prefixes use the same handlers. Legacy fields are accepted in the query string, the JSON body, and the multipart form.
The singular
sub_tenant_id still works on /query too. See Query.
Deprecation signals
When a request uses a legacy route or a legacy field, HydraDB adds a migration nudge. It is never an error, and the status code is unchanged:- Response headers:
Deprecation: true, plus aWarningheader carrying the migration message. meta.deprecation: a list of notices in the response envelope’smetaobject, on endpoints that return the envelope. Each entry carriesdeprecated, a readablemessage, anddeprecated_since("2.0.1"). Field-level notices, such assub_tenant_idstocollections, also includedeprecated_fieldandpreferred_field; route-level notices omit them.
Response envelope with a deprecation notice
Response envelope with a deprecation notice
/databases routes, the header and meta.deprecation disappear.
Sending both names
If you send a current field and its deprecated alias together:- Same value: for example
databaseandtenant_idboth"acme". Accepted. HydraDB uses the current field. - Different values: for example
database: "acme"andtenant_id: "other". Rejected with400, because the two names refer to the same thing and must agree. Send only one. The same rule applies tocollectionandsub_tenant_id, and tocollectionsandsub_tenant_idson/query.
Common mistakes
Mismatchedcollection between write and read:
Data written under one collection does not surface when queried under another. Use the same collection for the same logical scope on every call.
Sharing a database across environments:
Do not use one database for both production and staging. Create a database per environment.
Confusing database with collection:
Use database for primary boundaries such as customers or environments. Use collection for partitions inside a database, such as users or workspaces.
Writing shared knowledge under a user scope by accident:
Knowledge written with one user’s collection is invisible to every other user. Choose the write scope from where it should be queried later.
Related
- Memories: preferences, decisions, and past conversations
- Knowledge: shared document context
- Query: how scoping is applied at query time
- Access Control: restricting who can retrieve a document inside a collection
- How to Use API Results: merging query results into a prompt
- Databases API: creating databases and their metadata schema
