# Search the notes by their words and, when semantic search is on, by their meaning:

`POST /datanotes/operations/search/` (operation `search`)

Search the notes by their words and, when semantic search is on, by their meaning:
`{query, results: [{path, table?, score, heading, snippet, matched_by}], meaning}`, one result per
note, best first. It always works: with semantic search off it ranks by words alone (BM25:
rare words count more; a word in the note's name or properties counts more), with it on it fuses
both rankings (Reciprocal Rank Fusion), so a note found only by its words or only by its meaning
is still there. `matched_by` says which (`words`, `meaning`); `meaning` is `on`, `off` or `failed`
(the embedding provider failed: words only, `meaning_error` says why). Query syntax as search_docs:
`"a phrase"` and `+word` must appear, `-word` must not (both rankings); words in any language,
case and accents ignored, no stemming. Filters: `tables` (qualified or short names), `folder`,
`min_score` (the meaning ranking's cosine floor). `limit`: default 10, max 100. Then read_note /
select_rows for the details.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `X-Datanotes-View-As` | header | `string` | no | Owner only, on reads only (an operation that only reads, tokens/me/, extensions/, the change stream): the request runs with this named token's permissions and read scope, and the token's last_seen does not change. A named token sending it gets 403; a request that is not a read gets 400. |

## Request body

`application/json`, required

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `query` | `string` | yes |  |  |
| `limit` | `integer` | no | `10` |  |
| `tables` | `string[] \| null` | no | `null` |  |
| `folder` | `string \| null` | no | `null` |  |
| `min_score` | `number \| null` | no | `null` |  |

## Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | Done. | `object` (application/json) |
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
| 500 | Unexpected error. | `Error` (application/json) |

The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
