> ## Documentation Index
> Fetch the complete documentation index at: https://danswer-docs-versions-opensearch-example.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Handle Send Chat Message

> This endpoint is used to send a new chat message.

Args:
    chat_message_req (SendMessageRequest): Details about the new chat message.
        - When stream=True (default): Returns StreamingResponse with SSE
        - When stream=False: Returns ChatFullResponse with complete data
    request (Request): The current HTTP request context.
    user (User): The current user, obtained via dependency injection.
    _ (None): Rate limit check is run if user/group/global rate limits are enabled.

Returns:
    StreamingResponse | ChatFullResponse: Either streams or returns complete response.

<Info>
  **Required permission:** Chat — Write (`write:chat`), which `basic` includes, so any signed-in user has it.
  A limited [Personal Access Token](/developers/overview#personal-access-tokens) needs the Chat — Write scope.
  A service account in no group also holds it. Anonymous users can call this when anonymous access is enabled.
</Info>

<Note>
  **Multi-model requests must stream.** Passing `llm_overrides` with more than one entry runs the models in parallel and
  requires `stream=true`; combining it with `stream=false` returns `400 {"error_code": "INVALID_INPUT"}`.
  A single-entry `llm_overrides` list is ignored — use `llm_override` for an ordinary single-model override.
</Note>


## OpenAPI

````yaml POST /chat/send-chat-message
openapi: 3.1.0
info:
  title: Onyx API
  description: Onyx API for AI-powered enterprise search and chat
  version: Development
servers:
  - url: https://cloud.onyx.app/api
security: []
paths:
  /chat/send-chat-message:
    post:
      tags:
        - public
      summary: Handle Send Chat Message
      description: |-
        This endpoint is used to send a new chat message.

        Args:
            chat_message_req (SendMessageRequest): Details about the new chat message.
                - When stream=True (default): Returns StreamingResponse with SSE
                - When stream=False: Returns ChatFullResponse with complete data
            request (Request): The current HTTP request context.
            user (User): The current user, obtained via dependency injection.
            _ (None): Rate limit check is run if user/group/global rate limits are enabled.

        Returns:
            StreamingResponse | ChatFullResponse: Either streams or returns complete response.
      operationId: handle_send_chat_message
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessageRequest'
      responses:
        '200':
          description: |-
            If `stream=true`, returns `text/event-stream`.
            If `stream=false`, returns `application/json` (ChatFullResponse).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatFullResponse'
            text/event-stream:
              schema:
                type: string
              examples:
                stream:
                  summary: Stream of NDJSON AnswerStreamPart's
                  value: string
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - BearerAuth: []
components:
  schemas:
    SendMessageRequest:
      properties:
        message:
          type: string
          title: Message
        llm_override:
          anyOf:
            - $ref: '#/components/schemas/LLMOverride'
            - type: 'null'
        llm_overrides:
          anyOf:
            - items:
                $ref: '#/components/schemas/LLMOverride'
              type: array
            - type: 'null'
          title: Llm Overrides
          description: >-
            Two or three LLM overrides to run in parallel (multi-model mode),
            one entry per model. Requires `stream=true`: a request carrying more
            than one entry with `stream=false` is rejected with a 400
            `INVALID_INPUT` error. A list with a single entry is ignored — use
            `llm_override` to change the model for an ordinary single-model
            request.
        allowed_tool_ids:
          anyOf:
            - items:
                type: integer
              type: array
            - type: 'null'
          title: Allowed Tool Ids
        forced_tool_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Forced Tool Id
        file_descriptors:
          items:
            $ref: '#/components/schemas/FileDescriptor'
          type: array
          title: File Descriptors
          default: []
        internal_search_filters:
          anyOf:
            - $ref: '#/components/schemas/BaseFilters'
            - type: 'null'
        deep_research:
          type: boolean
          title: Deep Research
          default: false
        mcp_headers:
          anyOf:
            - additionalProperties:
                type: string
              type: object
            - type: 'null'
          title: Mcp Headers
          description: >-
            Headers forwarded to MCP tool calls made while answering this
            message, e.g. `{"Authorization": "Bearer <user_jwt>", "X-User-ID":
            "user123"}`. Use this to pass end-user credentials through to MCP
            servers that require them.
        origin:
          $ref: '#/components/schemas/MessageOrigin'
          default: unset
        parent_message_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Parent Message Id
          default: -1
        chat_session_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Chat Session Id
        chat_session_info:
          anyOf:
            - $ref: '#/components/schemas/ChatSessionCreationRequest'
            - type: 'null'
        stream:
          type: boolean
          title: Stream
          default: true
        include_citations:
          type: boolean
          title: Include Citations
          default: true
        additional_context:
          anyOf:
            - type: string
            - type: 'null'
          title: Additional Context
          description: >-
            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 the chat history. 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. Pass null or omit the field to use
            no additional context.
      type: object
      required:
        - message
      title: SendMessageRequest
    ChatFullResponse:
      properties:
        answer:
          type: string
          title: Answer
        answer_citationless:
          type: string
          title: Answer Citationless
        pre_answer_reasoning:
          anyOf:
            - type: string
            - type: 'null'
          title: Pre Answer Reasoning
        tool_calls:
          items:
            $ref: '#/components/schemas/ToolCallResponse'
          type: array
          title: Tool Calls
          default: []
        top_documents:
          items:
            $ref: '#/components/schemas/SearchDoc'
          type: array
          title: Top Documents
        citation_info:
          items:
            $ref: '#/components/schemas/CitationInfo'
          type: array
          title: Citation Info
        message_id:
          type: integer
          title: Message Id
        chat_session_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Chat Session Id
        incognito:
          type: boolean
          title: Incognito
          default: false
        error_msg:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Msg
      type: object
      required:
        - answer
        - answer_citationless
        - top_documents
        - citation_info
        - message_id
      title: ChatFullResponse
      description: Complete non-streaming response with all available data.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    LLMOverride:
      properties:
        model_configuration_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Model Configuration Id
        model_provider:
          anyOf:
            - type: string
            - type: 'null'
          title: Model Provider
        model_version:
          anyOf:
            - type: string
            - type: 'null'
          title: Model Version
        temperature:
          anyOf:
            - type: number
            - type: 'null'
          title: Temperature
        display_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Display Name
      type: object
      title: LLMOverride
      description: >-
        Per-request LLM settings that override persona defaults.


        All fields are optional — only the fields that differ from the persona's

        configured LLM need to be supplied. Used both over the wire (API
        requests)

        and for multi-model comparison, where one override is supplied per
        model.


        Attributes:
            model_configuration_id: Exact model configuration to use. Preferred
                over the name-based fields — provider display names are not
                unique, so only the id routes unambiguously.
            model_provider: LLM provider display name. When ``None``, the
                persona's default provider is used.
            model_version: Specific model version string (e.g. ``"gpt-4o"``).
                When ``None``, the persona's default model is used.
            temperature: Sampling temperature in ``[0, 2]``. When ``None``, the
                persona's default temperature is used.
            display_name: Human-readable label shown in the UI for this model,
                e.g. ``"GPT-4 Turbo"``. Optional; falls back to ``model_version``
                when not set.
    FileDescriptor:
      properties:
        id:
          type: string
          title: Id
        type:
          $ref: '#/components/schemas/ChatFileType'
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
        user_file_id:
          anyOf:
            - type: string
            - type: 'null'
          title: User File Id
      type: object
      required:
        - id
        - type
      title: FileDescriptor
      description: >-
        NOTE: is a `TypedDict` so it can be used as a type hint for a JSONB
        column

        in Postgres
    BaseFilters:
      properties:
        source_type:
          anyOf:
            - items:
                $ref: '#/components/schemas/DocumentSource'
              type: array
            - type: 'null'
          title: Source Type
        document_set:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Document Set
        created_at_range:
          anyOf:
            - $ref: '#/components/schemas/TimeRange'
            - type: 'null'
        updated_at_range:
          anyOf:
            - $ref: '#/components/schemas/TimeRange'
            - type: 'null'
        tags:
          anyOf:
            - items:
                $ref: '#/components/schemas/Tag'
              type: array
            - type: 'null'
          title: Tags
        time_cutoff:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Time Cutoff
      type: object
      title: BaseFilters
    MessageOrigin:
      type: string
      enum:
        - webapp
        - chrome_extension
        - api
        - slackbot
        - widget
        - discordbot
        - mobile
        - unknown
        - unset
      title: MessageOrigin
      description: Origin of a chat message for telemetry tracking.
    ChatSessionCreationRequest:
      properties:
        persona_id:
          type: integer
          title: Persona Id
          default: 0
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
        project_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Project Id
        incognito:
          type: boolean
          title: Incognito
          default: false
        incognito_session_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Incognito Session Id
      type: object
      title: ChatSessionCreationRequest
    ToolCallResponse:
      properties:
        tool_name:
          type: string
          title: Tool Name
        tool_arguments:
          additionalProperties: true
          type: object
          title: Tool Arguments
        tool_result:
          type: string
          title: Tool Result
        search_docs:
          anyOf:
            - items:
                $ref: '#/components/schemas/SearchDoc'
              type: array
            - type: 'null'
          title: Search Docs
        generated_images:
          anyOf:
            - items:
                $ref: '#/components/schemas/GeneratedImage'
              type: array
            - type: 'null'
          title: Generated Images
        pre_reasoning:
          anyOf:
            - type: string
            - type: 'null'
          title: Pre Reasoning
      type: object
      required:
        - tool_name
        - tool_arguments
        - tool_result
      title: ToolCallResponse
      description: Tool call with full details for non-streaming response.
    SearchDoc:
      properties:
        document_id:
          type: string
          title: Document Id
        chunk_ind:
          type: integer
          title: Chunk Ind
        semantic_identifier:
          type: string
          title: Semantic Identifier
        link:
          anyOf:
            - type: string
            - type: 'null'
          title: Link
        blurb:
          type: string
          title: Blurb
        source_type:
          $ref: '#/components/schemas/DocumentSource'
        boost:
          type: integer
          title: Boost
        hidden:
          type: boolean
          title: Hidden
        metadata:
          additionalProperties:
            anyOf:
              - type: string
              - items:
                  type: string
                type: array
          type: object
          title: Metadata
        score:
          anyOf:
            - type: number
            - type: 'null'
          title: Score
        is_relevant:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Relevant
        relevance_explanation:
          anyOf:
            - type: string
            - type: 'null'
          title: Relevance Explanation
        match_highlights:
          items:
            type: string
          type: array
          title: Match Highlights
        updated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Updated At
        primary_owners:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Primary Owners
        secondary_owners:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Secondary Owners
        is_internet:
          type: boolean
          title: Is Internet
          default: false
        file_id:
          anyOf:
            - type: string
            - type: 'null'
          title: File Id
      type: object
      required:
        - document_id
        - chunk_ind
        - semantic_identifier
        - blurb
        - source_type
        - boost
        - hidden
        - metadata
        - match_highlights
      title: SearchDoc
    CitationInfo:
      properties:
        type:
          type: string
          const: citation_info
          title: Type
          default: citation_info
        citation_number:
          type: integer
          title: Citation Number
        document_id:
          type: string
          title: Document Id
      type: object
      required:
        - citation_number
        - document_id
      title: CitationInfo
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    ChatFileType:
      type: string
      enum:
        - image
        - document
        - plain_text
        - tabular
      title: ChatFileType
    DocumentSource:
      type: string
      enum:
        - ingestion_api
        - slack
        - web
        - google_drive
        - gmail
        - github
        - gitbook
        - gitlab
        - guru
        - bookstack
        - outline
        - confluence
        - jira
        - slab
        - productboard
        - file
        - coda
        - canvas
        - notion
        - zulip
        - linear
        - hubspot
        - document360
        - gong
        - google_sites
        - zendesk
        - loopio
        - box
        - dropbox
        - sharepoint
        - teams
        - salesforce
        - discourse
        - axero
        - clickup
        - mediawiki
        - wikipedia
        - asana
        - s3
        - r2
        - google_cloud_storage
        - oci_storage
        - xenforo
        - not_applicable
        - discord
        - freshdesk
        - fireflies
        - egnyte
        - airtable
        - highspot
        - drupal_wiki
        - imap
        - bitbucket
        - testrail
        - braintrust
        - lumapps
        - mock_connector
        - user_file
        - craft_file
      title: DocumentSource
    TimeRange:
      properties:
        start:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Start
        end:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: End
      type: object
      title: TimeRange
      description: |-
        An inclusive [start, end] window; either bound may be None (open).
        Naive (timezone-less) bounds are treated as UTC.
    Tag:
      properties:
        tag_key:
          type: string
          title: Tag Key
        tag_value:
          type: string
          title: Tag Value
      type: object
      required:
        - tag_key
        - tag_value
      title: Tag
    GeneratedImage:
      properties:
        file_id:
          type: string
          title: File Id
        url:
          type: string
          title: Url
        revised_prompt:
          type: string
          title: Revised Prompt
        shape:
          anyOf:
            - type: string
            - type: 'null'
          title: Shape
      type: object
      required:
        - file_id
        - url
        - revised_prompt
      title: GeneratedImage
      description: Represents an image generated by an image generation tool.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: Authorization header with Bearer token

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.