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 (a content hash 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 a slice rather than a ranking — this kind, this field, this value — that is /query below. Ranked retrieval and exact predicates are different tools, and Nicia will not pretend one is the other by accepting a filter it cannot apply.

When you want exact answers over typed fields 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": { "role": "VP Platform" },
"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"
}
}

where filters on fields, and it is exact by construction. A scalar is equality; { "has": … } matches one element of a string_list field. Every predicate you send is AND-ed, up to eight of them:

{
"kind": "person",
"where": { "role": "VP Platform", "regions": { "has": "emea" } },
"limit": 50
}

has is element equality, not substring: { "has": "emea" } matches the list ["emea", "apac"] and does not match "emea-north". Nothing is normalized either — no case folding, no trimming — because an answer that depends on a rule you cannot see is not an exact answer.

Exact is the whole vocabulary. There is no range, no or, no ordering, and no traversal over links; a where carrying one is a 400 naming the field rather than a page that silently came back empty. Filter what the Brain can filter, sort on your side.

Only declared fields are queryable. Anything you sent that the schema does not declare is still stored and still returned on the record — it just cannot be filtered on until you declare it, and a predicate against it is that same 400. 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.
  • Populating a table, a dashboard, or a business rule/query.

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 — making a field queryable.