Writing Filter Expressions
AdvancedThe 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
| Condition | Matches |
|---|---|
{"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_filterdoes 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.