---
title: "Handle Send Search Message"
method: POST
path: "/search/send-search-message"
tags: ["public"]
---

# Handle Send Search Message

`POST /search/send-search-message`

Executes a search query with optional streaming.

If hybrid_alpha is unset and ONYX_SEARCH_UI_USES_OPENSEARCH_KEYWORD_SEARCH
is True, executes pure keyword search.

Returns:
    StreamingResponse with SSE if stream=True, otherwise SearchFullResponse.

## Request body

- SendSearchQueryRequest
  - `search_query` string, required — The query to search for.
  - `filters` BaseFilters
    - `source_type` DocumentSource[], nullable
    - `document_set` string[], nullable
    - `created_at_range` TimeRange — An inclusive [start, end] window; either bound may be None (open). Naive (timezone-less) bounds are treated as UTC.
      - `start` string, date-time, nullable
      - `end` string, date-time, nullable
    - `updated_at_range` TimeRange — An inclusive [start, end] window; either bound may be None (open). Naive (timezone-less) bounds are treated as UTC.
      - `start` string, date-time, nullable
      - `end` string, date-time, nullable
    - `tags` Tag[], nullable
      - `tag_key` string, required
      - `tag_value` string, required
    - `time_cutoff` string, date-time, nullable
  - `num_docs_fed_to_llm_selection` integer, nullable — When set to 1 or more, the top N merged sections are handed to an LLM that picks the most relevant ones, and their document ids come back in `llm_selected_doc_ids`. Omit it (or send `null`) to skip LLM selection and the extra LLM call it costs.
  - `run_query_expansion` boolean — When true, an LLM generates extra keyword queries from `search_query`. Every query runs in parallel and the results are merged with weighted reciprocal-rank fusion, with the original query weighted twice as heavily as each expansion. The queries that actually ran come back in `all_executed_queries`. Expansion failures are non-fatal: the original query still runs on its own.
  - `num_hits` integer — Maximum number of merged sections to return.
  - `hybrid_alpha` number, nullable — Balance between vector and keyword matching, from `0.0` (pure keyword) to `1.0` (pure vector). Leave unset to use the deployment's `HYBRID_ALPHA` (`0.5` by default) — except on deployments configured for OpenSearch keyword search, where leaving it unset runs a pure keyword search.
  - `include_content` boolean — When true, each returned document carries the full text of the matched section in `content`. When false, `content` is `null` and only `blurb` is populated.
  - `stream` boolean — When true, responds with a stream of newline-delimited JSON packets. When false (the default), returns the aggregated `SearchFullResponse`.

## Response `200`

If `stream=true`, returns `text/event-stream`.
If `stream=false` (the default), returns `application/json` (SearchFullResponse).

- SearchFullResponse
  - `all_executed_queries` string[], required — Every query that was run, starting with the original. Contains more than one entry only when `run_query_expansion` was set.
  - `search_docs` SearchDocWithContent[], required — Matched sections, most relevant first.
    - `document_id` string, required
    - `chunk_ind` integer, required
    - `semantic_identifier` string, required
    - `link` string, nullable
    - `blurb` string, required
    - `source_type` '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', required
    - `boost` integer, required
    - `hidden` boolean, required
    - `metadata` object, required
    - `score` number, nullable
    - `is_relevant` boolean, nullable
    - `relevance_explanation` string, nullable
    - `match_highlights` string[], required
    - `updated_at` string, date-time, nullable
    - `primary_owners` string[], nullable
    - `secondary_owners` string[], nullable
    - `is_internet` boolean
    - `file_id` string, nullable
    - `content` string, nullable, required
  - `doc_selection_reasoning` string, nullable — Reserved for the LLM's document-selection reasoning. Not currently populated — always `null` on this endpoint.
  - `llm_selected_doc_ids` string[], nullable — Document ids the LLM picked out of `search_docs`. `null` when LLM selection was not requested or failed, an empty list when it ran and chose nothing.
  - `error` string, nullable — Set when the search failed partway through; the other fields hold whatever was gathered before the failure.

## Other responses

- `422` — Validation Error

## Changes

- **2026-09-02** `fcb09658bc37` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/onyx-dot-app/apis/onyx-api/changes/search/send-search-message/post.md)

---

[API](https://skmtc.dev/onyx-dot-app/apis/onyx-api.md) · [All operations](https://skmtc.dev/onyx-dot-app/apis/onyx-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/onyx-dot-app/onyx-api/revisions/fcb09658bc37/schema)
