Skip to main content
Not every workflow needs a language model. When you want to select rows based on a specific column value — for example, all customers whose rating is greater than 4, or all contacts whose subscription status is active — the FILTER node gives you a fast, deterministic, and LLM-free way to do it. This guide walks you through building a complete filter-based workflow that reads a CSV upload, applies an expression to select matching rows, and sends each matched recipient a personalized email.

FILTER vs AI: choosing the right node

Both the FILTER node and the AI node can narrow down a list of rows, but they work very differently: Use FILTER when your selection criteria can be expressed as a simple rule. Use AI when you need the model to interpret, summarize, or generate content alongside filtering.
The FILTER node is the best choice when you’re testing a new workflow end-to-end. It runs instantly without any external API calls, so you can validate your graph structure and email templates before introducing an AI node.

FILTER node configuration

The FILTER node has two required fields inside its data object:
  • source — A template expression that resolves to the array of rows you want to filter. Typically this is {{ds.rows}} where ds is the id of an upstream DATA_SOURCE node.
  • expr — A filter expression written as a comparison against column values. The expression is evaluated once per row; rows for which it evaluates to true are included in the output.

Expression syntax

Expressions support standard comparison operators. The left-hand side must be a column name from your CSV header row (no curly-brace syntax needed here — you’re inside the expression language, not the template engine).

Output

After the FILTER node runs, the matched rows are available as {{nodeId.items}}. If your filter node has id: "f", you reference the result as {{f.items}} in downstream nodes.

Building the workflow

1

Authenticate

Obtain an access token by logging in with your Flowmatic credentials:
Export the token for use in subsequent requests:
2

Upload your CSV

If you haven’t already, upload the CSV file you want to filter. The file must include a header row whose column names match the field names you’ll use in the expr.
For this guide, the CSV is expected to have at least name, email, and rating columns:
3

Create the workflow

Submit the workflow definition. Replace <your-upload-id> with the uploadId from the previous step.
On success you’ll receive a 201 response with the created workflow:
Note the workflow id — you’ll use it to trigger runs.
4

Run the workflow

Trigger an execution against the workflow you just created:
The API acknowledges the request with a 202 and returns a run identifier:
The run will move through the PENDING → RUNNING → SUCCESS (or FAILED) lifecycle. See the Run & Monitor guide for details on polling for status and inspecting per-node output.

Full workflow JSON reference

Here is the complete workflow definition you used above, with a breakdown of each node’s role:
Node breakdown:
  • t (TRIGGER) — The mandatory pipeline entry point. It carries no configuration and simply initiates the execution chain when a run is enqueued.
  • ds (DATA_SOURCE) — Fetches and parses the uploaded CSV, making the full array of rows available as {{ds.rows}}. Each row is an object whose keys are the CSV column headers.
  • f (FILTER) — Iterates over {{ds.rows}} and evaluates rating > 4 for each row. Rows where the expression is true are collected into {{f.items}}. In this example, Alice (rating 5) and Carol (rating 5) pass; Bob (rating 3) does not.
  • out (OUTPUT) — Loops over {{f.items}} and dispatches one email per matched row. The {{item.email}}, {{item.name}} placeholders resolve to the current row’s values on each iteration.

Adapting the expression

You can swap out the expr value to filter on any column in your CSV. Here are a few common patterns:
String values in the expr must be wrapped in single quotes (e.g., status == 'active'). Numeric values should be written without quotes (e.g., rating > 4). Using double quotes inside the expression string will cause a parse error because the outer JSON string already uses double quotes.