Search

Hybrid retrieval — lexical, dense and structure, RRF-fused and reranked — over the active World.

What Search runs against

Search runs against the active version. A workspace with no activated World returns nothing rather than falling back to a candidate — an answer from a version nobody accepted is not a smaller answer, it is a different one.

The pipeline, source by source

Three retrieval sources run concurrently over the World's compiled index: lexical full-text, dense vectors, and structure (claim and entity overlap with what the query already matched). Their ranks are fused with reciprocal rank fusion — ranks only, so native scores from different scoring spaces never mix — then reranked, then filtered by the World Gate, which admits a region only if it belongs to your tenant, to the active world version, and is bound to evidence.

The fields that say what ran

FieldWhat it tells you
retrievalPathAlways compiled-retrieval-v1. Search has no excerpt fallback — see the table on the Ask page for what the other value means and where it can appear.
degradationsA named list of what did not run. Empty means every source ran.
retrieval.lexicalCandidates / denseCandidates / structureCandidatesHow many candidates each source returned before fusion.
retrieval.rerankerAppliedFalse means the fused order was returned as-is.
retrieval.gateRejectionsRegions the World Gate refused, with the reason.
freshnessThe four timestamps and the awaiting-activation flag described on the Ask page.

A degradation is reported, never hidden. dense retrieval skipped: no embedder configured means the answer came from lexical and structure alone; a reranker outage returns the fused order and says so. Reading degradations is how you tell a full-pipeline result from a partial one — the two otherwise look identical.

When there is no compiled index

Note Search requires a compiled retrieval index for the active World. Without one the response is 409 with the code RETRIEVAL_RUN_NOT_FOUND (or RETRIEVAL_PROFILE_NOT_FOUND), carrying retrievalIndex and retrievalNotice to say which state the index is in. It is not a 200 with fewer results: Search has no fallback, and a weaker answer presented as the real one is worse than a refusal you can act on. POST /v1/collections/{id}/retrieval-index rebuilds the index. It takes the collections:compile scope, the owner or admin role, and the same plan bar activating a World takes: Team, or Developer held by the workspace owner. The two bars are identical on purpose — this endpoint is the recovery path for an activation whose index did not compile, so a plan that may activate and may not rebuild would leave its own Worlds answering from the fallback with nothing to call.

POST/collections/{id}/searchScope ask:read

Retrieval-only search over the active World's compiled retrieval index: hybrid lexical + dense + structure retrieval, RRF-fused, reranked, then World Gate filtered. Returns the ContextPacket (the same runtime contract /ask, MCP and the CLI share) plus per-source retrieval telemetry, without generating an answer. There is no excerpt fallback here -- a World with no queryable compiled index is a 409, not a weaker answer. Read `degradations` before comparing two results: a full-pipeline result and a partial one otherwise look identical.

curl -sS -X POST https://tavonel.com/api/v1/collections/{id}/search \
  -H "Authorization: Bearer $TAVONEL_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "query": "<query>", "limit": 1 }'
Request body
{
  "query": "<query>",
  "limit": 1
}
StatusResponse
200{ code, retrievalPath, contextPacket, degradations, retrieval, activeWorld, freshness }. The contextPacket carries the evidence-bound retrieval units with their lexical, dense and structure ranks, the reranker score and the World Gate decisions; retrieval carries the per-source candidate counts and gateRejections. retrievalPath is always compiled-retrieval-v1. degradations is a named list of what did not run — dense retrieval skipped with no embedder configured, or the reranker degrading to the fused order — and reading it is how a full-pipeline result is told from a partial one, because the two otherwise look identical.
400QUERY_INVALID — The search query was absent, or shorter than the minimum. COLLECTION_ID_INVALID — The collection id did not match collection-<32 hex>. INVALID_JSON — The body was not parseable JSON.
401AUTH_REQUIRED — No credential was presented, or the bearer token is not a key TAVONEL issued. This is what an unauthenticated request to any scoped route returns.
403API_SCOPE_REQUIRED — The key authenticated and does not carry the scope this operation requires. The request was refused rather than answered with less. PILOT_ACCESS_REQUIRED — The credential is valid and the workspace it names is not admitted to TAVONEL.
409RETRIEVAL_RUN_NOT_FOUND — The active World has no completed retrieval compile run, so there is no queryable index. Search has no fallback — a weaker answer presented as the real one is worse than a refusal you can act on. RETRIEVAL_PROFILE_NOT_FOUND — The retrieval profile the index was compiled against is not registered. ACTIVE_WORLD_NOT_FOUND — Nothing has been activated for this collection, so there is no World to read, index or answer from. A candidate nobody accepted is not a smaller answer — it is a different one.
413QUERY_TOO_LARGE — The search query exceeded 500 characters.
429API_RATE_LIMITED — The key has used its per-minute allowance for this scope. The window is a fixed clock minute per key and scope; the allowances are on /docs/billing-and-limits.
503ACTIVE_WORLD_STORE_UNAVAILABLE — The World store could not be reached.

