> ## 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.

## 1. 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>

## 2. 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; in a real application your backend picks the collection for the signed-in user, since the name itself does not authenticate anyone. 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"}
  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>

## 3. 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
```

## 4. 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).

## 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.