Filter Node
The Filter node gates events by evaluating payload conditions. Only events that pass all (or any) of the configured filter rules continue through the pipeline — everything else is dropped before delivery, saving retries and quota.
Overview
Filters inspect the event payload against a set of rules and decide whether the event should proceed. Unlike Routers (which direct events to different destinations), Filters are binary: an event either passes or is blocked. You can configure the filter to require and (all rules must pass) or or (any rule passing is sufficient).
Blocked events are saved with status filtered and no delivery job is created. On the canvas, Filter nodes appear as yellow rectangles.
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
| name | string | — | Friendly label for the filter |
| filterMode | string | and | 'and' (all rules must pass) or 'or' (any rule passing is sufficient) |
| filters | FilterRule[] | [] | Array of filter rules (see below) |
| inputNodes | { nodeType, nodeId }[] | [] | Upstream nodes that feed this one. nodeType is the node kind (webhook, scheduledWorkflow, filter, …) |
| isActive | boolean | true | Whether the filter is enabled |
FilterRule object
| Field | Type | Description |
|---|---|---|
| field | string | Dot-notation path into the payload (e.g. data.status) |
| operator | string | Comparison operator (equals, not_equals, contains, not_contains, gt, lt, exists, not_exists, regex, in, not_in) |
| value | string | Value to compare against (not required for exists/not_exists) |
Create a Filter
curl -X POST /api/filter-nodes \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "High-Value Payments Only",
"filterMode": "and",
"filters": [
{
"field": "type",
"operator": "equals",
"value": "payment_intent.succeeded"
},
{
"field": "data.object.amount",
"operator": "gt",
"value": "5000"
},
{
"field": "data.object.currency",
"operator": "in",
"value": "usd,eur,gbp"
}
],
"inputNodes": [{ "nodeType": "webhook", "nodeId": "6654a1b2c3d4e5f6a7b8c9d0" }],
"isActive": true
}'Response
{
"_id": "6654e5f6a7b8c9d0e1f2a3b4",
"name": "High-Value Payments Only",
"filterMode": "and",
"filters": [
{
"field": "type",
"operator": "equals",
"value": "payment_intent.succeeded"
},
{
"field": "data.object.amount",
"operator": "gt",
"value": "5000"
},
{
"field": "data.object.currency",
"operator": "in",
"value": "usd,eur,gbp"
}
],
"inputNodes": [{ "nodeType": "webhook", "nodeId": "6654a1b2c3d4e5f6a7b8c9d0" }],
"isActive": true,
"ownerId": "org_abc123",
"createdAt": "2025-05-01T12:00:00.000Z",
"updatedAt": "2025-05-01T12:00:00.000Z"
}Update a Filter
curl -X PATCH /api/filter-nodes/6654e5f6a7b8c9d0e1f2a3b4 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"filterMode": "or",
"filters": [
{
"field": "data.object.amount",
"operator": "gt",
"value": "10000"
},
{
"field": "data.object.metadata.priority",
"operator": "equals",
"value": "high"
}
]
}'filters replaces the entire array. Include all rules you want to keep.Canvas Integration
The Filter uses canvas type filter-node and renders in yellow. It connects from a Webhook and acts as a gate — events that pass continue through outgoing edges; blocked events stop at the filter.
{
"id": "filter-6654e5f6a7b8c9d0e1f2a3b4",
"type": "filter-node",
"position": { "x": 350, "y": 200 },
"data": {
"label": "High-Value Payments Only",
"filterNodeId": "6654e5f6a7b8c9d0e1f2a3b4",
"filterMode": "and",
"ruleCount": 3,
"isActive": true
}
}Payload Examples
Event that passes the filter
{
"type": "payment_intent.succeeded",
"data": {
"object": {
"amount": 15000,
"currency": "usd",
"customer": "cus_abc123"
}
}
}
// Result: PASSES — type matches, amount > 5000, currency in [usd, eur, gbp]Event that is blocked
{
"type": "payment_intent.succeeded",
"data": {
"object": {
"amount": 2500,
"currency": "usd",
"customer": "cus_xyz789"
}
}
}
// Result: BLOCKED — amount (2500) is NOT > 5000. Event saved as "filtered".OR mode example
// filterMode: "or"
// Rule 1: data.object.amount gt 10000
// Rule 2: data.object.metadata.priority equals "high"
{
"type": "payment_intent.succeeded",
"data": {
"object": {
"amount": 500,
"metadata": { "priority": "high" }
}
}
}
// Result: PASSES — amount fails but priority matches (OR requires only one)Use Cases
- Event type filtering — Only process specific event types from a source that sends many (e.g., Stripe sends 100+ event types).
- Amount thresholds — Block low-value transactions to reduce processing load.
- Feature flags — Use
existsto only pass events with a specific metadata field present. - Security filtering — Block events from untrusted sources using
not_inon IP or source identifiers. - Quota management — Reduce event volume to stay within plan limits by filtering out non-essential events.
API Reference
| Method | Webhook | Description |
|---|---|---|
| GET | /api/filter-nodes | List all filter nodes |
| POST | /api/filter-nodes | Create a new filter node |
| GET | /api/filter-nodes/:id | Get a specific filter node |
| PATCH | /api/filter-nodes/:id | Update a filter node |
| DELETE | /api/filter-nodes/:id | Delete a filter node |