curl --request POST \
--url https://ndi-api.nace.ai/v1/workspaces/{workspace_id}/tools/hybrid-search \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"query": "<string>"
}
'{
"candidates_seen": 123,
"coverage": {
"labels_required": [
"<string>"
],
"request_access_hint": "<string>",
"restricted_candidates": 0
},
"hits": [
{
"file_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"path": "<string>",
"relevance_score": 123,
"snippet": "<string>",
"why": "<string>",
"component": "<string>",
"locator": {
"char_end": 123,
"char_start": 123,
"kind": "text_range",
"page": 123,
"pages": [
123
]
},
"page": 123
}
],
"truncated": true
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}hybrid_search
Search the workspace using RRF fusion over lexical and vector legs.
Cost class: medium.
The workspace’s one search method. Combines BM25 keyword matching with
dense-vector semantic similarity via Reciprocal Rank Fusion (RRF), so it
handles both exact-identifier queries (ticker symbols, account codes,
clause numbers) and paraphrase/concept queries in a single call. The
retrieval configuration is fixed server-side at the evaluated-best setting
(see service.SEARCH_LEGS) — there are no per-request retrieval knobs to
tune, and no single-leg variants to choose between.
path_prefix omitted means the whole workspace — there is no all
sentinel to get wrong.
curl --request POST \
--url https://ndi-api.nace.ai/v1/workspaces/{workspace_id}/tools/hybrid-search \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"query": "<string>"
}
'{
"candidates_seen": 123,
"coverage": {
"labels_required": [
"<string>"
],
"request_access_hint": "<string>",
"restricted_candidates": 0
},
"hits": [
{
"file_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"path": "<string>",
"relevance_score": 123,
"snippet": "<string>",
"why": "<string>",
"component": "<string>",
"locator": {
"char_end": 123,
"char_start": 123,
"kind": "text_range",
"page": 123,
"pages": [
123
]
},
"page": 123
}
],
"truncated": true
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}Authorizations
Path Parameters
Workspace identifier.
Body
Request for hybrid-search, the workspace's one search method.
The retrieval configuration (legs, fusion) is fixed server-side — see
tools.service.SEARCH_LEGS — so the body carries only the query and
scope. path_prefix and categories are additive scope filters —
omitting them means the whole workspace.
Response
Successful Response
Response of hybrid-search.
candidates_seen is the pre-access-filter count so the caller can tell
when truncation happened upstream of the access gate.
Every hits[].path is an uploaded source path. Each hit also carries the
ingestion derivative it was actually read from, but those fields are internal
to the host (the agent tools address files that way) and are excluded from this
body — a /v1 caller only ever sees the files it uploaded.
What the access gate withheld, in counts and label names only.
Never a name, path, or fragment of withheld content. Naming the labels leaks nothing the caller cannot already read from the workspace config, and it turns "some results were withheld" into an actionable request.
Show child attributes
Show child attributes
Show child attributes
Show child attributes