---
title: "Learn from Context (Ingest Messages)"
method: POST
path: "/v1/modal/learn"
tags: ["v1 modals"]
---

# Learn from Context (Ingest Messages)

`POST /v1/modal/learn`

Ingests a list of messages (conversation history) into long-term memory.
    
    The system automatically handles different modalities embedded in the messages:
    - **Text** is embedded directly
    - **Images/Video** are captioned/described by vision models, then embedded
    - **Audio** is transcribed, then embedded
    
    **Universal Base Params:**
    - user_id (str, required): The user these memories belong to
    - project_id (str, optional): The project bucket (optional)
    - persona_id (str, optional): Link these memories to a specific persona
    
    **Input (Multimodal):**
    - messages (array, required): A standard chat history list. Can contain Text, Image, Video, and Audio.
    - session_id (str, optional): Optional session identifier for conversation context
    
    **Example:**
    ```json
    {
        "user_id": "user_123",
        "project_id": "proj_ABC",
        "session_id": "session_123",
        "messages": [
            {"role": "user", "type": "image", "content": "<base64 encoded image data>"},
            {"role": "assistant","type": "text", "content": "The animation is too slow"},
            {"role": "user", "content": "Good catch. Let's speed it up to 200ms."}
            ],
            "timestamp": "2026-02-07T12:00:00Z"
        }
        ```

## Request body

- LearnRequest — Request model for learning/memory storage processing
  - `user_id` string, required — The user these memories belong to (required)
  - `project_id` string, nullable — The project bucket (optional)
  - `persona_id` string, nullable — Optional persona ID. Link these memories to a specific persona.
  - `messages` LearnMessageItem[], required — A standard chat history list. Can contain Text, Image, Video, and Audio.
    - `role` string, nullable — Message role: 'user', 'assistant', or 'system'
    - `type` string, nullable — Content type for multimodal: 'text', 'image', 'video', 'audio'
    - `content` string, required — Message content or Link
  - `session_id` string, nullable — Optional session identifier for conversation context
  - `timestamp` string, nullable — ISO format datetime string for the message timestamp

## Response `200`

Successful Response

- LearnResponse — Response model for learning processing
  - `session_id` string, required — Session identifier used for the learning
  - `success` boolean — Whether the learning was processed successfully

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `404` — User/Persona/Project Not Found
- `422` — Validation Error
- `500` — Internal Server Error

## Changes

- **2026-02-09** `bb6f89ac9cd3` — 2 breaking, 2 warning, 2 info
  - added the new required request property `messages`
  - removed the required property `message` from the response with the `200` status
  - removed the request property `message`
  - removed the optional property `job_id` from the response with the `200` status
  - …2 more
- **2026-01-21** `1660d0b2cbd9` — 2 info
  - added the new optional request property `persona_id`
  - added the new optional request property `project_id`
- **2025-12-10** `5a9a6b9cb07a` — 1 warning, 11 info
  - removed the request property `datetime_input`
  - added the new optional request property `timestamp`
  - added the non-success response with the status `404`
  - added the optional property `details` to the response with the `400` status
  - …8 more
- **2025-11-17** `826a61027c59` — 1 info
  - endpoint added
- **2025-11-17** `93aa65273d4d` — 1 breaking
  - api path removed without deprecation

[Full history](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/changes/v1/modal/learn/post.md)

---

[API](https://skmtc.dev/elicitlabs/apis/elicit-labs-api.md) · [All operations](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/elicitlabs/elicit-labs-api/revisions/27701839a070/schema)
