Writing Filter Expressions

Advanced

The full vocabulary for filter conditions — matching on type, tags, names, properties and dates, and combining them with and/or/not.

Most of the time you build a filter in the app: open the Filters area in the Model Navigator, add conditions, and the tree narrows to what matches. This article is for the other case — writing a filter's expression directly, which is what the AI assistant and the API do.

An expression is a small piece of JSON. It is one condition, or several conditions joined by and, or and not.

The simplest ones

{"OfType": {"type_id": "Risk"}}

Matches every element of one type. You can name the type or give its ID.

{"HasTag": {"tag": "critical"}}

Matches elements carrying a tag. Capitalisation is ignored, so critical and Critical are the same tag.

"All"

Matches everything. "None" matches nothing — occasionally useful as a starting point you fill in later.

Matching on tags

ConditionMatches
{"HasTag": {"tag": "critical"}}Has this one tag
{"HasAnyTag": {"tags": ["critical", "urgent"]}}Has at least one of these
{"HasAllTags": {"tags": ["critical", "reviewed"]}}Has every one of these

Matching on names and descriptions

{"NameMatches": {"operator": "Contains", "value": "payment"}}
{"DescriptionMatches": {"operator": "Contains", "value": "deprecated"}}

The operator is one of Contains, Equals, StartsWith, EndsWith or Regex.

NameMatches works on whatever that kind of element calls its name — an element's label, a type's name, a diagram's or folder's name.

Matching on a property

{"PropertyMatches": {"property_name": "status", "operator": "Equals", "value": "open"}}

Use the property's name, as it appears in the Properties Panel — not its internal ID.

Operators: Equals, NotEquals, Contains, GreaterThan, LessThan, GreaterOrEqual, LessOrEqual, IsEmpty, IsNotEmpty.

IsEmpty and IsNotEmpty ignore the value, so this finds everything still missing an owner:

{"PropertyMatches": {"property_name": "owner", "operator": "IsEmpty", "value": ""}}

Matching on dates

{"UpdatedDate": {"operator": {"InLast": {"days": 7}}, "value": ""}}
{"CreatedDate": {"operator": "Before", "value": "2026-01-01"}}

CreatedDate and UpdatedDate both take Before, After, Between (which carries an end date) or InLast (which carries a number of days). Dates are written as ISO 8601 — 2026-01-01.

Everything touched this week is {"InLast": {"days": 7}} on UpdatedDate.

Matching by folder or by ID

{"InFolder": {"folder_id": "folder-uuid", "recursive": true}}
{"HasId": {"ids": ["node-uuid", "RSK-4"]}}

recursive: true includes everything in sub-folders too; false stays in that one folder.

HasId picks out specific elements by ID or auto-ID — handy for a hand-assembled selection.

Reusing another filter

{"FilterRef": {"filter_id": "filter-uuid"}}

Matches whatever that saved filter matches, so you can build a broad filter once and narrow it in several directions without repeating yourself. If the filter it points at has been deleted, it simply matches nothing.

Combining conditions

{"And": [
  {"OfType": {"type_id": "Risk"}},
  {"HasTag": {"tag": "critical"}}
]}

And needs every condition to match, Or needs at least one, and Not reverses a single condition:

{"And": [
  {"OfType": {"type_id": "Service"}},
  {"Not": {"HasTag": {"tag": "deprecated"}}}
]}

They nest, so you can say critical or urgent risks that nobody owns:

{"And": [
  {"OfType": {"type_id": "Risk"}},
  {"HasAnyTag": {"tags": ["critical", "urgent"]}},
  {"PropertyMatches": {"property_name": "owner", "operator": "IsEmpty", "value": ""}}
]}

Things worth knowing

  • Conditions only apply where they make sense. A folder has a name but no properties, so a property condition simply doesn't match it. This matters most inside Not, which reverses the condition only for the kinds of element it applies to in the first place.
  • A misspelled type or property name matches nothing, quietly. There is no error — you just get an empty result. If a filter comes back empty and you expected rows, check the spelling against the Properties Panel first.
  • Updating a filter through the API replaces the whole expression. update_filter does not merge your change into what was there, so send the complete expression.
  • Filters are elements too. They live in folders, take tags, and can be translated — which is why they have names worth choosing well.

This content was written collaboratively with AI.