Filter
The Filter step takes a list and checks each item on its own. Items that match your rules continue on the KEPT route, and the rest go to DISCARDED.
Use it to strip a list down before doing expensive work on it. You might keep only active users out of a hundred, or only the orders above a threshold.
Think of it as a Condition applied to every item, with the verdict’s routing built in: an item that passes continues on KEPT, one that fails takes DISCARDED. Each route carries on with its share of the list — and a route that ends up with no items does not run at all.
Filter is the only one that divides a list. The other two look at the run as a whole and pick a path. Ask yourself whether you are splitting items or choosing a route — and see Choosing a Flow Step for the difference between the three.
- 5 itemsKEPT — matched “deal size is over 10,000”Notify sales
- 7 itemsDISCARDED — the restLog for review
Both routes run, each carrying its own share. That is what makes Filter different from the other two.
Choose the list, then write the rules
The panel opens with List: choose which list to filter, from the steps connected before this one. Connect an earlier step first and its lists are offered; Enter it myself takes a typed list instead.
Then each rule reads the way you would say it out loud: a property of an item, an operator, a value, as in status is equal to active. The property picker offers the fields of the list you chose.
Before an earlier step is connected, the List field says so:
Connect an earlier step to choose one of its lists.
Connect the step that returns the list first. The picker only offers lists from steps before this one on the canvas. Until the link exists, the Filter has nothing to offer you and the FILTERING line stays empty.
To point the Filter at a different list, pick a property from that list in one of the rules. The binding follows the property. Check the FILTERING line afterwards to confirm you landed on the list you meant. That matters when two upstream steps return similar-looking lists.
Setting it up
Select a property
Click Select a property on the first rule and choose a field of the item you want to test.
Choose the type and operator
Pick the data type: Text, Number, Yes/no, Record, List, or Date & Time. Then pick an operator from that type’s list. The catalogue is shared with Conditions.
Add more rules if you need them
Click Rule to add another. Rules within a group are joined with AND. Separate groups are joined with OR. The panel states the result plainly: items matching all rules in any group are kept.
Point the routes at steps
Choose a step under KEPT. Under DISCARDED, choose a step if you want to do something with the rejects, or leave it unassigned to drop them.
With no rules configured, every item is kept. An unfinished Filter is not a closed gate.
Referring to the item
Inside the rules, {{ $item }} is the whole item, {{ $item.field }} one of its properties, and {{ $itemIndex }} its position in the list, counting from 0.
Filter uses $item, with a dollar sign. Run for each
item uses item, without one.
The two are separate mechanisms and the tokens are not interchangeable.
One record works too
Filter is happiest with a list, but a single record is fine: it is treated as a list of one, and comes out on KEPT or DISCARDED like any other item.
That makes it a useful gate for a single thing. “Only carry on if this order is over £500” is a Filter with one record in and one route out, and unlike a Conditions step, the item itself travels down the route rather than only the decision.
What the step accepts:
| Input | What happens |
|---|---|
| A list | Each item is checked on its own |
| A single record | Treated as a list of one |
| Text holding a list or record | Read as one, if properly formed |
| A blank value, a bare number or some text | The step fails |
The last row is deliberate. A bare value has no fields to test, so wrapping it silently would produce a rule that can never match. The step says so instead: “Filter needs a list or record. Connect a step that returns a list, or pick a field that holds one.”
When an item does not make sense
Sometimes a rule cannot be answered for a particular item. You are comparing dates and one record has “last Tuesday” in that field, or comparing numbers and one has “N/A”.
Those items are discarded rather than stopping the run. One bad record does not cost you the other ninety-nine, and the step tells you it finished with problems.
The catch is that discarded then means two things at once: items that genuinely did not match, and items nobody could make sense of. If that distinction matters, send DISCARDED somewhere you can look at it rather than dropping it.
Capital letters matter here
Ignore capitalisation is off by default, so Active does not match
active. Text is compared exactly until you say otherwise, which is the same
rule the Switch step follows.
Turn it on to ignore capitals across every rule in the step. You can also set it on a single rule, which overrides the step for that rule alone. That helps when one field arrives from a system that capitalises inconsistently and the rest do not.
Describing a rule in words
Where no operator fits, set a rule’s type to AI Condition and write what you are testing in plain language: “the message sounds like a complaint”, “the address is outside the UK”. Prompt Examples offers starting points.
Watch the count on a long list. An AI condition costs a model call for every item, so a hundred items means a hundred calls, and two runs on the same item can differ. Use it for the tests a comparison cannot express, and switch the rest to a typed operator once you know the value you are testing.
AI Condition is available in Filter and Conditions. The Switch step is typed-only.
A branch with no items does not run
If every item matches, nothing connected to DISCARDED fires. If none match, nothing connected to KEPT fires. That is usually what you want, but it means a step on only one route is skipped when that route has no items. The run finishes successfully, without doing that work.
If something must happen either way, put it before the Filter or on both routes.
What it passes on
Downstream steps read the results by number, like any other step:
| Reference | What it holds |
|---|---|
{{ N.kept }} | The items that matched |
{{ N.discarded }} | The items that did not |
{{ N.keptCount }} | How many were kept |
{{ N.discardedCount }} | How many were discarded |
Discarded items are always in the step’s result, even with the DISCARDED
route unassigned. Leaving that route empty stops them continuing through the
workflow. It does not throw them away. If you need to see what fell out, read
{{ N.discarded }} on any later step.
Limits
A single Filter step processes up to 100,000 items. Above that it stops with an error rather than quietly doing part of the job.
If you use matches regex in a rule, all that pattern-matching together gets five seconds across the whole list. Any single pattern gets 250 milliseconds. Go over either and the step fails, naming how many items it got through. It will not hand you a half-filtered list. If you hit it, filter on something simpler first to cut the list down, or simplify the pattern.
Examples to copy
Keep only active users
| Setting | Value |
|---|---|
| Property | status, from the list of users |
| Type | Text |
| Operator | is equal to |
| Value | active |
Picking status out of the list of users is what binds the Filter to that list. Check the FILTERING line to confirm. The next step reads {{ N.kept }}.
Drop consumer email domains
Two rules with AND. Click Rule to add the second.
| Property | Type | Operator | Value | |
|---|---|---|---|---|
| Rule 1 | email | Text | does not end with | @gmail.com |
| AND | email | Text | does not end with | @yahoo.com |
Both must hold for an item to be kept. Matching is exact by default, so turn Ignore capitalisation on if @Gmail.com should be caught too.
Keep products that are in stock
| Setting | Value |
|---|---|
| Property | stock_count |
| Type | Number |
| Operator | is greater than |
| Value | 0 |
Point DISCARDED at a step that logs what fell out rather than leaving it empty. Otherwise you cannot tell “nothing was out of stock” from “the rule was wrong”.
What’s Next?
- Process each kept item individually with Loops & Iteration.
- Route the whole run instead of a list with the Conditions Step.