Rebuilding the index

Rebuilding is a no-op that returns alreadyCompiled: true when a completed run for that World version already exists, so it is safe to call before a search rather than only after one fails. The manifest comes from the active pointer, which is why this cannot index a candidate nobody activated. A rebuild that does not reach a queryable index answers 503 with RETRIEVAL_INDEX_NOT_COMPILED and the failure class in retrievalIndex.errorClass — never a 200 over a half-built index, because half an index is not a smaller index.

POST/collections/{id}/retrieval-indexScope collections:compile

Compiles the retrieval index for the collection's ACTIVE World, and is a no-op returning alreadyCompiled: true when a completed run for that World version already exists. The manifest comes from the active pointer, so this cannot index a candidate nobody activated. Requires the workspace owner or admin role in addition to the scope, and the same plan bar activating a World takes. A rebuild that does not reach a queryable index answers 503 with RETRIEVAL_INDEX_NOT_COMPILED and the failure class in retrievalIndex.errorClass -- never 200.

curl -sS -X POST https://tavonel.com/api/v1/collections/{id}/retrieval-index \
  -H "Authorization: Bearer $TAVONEL_API_KEY"
StatusResponse
200The index state after the run. alreadyCompiled: true means nothing was recompiled.
400COLLECTION_ID_INVALID — The collection id did not match collection-<32 hex>.
401AUTH_REQUIRED — No credential was presented, or the bearer token is not a key TAVONEL issued. This is what an unauthenticated request to any scoped route returns.
402STUDIO_SUBSCRIPTION_REQUIRED — The operation needs the higher plan tier — activation, rollback and retrieval-index rebuild are the three.
403RETRIEVAL_COMPILE_ROLE_REQUIRED — Rebuilding the retrieval index needs the workspace owner or admin role, on top of the scope. API_SCOPE_REQUIRED — The key authenticated and does not carry the scope this operation requires. The request was refused rather than answered with less. PILOT_ACCESS_REQUIRED — The credential is valid and the workspace it names is not admitted to TAVONEL.
404NOT_FOUND — The addressed resource does not exist in this workspace. Deliberately uniform across tenants: the same answer for an id that is not yours and an id that is nobody's.
409ACTIVE_WORLD_NOT_FOUND — Nothing has been activated for this collection, so there is no World to read, index or answer from. A candidate nobody accepted is not a smaller answer — it is a different one.
429ACTIVATION_RATE_LIMITED — The workspace has used its hour's allowance of World activations, rollbacks or retrieval-index rebuilds. Nothing was charged.
503RETRIEVAL_INDEX_NOT_COMPILED — A rebuild did not reach a queryable index. retrievalIndex.errorClass names the failure class. Never answered as a 200. RETRIEVAL_COMPILE_NO_UNITS — The World produced no retrievable units, so there was nothing to index. RETRIEVAL_COMPILE_EMBEDDING_PROVIDER_FAILED — The embedding provider failed during the rebuild. RETRIEVAL_COMPILE_SOURCE_BINDING_UNRESOLVED — A retrieval unit cited a source version that could not be resolved, so the index was refused rather than compiled with a dangling citation. ACTIVATION_RATE_LIMIT_UNAVAILABLE — That hourly allowance could not be read, so the request was refused rather than run unbounded.

API version 2026-09-02.1 · reviewed 11 September 2026

Something here out of date or wrong? Report an issue with this page.