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

# Send a Message to Onyx

> Sending messages programmatically to Onyx

<Note>
  We recommend you migrate any usage of `/chat/send-message` and `/chat/send-message-simple-api` to this new API by
  February 1st, 2026.
</Note>

The `/chat/send-chat-message` API is used to send a message to Onyx.
It is the same API that the Onyx frontend uses to send and receive messages.
You have the option of receiving a streaming response or the complete response as a string.

This guide was explain all of the parameters you can pass in to the API and provide a code sample.

## Request Parameters

| Parameter            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message`            | The user message to send to the Agent.                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `llm_override`       | Pass an object to override the default LLM settings for this request. If `None`, you will get the default Onyx behavior. <br /><br />You can pass or exclude any of the following fields: <br />• `model_provider` <br />• `model_version` <br />• `temperature` <br /><br />If you pass an invalid configuration (e.g., specifying `claude-sonnet-4.5` when the default `model_provider` is OpenAI), your request will fail.                           |
| `allowed_tool_ids`   | Agents are created with a set of Actions they are allowed to invoke. You can further configure this set for your immediate interaction using this parameter. See the list of Actions and their IDs via the [GET /tool](/developers/api_reference/actions/list_tools) endpoint. Pass in an empty list to disable all Actions. Pass in `None` to allow all the Actions which are configured for the Agent.                                                |
| `forced_tool_id`     | Force the Agent to use a specific Action for this request. The Agent may run other Actions before returning its final response, but it will be guaranteed to use this one. Leave empty to let the Agent decide which Actions to use.                                                                                                                                                                                                                    |
| `file_descriptors`   | A list of files to include along with your request. File IDs can be found via the [POST /user/projects/file/upload](/developers/api_reference/projects/upload_user_files) and the [GET /user/projects/file/{file_id}](/developers/api_reference/projects/get_user_file) endpoints.                                                                                                                                                                      |
| `search_filters`     | Filters to narrow down the internal search results used by the Agent. All filter arguments are optional and can be combined: <br /><br />• `source_type` – Source types like `web`, `slack`, `google_drive`, `confluence` <br />• `document_set` – The name of the document sets to search within <br />• `time_cutoff` – ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ` <br />• `tags` – Format: `{"tag_key": "tag_value"}`                                   |
| `deep_research`      | Enables Deep Research mode for this request. <br /><br />**Note:** This mode consumes significantly more tokens, so be careful accessing it via the API.                                                                                                                                                                                                                                                                                                |
| `parent_message_id`  | The ID of the parent message in the chat history (primary-key for the previous message in the chat history tree). If not passed in, your new message is assumed to be sequentially after the last message. <br /><br />**Warning:** If set to `None`, the chat history is reset and the new message is considered the first message in the chat history.                                                                                                |
| `chat_session_id`    | To continue an existing conversation, pass in the chat session ID where the message should be sent. If left blank, a new chat session will be created according to `chat_session_info`.                                                                                                                                                                                                                                                                 |
| `chat_session_info`  | Details about the chat session which will be used for all messages in the session. Fields can be left blank to use defaults. <br /><br />• `persona_id` – The ID of the Agent to use for the chat session <br />• `project_id` – ID of a Project if the chat should be scoped to a Project                                                                                                                                                              |
| `stream`             | If true, responds with an SSE stream of individual packets (same set used for the Onyx UI). Fields like the Answer, reasoning tokens, and iterative Tool Calls need to be pieced together from streamed tokens.                                                                                                                                                                                                                                         |
| `include_citations`  | If true, responses will include citations for the sources used to generate the answer.                                                                                                                                                                                                                                                                                                                                                                  |
| `additional_context` | A string of extra context injected into the LLM call for this request. The context is passed to the model but is **not stored in the database** and will not appear in chat history.<br />Use this to supply ephemeral, request-scoped information (e.g. the user's current page URL, session metadata, or any runtime context) without polluting the persistent conversation history.<br />Pass `null` or omit the field to use no additional context. |

## Response Format

### Streaming Response

Onyx returns various types of packets in the streaming response depending on the LLM's behavior.

See our
[streaming\_models.py](https://github.com/onyx-dot-app/onyx/blob/main/backend/onyx/server/query_and_chat/streaming_models.py)
on GitHub for the complete list of packet types and their corresponding fields.

```python expandable theme={null}
class StreamingType(Enum):
    """Enum defining all streaming packet types."""

    SECTION_END = "section_end"
    STOP = "stop"
    TOP_LEVEL_BRANCHING = "top_level_branching"
    ERROR = "error"

    MESSAGE_START = "message_start"
    MESSAGE_DELTA = "message_delta"
    SEARCH_TOOL_START = "search_tool_start"
    SEARCH_TOOL_QUERIES_DELTA = "search_tool_queries_delta"
    SEARCH_TOOL_DOCUMENTS_DELTA = "search_tool_documents_delta"
    OPEN_URL_START = "open_url_start"
    OPEN_URL_URLS = "open_url_urls"
    OPEN_URL_DOCUMENTS = "open_url_documents"
    IMAGE_GENERATION_START = "image_generation_start"
    IMAGE_GENERATION_HEARTBEAT = "image_generation_heartbeat"
    IMAGE_GENERATION_FINAL = "image_generation_final"
    PYTHON_TOOL_START = "python_tool_start"
    PYTHON_TOOL_DELTA = "python_tool_delta"
    CUSTOM_TOOL_START = "custom_tool_start"
    CUSTOM_TOOL_DELTA = "custom_tool_delta"
    REASONING_START = "reasoning_start"
    REASONING_DELTA = "reasoning_delta"
    REASONING_DONE = "reasoning_done"
    CITATION_INFO = "citation_info"

    DEEP_RESEARCH_PLAN_START = "deep_research_plan_start"
    DEEP_RESEARCH_PLAN_DELTA = "deep_research_plan_delta"
    RESEARCH_AGENT_START = "research_agent_start"
    INTERMEDIATE_REPORT_START = "intermediate_report_start"
    INTERMEDIATE_REPORT_DELTA = "intermediate_report_delta"
    INTERMEDIATE_REPORT_CITED_DOCS = "intermediate_report_cited_docs"
```

### Non-streaming Response

```python theme={null}
class ChatFullResponse(BaseModel):
    """Complete non-streaming response with all available data."""

    # Core response fields
    answer: str
    answer_citationless: str
    pre_answer_reasoning: str | None = None
    tool_calls: list[ToolCallResponse] = []

    # Documents & citations
    top_documents: list[SearchDoc]
    citation_info: list[CitationInfo]

    # Metadata
    message_id: int
    chat_session_id: UUID | None = None
    error_msg: str | None = None
```

## Sample Request

<CodeGroup>
  ```python Python expandable theme={null}
  import requests

  API_BASE_URL = "https://cloud.onyx.app/api"  # or your own domain
  API_KEY = "YOUR_KEY_HERE"

  headers = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json"
  }

  response = requests.post(
      f"{API_BASE_URL}/chat/send-chat-message",
      headers=headers,
      json={
          "message": "What is Onyx?",
      }
  )

  data = response.json()
  print("Answer:", data["answer"])
  print("Message ID:", data["message_id"])
  ```

  ```bash Shell expandable theme={null}
  #!/bin/bash

  API_BASE_URL="https://cloud.onyx.app/api"  # or your own domain
  API_KEY="YOUR_KEY_HERE"

  RESPONSE=$(curl -s -X POST "${API_BASE_URL}/chat/send-chat-message" \
    -H "Authorization: Bearer ${API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{
      "message": "What is Onyx?"
    }'
  )

  echo "Answer:" $(echo "$RESPONSE" | jq -r '.answer')
  echo "Message ID:" $(echo "$RESPONSE" | jq -r '.message_id')
  ```
</CodeGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Guide: Use the Ingestion API" icon="upload" href="/developers/guides/index_files_ingestion_api">
    Use the lightweight ingestion API to index documents
  </Card>

  <Card title="Guide: Create a Connector" icon="link" href="/developers/guides/create_connector">
    Learn how to create and configure Connectors programmatically
  </Card>
</CardGroup>
