Skip to content
NeuralRepo
Get Support

Search

GET /api/v1/ideas/search

Searches your unarchived ideas by meaning (default) or by keyword. The two modes are separate engines with separate result shapes — the response tells you which one ran.

ParameterTypeRequiredDefaultDescription
qstringYesSearch query, max 500 characters
modestringNosemantickeyword or semantic; anything else returns 400
limitnumberNo20Clamped to 100. Keyword mode can return up to this
fts_modestringNoorKeyword matching: or, and, or exact
min_scorenumberNo0.2Semantic score floor; overrides your search_threshold setting

There is no offset — search is not paginated. Raise limit instead.

The default mode. The query is embedded, matched against your idea vectors, filtered by score, and then reranked by a second model before being cut to limit.

Terminal window
curl "https://neuralrepo.com/api/v1/ideas/search?q=user+interface+theming" \
-H "X-API-Key: nrp_YOUR_KEY"

Two consequences worth knowing:

  • Results are ordered by the reranker, not by raw score, so scores are not guaranteed to descend down the list.
  • Ideas captured seconds ago may be missing. An idea is only searchable once its queued embedding lands (vectorize_id stops being null).

Only ideas scoring strictly above min_score survive. The default floor is 0.2; your search_threshold user setting replaces it, and an explicit min_score parameter overrides both.

Keyword mode queries the SQLite FTS5 index over titles and bodies, ordered by BM25 rank.

Terminal window
curl "https://neuralrepo.com/api/v1/ideas/search?q=dark+mode&mode=keyword" \
-H "X-API-Key: nrp_YOUR_KEY"

Before matching, the query is lowercased, stripped of punctuation, and split on whitespace. Tokens of one character and common stop words (the, and, for, what, this, and about sixty others) are dropped. A query made entirely of stop words matches nothing"how to do it" reduces to zero tokens and returns an empty array.

fts_mode controls how the surviving tokens are combined:

fts_modeBehaviourdark mode becomes
or (default)Any token matches"dark" OR "mode"
andEvery token must match"dark" "mode"
exactThe raw phrase, quoted; stop words are kept"dark mode"

200 OK

The response echoes the query, reports search_type (semantic or fts), and — in keyword mode — the fts_mode that ran.

{
"query": "user interface theming",
"search_type": "semantic",
"results": [
{
"id": 137,
"number": 42,
"title": "Add dark mode support",
"body": "Users have requested a dark theme...",
"status": "exploring",
"source": "web",
"source_url": null,
"is_archived": 0,
"tags": ["ui", "feature-request"],
"score": 0.92,
"created_at": "2026-03-20 10:00:00",
"updated_at": "2026-03-22 14:30:00"
}
]
}
Modescore
ftsAlways null — the BM25 rank orders the rows but is not returned
semanticCosine similarity between the query and the idea embedding

Free accounts get 10 semantic searches per calendar month. Once they are spent, the endpoint serves keyword results instead and says so:

{
"query": "user interface theming",
"search_type": "fts",
"fts_mode": "or",
"results": [],
"semantic_limit_reached": true,
"semantic_limit_message": "You've used all 10 semantic searches this month. Showing keyword results instead. Upgrade to Pro for unlimited semantic search."
}

Three details that surprise people:

  • The counter is incremented before the search runs, so a search that errors or matches nothing still costs one of the ten.
  • mode=keyword requests are free and never touch the counter.
  • The count resets on the first of the month; the underlying counter is stored per account-month with a 35-day expiry.

Pro accounts have no semantic-search limit. Both plans have unlimited keyword search.

Keyword (mode=keyword)Semantic (default)
EngineSQLite FTS5, BM25 rankVector index + reranker
Matches exact wordsYesNot necessarily
Finds conceptual matchesNoYes
Needs an embeddingNo — searchable immediatelyYes — after the queue processes the idea
Returns a scoreNo (null)Yes
Respects limitReturns up to 2×Yes
Free-plan limitNone10 per month
StatusMeaning
200 OKSearch completed — including when results is empty
400 Bad RequestMissing q, or a mode other than keyword/semantic
401 UnauthorizedMissing or invalid auth