The dashboard, public HTTP API and Python SDK do not accept or evaluate NQL1 queries, and do not list query fields. Capabilities and limits records this boundary.
What a field definition holds
Each field declares the same attributes. Here they are for one built-in field, the spacing between slices:
From that definition,
source.spacing.z:<=0.5 is a well-formed filter on the field, in millimetres. The execution row marks it unavailable and not executable, which is the subject of Discoverable is not executable.
Types and the operators they admit
The registry sets a field’s operators from its type and cardinality:
Three consequences are easy to miss:
- A list field does not admit
!=, andNOT field:valueis not a replacement: it also selects records with no value. To require a value and exclude one, writehas:field AND NOT field:value. Whether an empty list counts as a value is not fixed, so that filter does not separate an empty list from a missing one. - No field in the current registry admits prefix (
blade*) or substring (~"blade") filters, although both are part of the language. NOTis not an operator of a field. It applies to a whole filter, so any filter a field admits can be negated.
Where fields come from
Taxonomy fields use the definition bound to the branch you are reading, and the project’s main branch when none is named. Archived options stay valid, so a query can still match historical answers that used them. A Taxonomy Field’s defaults, hints, option names and stored answers are never shown as examples. Taxonomy versions explains how a Taxonomy is bound and versioned.
Metadata fields, from DICOM tags, sidecar files and the normalised
study.protocol, are defined but not executable: Nitsor does not extract controlled metadata from files, so these fields hold no values a query could read.
Discoverable is not executable
In registry terms, a discoverable field is one you may name: it exists in the registry revision, you are allowed to see it, and a filter on it passes the registry’s checks. Whether Nitsor can evaluate a query on it is a separate question, answered by the field’s execution status:
The
executable flag beside the status is the one to act on. A status other than unavailable appears only after the planner has qualified that field, operator and scope. The registry marks every field unavailable and not executable. Separately, Nitsor’s internal Task reader evaluates a limited set of Task filters through its own planner, as Open Tasks in one Stage describes. That reader does not change any field’s execution status.
Treat a definition as a description of the field, never as evidence that a query on it will run. An agent that writes a filter on a discoverable, non-executable field has written valid NQL1, and should say that it cannot be evaluated.
Coverage and counts
Coverage and distinct count are measurements. Each carries a value, a completeness (exact, estimated, lower-bound or unknown) and the time it was measured. unknown with no value means not measured; it is not zero.
Reading field definitions observes no Source, Task or label values and computes no facets or counts. A field’s examples are synthetic format illustrations, never sample data. Do not estimate coverage or a distinct count from the results of a capped read; a capped read is a lower bound at best.
Access and sensitivity
Field definitions are read with permission to browse Sources in the project and read access to the project, including for related families such as labels and Tasks. Access that reaches a Source only through one Task does not open the project’s field list. Some fields are not in the registry. It has no fields about people, such as who holds a Task, and identifying DICOM fields and gold-standard answers never enter it. Asensitive field, such as study.uid or series.uid, records an identifier whose values are never summarised into facets.
A field that does not exist and a field you may not see look the same. A request for either returns an unavailable answer that does not repeat the field name or say why. A request that names several fields returns no fields at all if any one of them is unavailable. Do not try variants of a name to learn which fields exist, and do not infer a hidden field’s name, count or values from a refusal.
Revisions
The registry is versioned. An envelope records theregistryRevision its expression was checked against, and the language version separately. NQL1 itself never changes meaning; a registry revision can add a field, change its operators or remove it from your view.
A query checked against an older registry revision is unsupported until it is checked again against the current one. Re-check it, and if a field it names is now unavailable, report that rather than substituting a similar field.
Read a field before you filter on it
1
Confirm the field is in the registry revision
Use the selector exactly as defined.
meta["machine.name"] and meta.machine.name are different fields.2
Read its type and cardinality
They decide which value kinds and filter forms make sense. A list field takes
ANY(...) and ALL(...); a number field takes comparisons and ranges.3
Check its operators
Write only operators the field lists.
has is listed for every field.4
Read its units
Write numbers in the declared units, without a unit suffix.
5
Check its sensitivity
Do not summarise or repeat the values of a
sensitive field beyond what the task in hand needs.6
Check whether it is executable
If it is not, the filter is valid and cannot be evaluated. Say so instead of reporting an empty result.
Fields used in the examples
The NQL1 pages use some real built-in fields and some synthetic ones. The synthetic names illustrate grammar and are not in the registry.task.waited does not add up waiting across a release and requeue; it measures one stretch from queue entry.
Next step
Query recipes
Apply these definitions to common questions, with what each query selects and where it stops.
Query language (NQL1)
The full language reference: what each query selects, and why the parser refuses one.
| Plans | All plans |
|---|---|
| Last verified | 2026-10-25 |