# Search API

Query a loaded database with `GET /api/search`, and understand the deprecated single-strategy routes.

## Search

```http
GET /api/search?db=notes&q=what+is+RAG&limit=5
```

### Query parameters

| Parameter | Required | Default | Behavior |
|---|---|---|---|
| `db` | Yes | — | Selects a currently loaded database |
| `q` | Yes | — | Exact query text used by the selected strategies |
| `limit` | No | `10` | Result-row limit per strategy; valid values are 1–100 |
| `target` | No | Both | Use `keyword` or `semantic` to select one branch; matched case-insensitively |

An absent, non-numeric, non-positive, or greater-than-100 `limit` falls back to 10.

### Combined response

With no `target`, KuraDB runs both branches concurrently:

```json
{
  "keyword": [
    {
      "source": "/Users/example/.config/kuradb/notes/inbox/rag.md",
      "matches": [
        {
          "chunk": 1,
          "content": "RAG combines retrieval with generation."
        }
      ]
    }
  ],
  "semantic": [
    {
      "source": "/Users/example/.config/kuradb/notes/inbox/rag.md",
      "matches": [
        {
          "chunk": 1,
          "content": "RAG combines retrieval with generation."
        }
      ]
    }
  ]
}
```

A selected-out branch is omitted rather than returned as `null`. A selected branch with no matches is returned as an empty array. Grouping and the fields each match exposes are described in [Errors and Contract](/api-reference-errors#api-response-contract).

### Keyword target

```http
GET /api/search?db=notes&q=vector+cache&target=keyword
```

The query is tokenized with gse, normalized to lowercase, deduplicated, and matched against active SQLite rows. Ranking uses matched-token count followed by row ID. A query that produces no tokens returns an empty array rather than an error. See [Search and Retrieval](/search-and-retrieval) for the full keyword path.

### Semantic target

```http
GET /api/search?db=notes&q=vector+cache&target=semantic
```

KuraDB obtains a 512-dimensional query embedding from cache or OpenAI, searches the in-memory vector bucket, removes hits below cosine score 0.3, then hydrates active rows from SQLite. See [Semantic Search](/search-and-retrieval-semantic) for the two-stage ranking.

## Compatibility routes

These routes invoke the same search handler with a fixed target:

```http
GET /api/keyword?db=notes&q=vector+cache&limit=5
GET /api/semantic?db=notes&q=vector+cache&limit=5
```

The fixed target overrides any `target` query parameter. They remain available to avoid breaking Agenvoy, but are marked for removal in v1. New consumers should use `/api/search`.
