vault

Search the workspace vault (hybrid by default)

Natural-language search over the workspace’s evidence notes AND its finished reports.

Just send text. The default mode is hybrid — bm25 over title/body/tags/summary fused with embedding similarity by reciprocal rank, then weighted by each note’s lifecycle and quality grade. A whole question is a fine query; it is sanitised into a safe FTS5 match, so no punctuation, quoting or operator can fail the request. Quoted spans are honoured as phrases (EU "AI Act" enforcement). A blank text is a filtered listing, not an error.

Ask it as a question if you like. The interrogative frame is stripped before anything is embedded or matched — what did the report on agent protocols conclude? retrieves on agent protocols — so a question and its subject find the same notes. A quoted span survives the strip and is still honoured as a phrase.

Scope it. project (or tag), type, status, domain, since/until all narrow the same search. Finished runs’ reports come back as kind: "report" hits by default, above the notes and inside the same limit; repeated runs of one question collapse to the newest, carrying versions. include_reports=false leaves them out.

Then read. A hit’s id is a note id for POST /v1/vault/notes/batch (up to 50 at once) or GET /v1/vault/notes/{id}; a report hit’s run_id is for GET /v1/runs/{id}/result. Cite source_url.

score is relative to the best hit in THIS result set (1.0 = best here), not an absolute confidence. Results are deduplicated server-side: two runs that read the same page are one row. There is no cursor — raise limit (max 200) or narrow the scope.

Hits carry display_tags beside tags, resolved the same way GET /v1/vault/notes resolves them (E2E5-08). snippet is the excerpt to show: the note’s own summary with the source site’s chrome removed — the same text GET /v1/vault/notes returns as display_summary — falling back to the matched window of the stored body, also cleaned, for a note that has no usable summary, and null when neither holds anything but the site’s furniture (E2E16-01).

get/v1/vault/search

Request

  • Base URL: https://api.hyperresearch.ai
  • URL: https://api.hyperresearch.ai/v1/vault/search
  • Auth: one of:
    • HTTP bearer
    • API key in cookie hr_session

Query parameters

textstring
qstring

Alias for text, accepted for core-interface and MCP clients. text wins if both are sent.

mode'fts' | 'semantic' | 'hybrid'

Omit this. The default is hybrid (bm25 + embeddings, reciprocal-rank fused), which is the right answer for a natural-language question and degrades to lexical by itself when the workspace has no embeddings. fts is lexical only and cheaper. semantic is vectors only and fails closed when no embedder is configured.

tagstring

One vault tag. project:<id> is a project’s scope — see GET /v1/projects.

projectstring

A proj_… id, resolved to its project:<id> tag. The readable spelling of tag for the common case; pass one or the other, not both.

statusstring

One note lifecycle: draft|review|evergreen|stale|deprecated|archive.

typestring

One note kind: note|raw|interim|source-analysis|moc|index.

domainstring

Only notes read from this publisher, e.g. eur-lex.europa.eu. A leading dot (.europa.eu) includes subdomains.

sincestring

Only notes created at or after this ISO timestamp (a bare date works).

untilstring

Only notes created at or before this ISO timestamp. Pairs with since to make a range.

include_reports'0' | '1' | 'true' | 'false'

Whether this workspace’s finished run REPORTS are returned as hits alongside the notes, matched on the question each run asked. Default true: the report is the thing the research produced, and a vault search that returns forty of its sources and not the document itself is answering the wrong question. A report hit carries kind: "report", type: "report" and a run_id/report_id to pass to GET /v1/runs/{id}/result; it is NOT a note id and GET /v1/vault/notes/{id} will not resolve it. Report hits sort above notes of equal score and SHARE the limit with them — a page of six is six rows, however they divide. Repeated runs of one question are one row: it is the newest finished run, and versions says how many runs stand behind it (version_group matches the runs API). Reports take at most half the page unless the query itself says "report". Pass include_reports=false to get notes only — the thing to do when every id you receive is going straight to a note endpoint.

rank'relevance' | 'quality'
limitinteger

Rows in the response, notes and reports together (default 20, max 200). The two kinds share this budget; they are not two lists of limit.

Response

Hits

unknown required

Changes

No recorded changes to this operation across all 1 revision of this API.