> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nitsor.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Every page in this documentation carries a `plans` list in its frontmatter and a page-details table naming the plans its content applies to: `All plans`, or a subset of `Community`, `Team` and `Enterprise`. A page limited to some plans also opens with a plan marker naming them.
> Use [Capabilities and limits](/product-status) for capability entitlements and documented availability and limits, and [Plans and billing](/plans-and-billing) for plan pricing and billing policy. Those pages are canonical; do not duplicate their policy values here.
> Reading this documentation grants no product access and no permission. No agent can create or approve a Nitsor release.

# Read a query field

> Read a field's definition to see which filters it admits, what its values mean, and whether Nitsor can evaluate a query on it.

Nitsor documents each query field as a definition in its field registry. The language decides whether text is NQL1; the registry decides which fields exist, which you may see, what their values are, and which operators each one admits. [Read a field before you filter on it](#read-a-field-before-you-filter-on-it) is the checklist to follow, and [Fields used in the examples](#fields-used-in-the-examples) says which example names are real.

> [!NOTE]
>
> The dashboard, public HTTP API and Python SDK do not accept or evaluate NQL1 queries, and do not list query fields. [Capabilities and limits](https://docs.nitsor.com/product-status.md#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:

| Attribute | What it tells you | `source.spacing.z` |
| - | - | - |
| Selector | The field name you write in a query | `source.spacing.z` |
| Display text | The name a person sees | Z spacing |
| Description | What the value records | Recorded spacing between slices. |
| Origin | Where the definition comes from: built-in, DICOM tag, sidecar path or Taxonomy definition | built-in |
| Type | `keyword`, `text`, `number`, `date`, `boolean`, `enum` or `duration` | `number` |
| Units | The unit values are recorded in, or none | `mm` |
| Cardinality | `scalar`, one value, or `list`, several | `scalar` |
| Related scope | The record family the registry files the field under, which can differ from the selector's first segment | geometry |
| Operators | The operators the field admits | `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `range`, `has` |
| Examples | Synthetic values that show the format | `0.5` |
| Coverage and distinct count | How many records carry a value, and how many distinct values, each with its completeness and measurement time | unknown |
| Execution | An execution status and whether a query on the field can be evaluated | unavailable; not executable |
| Sensitivity | `standard`, or `sensitive` for values that can identify a study or series | `standard` |

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](#discoverable-is-not-executable).

## Types and the operators they admit

The registry sets a field's operators from its type and cardinality:

| Type and cardinality | NQL1 forms | Operators |
| - | - | - |
| Scalar `keyword`, `text`, `enum` or `boolean` | `field:value`, `field:!=value`, `has:field` | `eq`, `ne`, `has` |
| Scalar `number`, `date` or `duration` | the above, plus `>` `>=` `<` `<=` and `[low TO high]` | `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `range`, `has` |
| A `list` of any type | `field:value` (contains), `field:ANY(...)`, `field:ALL(...)`, `has:field` | `eq`, `any`, `all`, `has` |

Three consequences are easy to miss:

* A list field does not admit `!=`, and `NOT field:value` is not a replacement: it also selects records with no value. To require a value and exclude one, write `has: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.
* `NOT` is not an operator of a field. It applies to a whole filter, so any filter a field admits can be negated.

Values follow the type:

| Type | Write values as |
| - | - |
| `keyword`, `text` | text: a bare word or a quoted string. How text matches is the registry's rule. |
| `enum` | the option's ID, which is case-sensitive. A display name resolves to an ID only when it is unambiguous. |
| `number` | a number in the field's units, without the unit: `0.5`, not `0.5mm`. |
| `date` | a date, a relative date or a quoted RFC 3339 timestamp with an offset. |
| `duration` | a duration: `15m`, `48h`, `2d`, `1w`. |
| `boolean` | `true` or `false`. |

## Where fields come from

| Origin | Selector form | What it covers |
| - | - | - |
| Built-in | `source.modality`, `label.class`, `task.state` | Nitsor's own facts about Scans, Sources, geometry, Tasks, labels, versions and ingests. |
| Taxonomy definition | `taxonomy["defect-types"]` | Each Field declared in the Taxonomy bound to the branch. A select Field is a scalar `enum`, a multi-select Field is a list of `enum`, and numeric, text and Boolean Fields keep their type. |
| DICOM tag | `dicom["0018,1030"]` | Tags on a controlled allowlist. Identifying DICOM fields are never in the registry. |
| Sidecar path | `meta["machine.name"]` | Typed keys from a sidecar file. The bracketed key keeps its dot. |

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](https://docs.nitsor.com/concepts/taxonomy-versions.md) 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:

| Execution status | It means |
| - | - |
| `indexed` | Evaluated from an index. |
| `projected` | Evaluated from a maintained projection of the field. |
| `bounded scan` | Evaluated by a scan with a stated bound. |
| `building` | The field's index or projection is being built and is not complete. |
| `unavailable` | The registry advertises no way to evaluate it. |

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](https://docs.nitsor.com/guides/query-recipes.md#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. A `sensitive` 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 the `registryRevision` 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.

| Field | In the registry | Type, cardinality |
| - | - | - |
| `source.modality` | yes | `keyword`, scalar |
| `source.registered` | yes | `date`, scalar |
| `source.rows` | yes | `number` in px, scalar |
| `source.spacing.z` | yes | `number` in mm, scalar |
| `asset.name` | yes | `text`, scalar |
| `label.class`, `label.reviewState` | yes | `keyword` and `enum`, scalar |
| `label.provenance.modelVersion` | yes | `keyword`, scalar |
| `task.state`, `task.created`, `task.completed` | yes | `enum`, `date`, `date`, scalar |
| `task.stage` | yes | `keyword`, scalar; the Stage pinned by the Task's workflow version |
| `task.id` | yes | `keyword`, scalar |
| `task.waited` | yes | `duration` in ms, scalar; ends at the first hold or completion, or at `asOf` while queued |
| `study.uid`, `series.uid` | yes, `sensitive` | `keyword`, scalar |
| `study.protocol`, `dicom["0018,1030"]`, `meta["machine.name"]`, `meta["Inspection protocol"]` | yes, metadata | defined, not executable |
| `taxonomy["defect-types"]` | as a Taxonomy Field, if your Taxonomy declares one | multi-select: `enum`, list |
| `tags`, `notes`, `meta.partNumber`, `inspection.passed`, `defects.count`, `measurement` | no, synthetic | as each example describes |

`task.waited` does not add up waiting across a release and requeue; it measures one stretch from queue entry.

## Next step

> [card] [Query recipes](https://docs.nitsor.com/guides/query-recipes.md)
>
> Apply these definitions to common questions, with what each query selects and where it stops.

> [card] [Query language (NQL1)](https://docs.nitsor.com/reference/query-language.md)
>
> The full language reference: what each query selects, and why the parser refuses one.

<table aria-label="Page details">
  <tbody>
    <tr><th scope="row">Plans</th><td>All plans</td></tr>
    <tr><th scope="row">Last verified</th><td>2026-10-25</td></tr>
  </tbody>
</table>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.