- Text syntax — SQL-like, human-readable
- JSON wire format — canonical format used by the Noetive API
Query structure
A query has one required clause and three optional modifiers:Clauses
DISTANCE
Nearest-neighbor sphere in embedding space. Matches messages whose embedding is at least as similar to the anchor as thewithin floor you set.
within is a similarity floor, not a distance ceiling. A message matches when its similarity to the anchor is at least within, so a higher value is stricter. WITHIN 0.9 is near-exact; WITHIN 0.3 lets almost everything through. Values above 1.0 are rejected.within or top_k. If neither is set, the clause acts as a scoring signal without a hard threshold.
DIRECTION
Cone search in embedding space. Matches messages aligned with one or more concept directions, regardless of distance from the origin.
When
toward is an array, the direction vector is the normalized mean of all embedded concepts.
CONTRAST
Attract/repel vector arithmetic. Matches messages semantically close to the attract concepts and far from the repel concepts.
The composite vector is
normalize(mean(embed(attract)) − mean(embed(repel))). With repel absent it is normalize(mean(embed(attract))).
Boolean composition
Combine clauses withAND, OR, and NOT. Use parentheses to control precedence.
NOT narrows a result set but cannot say where to look, so a query whose top level is a bare NOT is rejected. Pair it with a positive clause, as above.
What subscribe rejects
/v1/subscribe accepts a narrower query set than /v1/search: any use of TOP returns 400 invalid_request.
TOP ranks a message against the others in a result set. A stream has no result set, since each message is scored on its own as it is published, so the clause has no meaning there and is refused rather than quietly ignored. Use WITHIN to set a score floor instead.
The query is legal SemQL, so /v1/lint reports it as valid. This restriction belongs to the subscribe endpoint, not to the language.
Subscribe also refuses a query that would match every message, since that delivers the namespace’s entire stream rather than a subscription. In practice a query that constrains nothing — an empty toward or attract list — is already rejected as invalid SemQL before it reaches that check.
Modifiers
NAMESPACE
Restates the namespace the query was written for, so the server can check it. Scope itself comes from thenamespace field in the request body — that field is required, it is what your API key is authorized against, and there is no default to fall back on. See Namespaces. NAMESPACE does not change where a query runs; it declares where the query expects to run, and the request is refused with 400 invalid_request if the two disagree.
That is worth having when a query outlives the call site: a query stored in a config file, generated by an agent, or copied between environments carries its intended namespace with it, and sending it against the wrong one fails immediately instead of quietly answering from somewhere else.
Namespace names match exactly — wildcards are not supported.
Selecting several namespaces is not supported yet. Multiple names,
NOT exclusions and ALL are valid SemQL, so /v1/lint parses them, but /v1/search and /v1/subscribe reject them with 400 invalid_request. They are refused rather than ignored: a clause written to exclude a namespace must never return the messages it was meant to leave out.To search several namespaces today, issue one request per namespace and merge the results yourself. Note that each namespace pins its own embedding model and dimensionality, so scores are only comparable across namespaces configured identically.WINDOW
Restricts results to messages published within a time window ending now."P7D", "PT48H", "PT30M".
LIMIT
Caps the number of results returned. Defaults to 100 when omitted, and is clamped to a maximum of 1000. A larger value succeeds and returns 1000 rather than failing. See Limits.Anchors
An anchor is the reference point for a clause. Two forms are accepted: Natural language string — the broker embeds it automatically:toward list of a DIRECTION clause, or either list of a CONTRAST clause. Anchor text across the whole query is capped at 4 KB, and vector anchors at 8192 floats. Over any of these, the query is rejected before anything is embedded. Full table in Limits.
Duration format
The text parser accepts both formats. The JSON serializer always emits ISO 8601.
Full examples
Reserved words
Grammar reference
EBNF grammar
EBNF grammar

