Skip to content
Beta. This surface may change before GA; breaking changes are dated in the changelog.

Search and queries

/context is the right call for “what should my agent know.” These two are for when you want the raw material instead.

Terminal window
curl "$API/v1/brains/tenant:acme/search?q=sso+redirect+loop&limit=5" \
-H "authorization: Bearer $NICIA_KEY"
{
"data": {
"results": [
{
"source": "zendesk:ticket:8821",
"slug": "brain-evidence-3bb86259c42d0261e0f1cc2d0f7f5f6bb2ee2a9a1cfa8a5b1c5e8a5f0f2a7d31",
"title": "SSO login loop after IdP change",
"excerpt": "Customer reports a redirect loop after switching to Okta…",
"rank": 1,
"version": 3
}
],
"mode": "fulltext",
"staged": 0,
"warnings": [],
"receipt": "rcp_019fff21"
}
}

Search ranks the passages of everything the Brain holds, best match first. Use it to build your own retrieval flow, to show a “sources” panel, or to debug why /context answered the way it did.

rank is a position, not a score: 1 is the best match. Ranking fuses a keyword leg and a semantic leg into an ORDER, and there is no comparable relevance number underneath to hand you. version is the exact document version the passage was cut from, and it is what the receipt records.

source is the id you wrote the document under — the address to act on, and the one that round-trips into GET /documents/{id}. slug is the Brain’s internal address for the page (an opaque hash, derived from the Brain and your document id, for anything written through this API), and it is what lets you line a hit up against a /context citation.

mode is the whole narrowing vocabulary:

mode Ranks by
fulltext (default) Keywords. No embedding round trip, so it is the fast path
hybrid Keywords and meaning, fused — matches phrasings you did not use

The response echoes the mode it actually ranked by. hybrid needs an embedding provider, and a deployment without one answers your hybrid request with keyword ranking rather than failing a read it can still serve — so data.mode comes back fulltext and you can tell a fused answer from a keyword one. Check it before you conclude that semantic matching did not help.

Search takes no filter, exactly like /context. Ranking reads a passage index, and that index knows nothing about your document metadata. When you want exact resolution rather than a ranking — this kind, this slug — that is /query below. One optional indexed linked predicate can narrow to neighbors of a known record first; non-slug field predicates still return 400 index_not_ready. Ranked retrieval and exact address resolution are different tools, and Nicia will not pretend one is the other by accepting a filter it cannot apply.

When you want exact resolution by record address (slug) rather than ranked passages:

Terminal window
curl -X POST "$API/v1/brains/tenant:acme/query" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{
"kind": "person",
"where": { "slug": "bob-smith" },
"limit": 20
}'
{
"data": {
"records": [
{
"id": "bob-smith",
"kind": "person",
"fields": { "name": "Bob Smith", "role": "VP Platform" },
"sources": ["zendesk:ticket:8821"],
"version": 3,
"updatedAt": "2026-08-02T14:20:00Z"
}
],
"staged": 0,
"warnings": [],
"receipt": "rcp_019fff44"
}
}

Today, /query index-resolves exact equality on slug, plus one optional exact linked predicate (one declared link → one kind:identity target). The following is a valid request:

{
"kind": "person",
"where": { "slug": "bob-smith" },
"limit": 50
}

slug equality is literal: no case folding or trimming. Every non-slug-field where predicate — declared or undeclared — returns 400 index_not_ready until a property index ships. A has on slug, or a non-string slug equality, is a type/operator validation error, not that limit. Declaring a field makes it governed vocabulary and preserves and returns its values; it does not make that field filterable. linked is one-hop only: the Brain resolves that indexed edge, then AND-applies where inside the candidate set. There is no range, or, ordering, multi-hop walk, or arbitrary graph traversal. See Schemas.

/query is keyset-paged with an opaque cursor. Its limit may ask for at most 100 records — that is the reader’s page, and a larger one is a 400 rather than a page quietly cut down to size:

Terminal window
curl -X POST "$API/v1/brains/tenant:acme/query" \
-H "authorization: Bearer $NICIA_KEY" \
-H "content-type: application/json" \
-d '{ "kind": "person", "cursor": "eyJrIjoi…" }'
{
"data": {
"records": [],
"staged": 0,
"warnings": [],
"receipt": "rcp_019fff44",
"nextCursor": "eyJrIjoi…"
}
}

Cursors are stable under concurrent writes: a record added mid-walk will not shift the page boundary and cause you to skip one.

/search is not paged. It is a ranked top-N read with no stable cursor to hand out, so it takes a limit of at most 20 and returns the best matches for your query. Ask a narrower question rather than walking a ranking — a cursor here would have served you the same first page over and over.

Search and query both issue receipts, exactly like /context. Anything that shows a customer information can be reconstructed later, whichever endpoint produced it. See Receipts.

  • Putting knowledge in a prompt/context. It selects, budgets, and renders for you.
  • Showing sources, or building your own selection/search.
  • Resolving a known record by slug for a table, dashboard, or rule/query (non-slug field filters return 400 index_not_ready until a property index ships).

If you are reaching for /search to then paste the results into a prompt, use /context with format: "items" instead — you get the same pieces plus the budgeting.

  • Context — the prompt-shaped read.
  • Schemas — governing fields while property indexes are pending.