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

# Message

The `Message` class is designed to send, stream, update or remove messages.

## Parameters

<ParamField path="content" type="str">
  The content of the message.
</ParamField>

<ParamField path="author" type="str" optional>
  The author of the message, defaults to the chatbot name defined in your config
  file.
</ParamField>

<ParamField path="elements" type="Element[]" optional>
  Elements to attach to the message.
</ParamField>

<ParamField path="actions" type="Action[]" optional>
  Actions to attach to the message.
</ParamField>

<ParamField path="language" type="str" optional>
  Language of the code if the content is code. See
  [https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages](https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages)
  for a list of supported languages.
</ParamField>

<ParamField path="metadata" type="Dict" optional>
  Custom metadata dictionary to attach to the message. Persisted with the message in the data layer.
</ParamField>

<ParamField path="tags" type="List[str]" optional>
  Tags to attach to the message for filtering and categorization.
</ParamField>

<ParamField path="command" type="str" optional>
  The [command](/concepts/command) selected by the user for this message. Set automatically by the UI when the user picks a command. Access this value in the [on\_message](/api-reference/lifecycle-hooks/on-message) handler via `msg.command`.

  <Note>
    Since version **2.1.0**.
  </Note>
</ParamField>

<ParamField path="modes" type="Dict[str, str]" optional>
  The [modes](/concepts/modes) selected by the user for this message, as a dict of `{mode_id: option_id}`. Set automatically by the UI when the user configures mode pickers. Access this value in the [on\_message](/api-reference/lifecycle-hooks/on-message) handler via `msg.modes`.

  <Note>
    Since version **2.9.4**.
  </Note>
</ParamField>

<ParamField path="id" type="str" optional>
  Unique identifier for the message. Auto-generated as a UUID if not provided.
</ParamField>

<ParamField path="parent_id" type="str" optional>
  ID of the parent step or message. Automatically resolved from the current step context if not provided.
</ParamField>

<ParamField path="type" type="str" default="assistant_message" optional>
  The message type (`assistant_message` or `user_message`). Automatically set based on the message direction.
</ParamField>

<ParamField path="created_at" type="str" optional>
  ISO 8601 timestamp for the message creation. Automatically set to the current UTC time when `.send()` is called.
</ParamField>

## Send a message

Send a new message to the UI.

```python theme={null}
import chainlit as cl


@cl.on_message
async def main(message: cl.Message):
    await cl.Message(
        content=f"Received: {message.content}",
    ).send()
```

## Stream a message

Send a message token by token to the UI.

```python theme={null}
import chainlit as cl

token_list = ["the", "quick", "brown", "fox"]


@cl.on_chat_start
async def main():
    msg = await cl.Message(content="").send()
    for token in token_list:
        await msg.stream_token(token)

    await msg.update()
```

## Update a message

Update a message that already has been sent.

```python theme={null}
import chainlit as cl


@cl.on_chat_start
async def main():
    msg = cl.Message(content="Hello!")
    await msg.send()

    await cl.sleep(2)

    msg.content = "Hello again!"
    await msg.update()
```

## Remove a message

Remove a message from the UI.

```python theme={null}
import chainlit as cl


@cl.on_chat_start
async def main():
    msg = cl.Message(content="Message 1")
    await msg.send()
    await cl.sleep(2)
    await msg.remove()
```
