> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hydradb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Memory

> Ingest user memories – preferences, conversation history, or inline text.

## When to use it

Use this endpoint to store user-specific context that personalizes recall:

* **Preferences** – "User prefers dark mode and detailed technical explanations"
* **Conversation history** – chat messages between the user and your agent
* **User notes** – markdown snippets, settings, profile data

For documents, files, and app-generated content, use [`POST /ingestion/upload_knowledge`](/api-reference/endpoint/upload-knowledge) instead.

## Endpoint

* **Auth:** Bearer token
* **Idempotency:** Controlled by `upsert` (default `true` – overwrites existing items with the same `source_id`)
* **Async:** Yes – memories are queued for processing. Use [`POST /ingestion/verify_processing`](/api-reference/endpoint/verify-processing) to check status.

<Warning>
  For memories, `metadata` and `additional_metadata` are plain JSON objects. Do not pre-stringify them.
</Warning>

## Example

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl -X POST 'https://api.hydradb.com/memories/add_memory' \
    -H "Authorization: Bearer <your_api_key>" \
    -H "Content-Type: application/json" \
    -d '{
      "tenant_id": "my_first_tenant",
      "memories": [
        {
          "text": "User prefers detailed technical explanations and dark mode",
          "infer": true,
          "user_name": "Alex",
          "metadata": {"team": "engineering"},
          "additional_metadata": {"source": "onboarding"}
        }
      ]
    }'
  ```

  ```typescript TypeScript SDK theme={"dark"}
  const response = await client.upload.addMemory({
    tenant_id: "my_first_tenant",
    memories: [
      {
        text: "User prefers detailed technical explanations and dark mode",
        infer: true,
        user_name: "Alex",
        metadata: { team: "engineering" },
        additional_metadata: { source: "onboarding" }
      }
    ]
  });
  ```

  ```python Python SDK theme={"dark"}
  response = client.upload.add_memory(
      tenant_id="my_first_tenant",
      memories=[
          {
              "text": "User prefers detailed technical explanations and dark mode",
              "infer": True,
              "user_name": "Alex",
              "metadata": {"team": "engineering"},
              "additional_metadata": {"source": "onboarding"},
          }
      ],
  )
  ```
</CodeGroup>

## Request parameters

| Name            | Type    | Required | Description                                                                             |
| --------------- | ------- | -------- | --------------------------------------------------------------------------------------- |
| `tenant_id`     | string  | Yes      | The tenant to ingest into.                                                              |
| `memories`      | array   | Yes      | One or more `MemoryItem` objects. See [Memory item](#memory-item) below.                |
| `sub_tenant_id` | string  | No       | Sub-tenant scope. If omitted, the default sub-tenant is used.                           |
| `upsert`        | boolean | No       | Default `true`. If `true`, existing memories with the same `source_id` are overwritten. |

## Memory item

Each entry in the `memories` array supports three content formats. Pick one:

### Format 1 – Plain text

```json theme={"dark"}
{
  "text": "User prefers dark mode",
  "infer": true
}
```

### Format 2 – Markdown

```json theme={"dark"}
{
  "text": "# Notes\n\n- Prefers dark mode\n- Likes detailed explanations",
  "is_markdown": true,
  "infer": true
}
```

### Format 3 – Conversation pairs

```json theme={"dark"}
{
  "user_assistant_pairs": [
    { "user": "I work mostly at night", "assistant": "Got it, I'll remember that." },
    { "user": "And I prefer concise answers", "assistant": "Understood." }
  ],
  "infer": true,
  "user_name": "Alex"
}
```

## All MemoryItem fields

| Name                   | Type    | Default  | Description                                                                                                           |
| ---------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `text`                 | string  | –        | Raw text or markdown content. Use with Formats 1 or 2.                                                                |
| `user_assistant_pairs` | array   | –        | Conversation pairs. Use with Format 3.                                                                                |
| `is_markdown`          | boolean | `false`  | Set `true` if `text` is markdown.                                                                                     |
| `infer`                | boolean | `false`  | If `true`, HydraDB extracts implicit insights from the content. See [Inference modes](#inference-modes).              |
| `source_id`            | string  | auto     | Unique identifier. Auto-generated if omitted.                                                                         |
| `title`                | string  | –        | Display title for this memory.                                                                                        |
| `user_name`            | string  | `"User"` | User's name. Useful for personalizing conversation pairs.                                                             |
| `expiry_time`          | integer | –        | Optional TTL in seconds. The memory is deleted after this duration.                                                   |
| `custom_instructions`  | string  | –        | Custom instructions to guide inference processing.                                                                    |
| `metadata`             | object  | `{}`     | Tenant-level key-value metadata (plain JSON object).                                                                  |
| `additional_metadata`  | object  | `{}`     | Document-level key-value metadata (plain JSON object).                                                                |
| `relations`            | object  | –        | Forcefully connect this memory to other sources. See [Forceful relations](/essentials/memories#7-forceful-relations). |

## Inference modes

The `infer` flag controls how HydraDB processes content:

* **`infer: true`** – HydraDB extracts implicit preferences, insights, and entities from the text. Best for conversation history and free-form user notes where you want HydraDB to derive structured signals.
* **`infer: false`** (default) – Content is chunked and indexed as-is. Best for content that should be stored verbatim, like preset profile fields or raw notes.

<Info>
  **Always set `infer` explicitly.** The default is `false`. If you're storing conversational content and expect HydraDB to extract preferences, you must set `infer: true`.
</Info>

## Response

```json theme={"dark"}
{
  "success": true,
  "message": "Memories queued for ingestion successfully",
  "results": [
    {
      "source_id": "1d50e5cd7c196a2bbcc1a59b037b3a44",
      "title": null,
      "status": "queued",
      "infer": true,
      "error": null
    }
  ],
  "success_count": 1,
  "failed_count": 0
}
```

| Field                 | Description                                                                   |
| --------------------- | ----------------------------------------------------------------------------- |
| `success`             | `true` if at least one memory was queued.                                     |
| `message`             | Human-readable status.                                                        |
| `results`             | Per-memory ingestion result.                                                  |
| `results[].source_id` | The ID assigned to this memory. Use this to track processing or delete later. |
| `results[].status`    | Initial status. One of `queued`, `processing`, `completed`, `failed`.         |
| `results[].infer`     | Whether inference was requested for this memory.                              |
| `success_count`       | Number of memories successfully queued.                                       |
| `failed_count`        | Number of memories that failed to queue.                                      |

## Behavior notes

<Info>
  **Processing is asynchronous.** This endpoint returns immediately after queuing. To verify a memory is fully indexed, poll [`POST /ingestion/verify_processing`](/api-reference/endpoint/verify-processing) with the returned `source_id` until status is `completed`.
</Info>

<Info>
  **Sub-tenants are created implicitly.** If you pass a `sub_tenant_id` that doesn't exist, HydraDB creates it automatically on first use. There is no separate sub-tenant creation endpoint.
</Info>

## Related endpoints

* **Next:** [Verify processing](/api-reference/endpoint/verify-processing) – check ingestion status
* **Next:** [Recall preferences](/api-reference/endpoint/recall-preferences) – retrieve memories
* **Related:** [Delete memory](/api-reference/endpoint/delete-memory) – remove individual memories
* **Alternative:** [Upload knowledge](/api-reference/endpoint/upload-knowledge) – for documents and app knowledge instead of user memories

## Errors

Common codes: `400 INVALID_PARAMETERS`, `404 TENANT_NOT_FOUND`, `422 VALIDATION_ERROR`. See [Error Responses](/api-reference/error-responses) for the full list.

Read more: [Essentials → Memories](/essentials/memories) · [Essentials → Metadata](/essentials/metadata)


## OpenAPI

````yaml POST /memories/add_memory
openapi: 3.1.0
info:
  title: HydraDB API
  description: REST APIs for the HydraDB retrieval engine
  version: 0.0.1
servers:
  - url: https://api.hydradb.com
    description: Production
    x-fern-server-name: hydradb-prod
security: []
paths:
  /memories/add_memory:
    post:
      tags:
        - Memories
      summary: Add memory
      operationId: add_memory_memories_add_memory_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Body_add_memory_memories_add_memory_post'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AddMemoryResponse'
        '400':
          description: Bad Request - Invalid input parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
        '401':
          description: Unauthorized - Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
        '403':
          description: Forbidden - Access denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
        '404':
          description: Not Found - Resource does not exist
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
        '422':
          description: Unprocessable Entity - Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
        '503':
          description: Service Unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActualErrorResponse'
      security:
        - HTTPBearer: []
components:
  schemas:
    Body_add_memory_memories_add_memory_post:
      properties:
        memories:
          items:
            $ref: '#/components/schemas/MemoryItem'
          type: array
          minItems: 1
          title: Memories
          description: List of memory items to ingest
          example: []
        tenant_id:
          type: string
          title: Tenant Id
          description: Unique identifier for the tenant/organization
          example: tenant_1234
        sub_tenant_id:
          type: string
          title: Sub Tenant Id
          description: >-
            Optional sub-tenant identifier used to organize data within a
            tenant. If omitted, the default sub-tenant created during tenant
            setup will be used.
          default: ''
          example: sub_tenant_4567
        upsert:
          type: boolean
          title: Upsert
          description: If true, update existing sources with the same source_id.
          default: true
          example: true
      type: object
      required:
        - memories
        - tenant_id
      title: Body_add_memory_memories_add_memory_post
    AddMemoryResponse:
      properties:
        success:
          type: boolean
          title: Success
          default: true
          example: true
        message:
          type: string
          title: Message
          default: Memories queued for ingestion successfully
        results:
          items:
            $ref: '#/components/schemas/MemoryResultItem'
          type: array
          title: Results
          description: List of results for each ingested memory item.
          example: []
        success_count:
          type: integer
          title: Success Count
          description: Number of items successfully queued for ingestion.
          default: 0
          example: 1
        failed_count:
          type: integer
          title: Failed Count
          description: Number of items that failed to queue.
          default: 0
          example: 1
      type: object
      title: AddMemoryResponse
      description: Response model for add_memory endpoint.
    ActualErrorResponse:
      properties:
        detail:
          $ref: '#/components/schemas/ErrorResponse'
      type: object
      required:
        - detail
      title: ActualErrorResponse
    MemoryItem:
      properties:
        source_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Source Id
          description: Optional unique identifier. Auto-generated if not provided.
        title:
          anyOf:
            - type: string
            - type: 'null'
          title: Title
          description: Display title for this memory item.
        text:
          anyOf:
            - type: string
            - type: 'null'
          title: Text
          description: Raw text or markdown content to be indexed.
          examples:
            - |-
              # Introduction

              This is the document content.
        user_assistant_pairs:
          anyOf:
            - items:
                $ref: '#/components/schemas/UserAssistantPair'
              type: array
            - type: 'null'
          title: User Assistant Pairs
          description: Array of user/assistant conversation pairs to store as memory.
        is_markdown:
          type: boolean
          title: Is Markdown
          description: Whether the text is markdown formatted.
          default: false
          example: true
        infer:
          type: boolean
          title: Infer
          description: >-
            If true, process and extract additional insights/inferences from the
            contentbefore indexingUseful for extracting implicit information
            from conversations
          default: false
          example: true
        custom_instructions:
          anyOf:
            - type: string
            - type: 'null'
          title: Custom Instructions
          description: Custom instructions to guide inference processing.
        user_name:
          type: string
          title: User Name
          description: User's name for personalization in conversation pairs.
          default: User
          example: John Doe
        expiry_time:
          anyOf:
            - type: integer
            - type: 'null'
          title: Expiry Time
          description: Optional TTL in seconds for this memory.
        tenant_metadata:
          anyOf:
            - type: string
            - type: 'null'
          title: Tenant Metadata
          description: >+
            JSON string containing tenant-level document metadata (e.g.,
            department, compliance_tag)


            Example: > "{"department":"Finance","compliance_tag":"GDPR"}"

          default: ''
        document_metadata:
          anyOf:
            - type: string
            - type: 'null'
          title: Document Metadata
          description: >+
            JSON string containing document-specific metadata (e.g., title,
            author, file_id). If file_id is not provided, the system will
            generate an ID automatically.


            Example: > "{"title":"Q1 Report.pdf","author":"Alice
            Smith","file_id":"custom_file_123"}"


          default: ''
        relations:
          anyOf:
            - $ref: '#/components/schemas/ForcefulRelationsPayload'
            - type: 'null'
          description: >-
            Forcefully connect 2 sources based on HydraDB source IDs or common
            properties.
      type: object
      title: MemoryItem
      description: |-
        Represents a single memory item for ingestion.
        Supports raw text, markdown, and user/assistant conversation pairs.
    MemoryResultItem:
      properties:
        source_id:
          type: string
          title: Source Id
          description: Unique identifier for the ingested source.
          example: <source_id>
        title:
          anyOf:
            - type: string
            - type: 'null'
          title: Title
          description: Title of the memory if provided.
        status:
          $ref: '#/components/schemas/SourceStatus'
          description: Initial processing status.
          default: queued
        infer:
          type: boolean
          title: Infer
          description: Whether inference was requested for this memory.
          default: false
          example: true
        error:
          anyOf:
            - type: string
            - type: 'null'
          title: Error
          description: Error message if ingestion failed.
      type: object
      required:
        - source_id
      title: MemoryResultItem
      description: Result for a single ingested memory item.
    ErrorResponse:
      properties:
        success:
          type: boolean
          title: Success
          default: false
        message:
          type: string
          minLength: 1
          title: Message
          default: Error occurred
        error_code:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Code
      type: object
      title: ErrorResponse
    UserAssistantPair:
      properties:
        user:
          type: string
          title: User
          description: User's message in the conversation
          example: <user>
        assistant:
          type: string
          title: Assistant
          description: Assistant's response to the user message
          example: <assistant>
      type: object
      required:
        - user
        - assistant
      title: UserAssistantPair
      description: Represents a user-assistant conversation pair.
    ForcefulRelationsPayload:
      properties:
        hydradb_source_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: HydraDB Source Ids
          description: HydraDB source IDs to forcefully relate to the uploaded source.
        properties:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Properties
          description: Optional properties to attach to the forceful relation.
      type: object
      title: ForcefulRelationsPayload
    SourceStatus:
      type: string
      enum:
        - queued
        - processing
        - completed
        - failed
      title: SourceStatus
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````