> ## Documentation Index
> Fetch the complete documentation index at: https://cortex-e852fafe-t3code-rewrite-docs-declutter.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Save a user preference, retrieve it, and prepare it for your AI model.

Save a preference for `user_123`, search it, and use it in a model prompt. You will create a **database** (a separate workspace for your data) and write to a **collection** (a named group inside it) for this user.

## Install and initialize

Get an API key from [app.hydradb.com](https://app.hydradb.com), then set it in the terminal where you run the examples:

```bash theme={"dark"}
export HYDRA_DB_API_KEY="your_api_key"
```

Choose Python, TypeScript, or cURL and keep using that tab below. For TypeScript, use a Node.js project that supports top-level `await`. The cURL examples also require `jq` to read JSON responses. Install the SDK with the command shown in its tab; keep the initialized `client` for the next step.

<CodeGroup>
  ```python Python SDK theme={"dark"}
  # Install: pip install "hydradb-sdk>=2,<3"
  import os
  from hydra_db import HydraDB
  from hydra_db.helpers import build_string

  client = HydraDB(token=os.environ["HYDRA_DB_API_KEY"])
  ```

  ```typescript TypeScript SDK theme={"dark"}
  // Install: npm install @hydradb/sdk@^2
  import { HydraDBClient } from "@hydradb/sdk";
  import { buildString } from "@hydradb/sdk/helpers";

  const client = new HydraDBClient({
    token: process.env.HYDRA_DB_API_KEY!,
  });
  ```

  ```bash cURL theme={"dark"}
  # Confirm your key works by listing databases.
  curl 'https://api.hydradb.com/databases' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "API-Version: 2"
  ```
</CodeGroup>

***

## Save and retrieve a memory

Use an unused database name, or skip the create call if you already have a database. Writing the memory creates `user_123` automatically. Checking **indexing** means waiting until HydraDB has processed the memory and made it searchable.

<CodeGroup>
  ```python Python SDK theme={"dark"}
  import json, time

  database = "my_first_database"
  collection = "user_123"

  # 1. Create a database.
  client.databases.create(database=database)

  # 2. Wait until the database can accept data.
  while True:
      infra = client.databases.status(database=database).data.infra
      if infra.ready_for_ingestion:
          break
      time.sleep(5)

  # 3. Save one memory in the user's collection.
  ingest = client.context.ingest(
      type="memory",
      database=database,
      collection=collection,
      memories=json.dumps([
          {"text": "User prefers detailed technical explanations and dark mode"}
      ]),
  )

  id = ingest.data.results[0].id

  # 4. Wait until the memory is indexed.
  while True:
      status = client.context.status(
          database=database,
          collection=collection,
          ids=[id],
      ).data.statuses[0]

      if status.indexing_status == "completed":
          break
      if status.indexing_status == "errored":
          raise RuntimeError(status.error_message)

      time.sleep(2)

  # 5. Search memories.
  results = client.query(
      database=database,
      collection=collection,
      type="memory",
      query="What does the user prefer?",
  )

  print(build_string(results))
  ```

  ```typescript TypeScript SDK theme={"dark"}
  const database = "my_first_database";
  const collection = "user_123";

  // 1. Create a database.
  await client.databases.create({ database: database });

  // 2. Wait until the database can accept data.
  while (true) {
    const { data } = await client.databases.status({ database: database });
    if (data?.infra?.readyForIngestion) break;
    await new Promise((resolve) => setTimeout(resolve, 5_000));
  }

  // 3. Save one memory in the user's collection.
  const ingest = await client.context.ingest({
    type: "memory",
    database: database,
    collection: collection,
    memories: JSON.stringify([
      { text: "User prefers detailed technical explanations and dark mode" },
    ]),
  });

  const id = ingest.data?.results?.[0]?.id;
  if (!id) throw new Error("Ingestion returned no memory ID");

  // 4. Wait until the memory is indexed.
  while (true) {
    const status = (await client.context.status({
      database: database,
      collection: collection,
      ids: [id],
    })).data?.statuses?.[0];
    if (!status) throw new Error("Memory status is missing");

    if (status.indexingStatus === "completed") break;
    if (status.indexingStatus === "errored") {
      throw new Error(status.errorMessage ?? "Memory indexing failed");
    }

    await new Promise((resolve) => setTimeout(resolve, 2_000));
  }

  // 5. Search memories.
  const results = await client.query({
    database: database,
    collection: collection,
    type: "memory",
    query: "What does the user prefer?",
  });

  console.log(buildString(results));
  ```

  ```bash cURL theme={"dark"}
  export HYDRA_DB_API_KEY="your_api_key"
  DATABASE="my_first_database"
  COLLECTION="user_123"

  # 1. Create a database.
  curl -s -X POST 'https://api.hydradb.com/databases' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "API-Version: 2" \
    -H "Content-Type: application/json" \
    -d "{\"database\":\"${DATABASE}\"}"

  # 2. Wait until the database can accept data.
  until curl -s "https://api.hydradb.com/databases/status?database=${DATABASE}" \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "API-Version: 2" \
    | jq -e '.data.infra.ready_for_ingestion' > /dev/null; do
    sleep 5
  done

  # 3. Save one memory in the user's collection.
  ID=$(curl -s -X POST 'https://api.hydradb.com/context/ingest' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "API-Version: 2" \
    -F "type=memory" \
    -F "database=${DATABASE}" \
    -F "collection=${COLLECTION}" \
    -F 'memories=[{"text":"User prefers detailed technical explanations and dark mode"}]' \
    | jq -r '.data.results[0].id')

  # 4. Wait until the memory is indexed.
  while true; do
    STATUS=$(curl -s -G 'https://api.hydradb.com/context/status' \
      -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
      -H "API-Version: 2" \
      --data-urlencode "database=${DATABASE}" \
      --data-urlencode "collection=${COLLECTION}" \
      --data-urlencode "ids=${ID}")

    INDEXING_STATUS=$(echo "$STATUS" | jq -r '.data.statuses[0].indexing_status')

    if [ "$INDEXING_STATUS" = "completed" ]; then break; fi
    if [ "$INDEXING_STATUS" = "errored" ]; then
      echo "$STATUS" | jq -r '.data.statuses[0].error_message'
      exit 1
    fi

    sleep 2
  done

  # 5. Search memories.
  curl -s -X POST 'https://api.hydradb.com/query' \
    -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
    -H "API-Version: 2" \
    -H "Content-Type: application/json" \
    --data-binary @- <<EOF | jq -r '.data.chunks[].chunk_content'
  {
    "database": "${DATABASE}",
    "collection": "${COLLECTION}",
    "type": "memory",
    "query": "What does the user prefer?"
  }
  EOF
  ```
</CodeGroup>

***

## Check the result

The query returns passages from your saved memory, not a generated answer. The SDK examples print formatted context; cURL prints the passage text. Both should include the preference you stored:

```text theme={"dark"}
User prefers detailed technical explanations and dark mode
```

The same `collection` on ingest, status, and query keeps the steps pointed at `user_123`. Your backend must select the collection for the authenticated user; the name itself does not authenticate them.

## Use the memory in a model prompt

Continue from the `results` above. The SDK helper formats the returned passages and any relationships into a string, which you can add to the messages you send to your model:

<CodeGroup>
  ```python Python SDK theme={"dark"}
  messages = [
      {"role": "system", "content": "Use these saved preferences when answering:\n" + build_string(results)},
      {"role": "user", "content": "How should I set up my editor?"},
  ]
  ```

  ```typescript TypeScript SDK theme={"dark"}
  const messages = [
    { role: "system", content: "Use these saved preferences when answering:\n" + buildString(results) },
    { role: "user", content: "How should I set up my editor?" },
  ];
  ```
</CodeGroup>

Send `messages` to the chat model your application uses. It now has the user's preferences available when answering the editor question. For raw HTTP response formatting and complete model-call examples, see [How to Use API Results](/essentials/v2/api-results).

Database creation and indexing run in the background, which is why the example waits for both. When adding more data, reuse the database and save each user's memories in their own collection.

## Where to go next

| If you want to… | Read… |
| - | - |
| Understand how content gets stored and retrieved | [Architecture](/essentials/v2/architecture) |
| Tune query behavior (`alpha`, `mode`, `recency_bias`) | [Query](/essentials/v2/query) |
| Design a filterable metadata schema | [Metadata](/essentials/v2/metadata) |
| Scope data per user or workspace | [Multi-Tenant](/essentials/v2/multi-tenant) |
| Turn query results into a model prompt | [How to Use API Results](/essentials/v2/api-results) |
| See the full endpoint reference | [API Reference](/api-reference/v2) |
| Pick from real-world recipes | [Cookbooks](/cookbooks/v2/index) |

Stuck? Reach out at [founders@hydradb.com](mailto:founders@hydradb.com).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.