Common expression patterns
Recipes for things you'll write often. Copy, adjust, run.
1. Pull a webhook field into an HTTP body
{
"user_id": "{{ $trigger.payload.userId }}",
"items": "{{ $node['Cart'].output.items }}"
}user_id is placed inside a string, so it is inserted as text and escaped for JSON. items is a value that is exactly one expression, so a list stays a real JSON array. The webhook body is under $trigger.payload, not $trigger.body.
2. Build a URL with path parameters
https://{{ $env.API_HOST }}/users/{{ $trigger.payload.userId }}/ordersKeep the host in a workspace variable ($env) so it can change without editing the workflow.
3. Compose a chat message
:tada: Order {{ $trigger.payload.orderId }} from *{{ $trigger.payload.customerName }}*, total {{ $trigger.payload.amount }}Mix literal text and expressions freely. Formatting characters such as *bold* are just text to Flero.
4. Date for a file name
report-{{ $node["Today"].output.formatted }}.pdfExpressions can't format dates. Use two Date & Time nodes:
- Now: operation
now. Its output hasdateTime(ISO 8601). - Today: operation
format, input{{ $node["Now"].output.dateTime }}, output formatdate. Its output hasformatted, for example2026-10-13.
5. Choose between two values
Expressions have no ternary. Branch with an If node and set the value on each branch with a Set node, or use a small Code node:
// Code node "Greeting"
const name = input[0].firstName;
return { greeting: `Hello, ${name || "there"}!` };Then reference {{ $node["Greeting"].output.greeting }} downstream.
6. Default for a missing field
Use a Set node rule with allowOverwrite off. It writes the key only when it isn't already there:
{
"allowOverwrite": false,
"rules": [ { "key": "name", "value": "Anonymous" } ]
}7. Lower-case an email before comparing
{ "globalTransforms": { "lowercase": ["email"], "trim": ["email"] }, "rules": [] }Put this Set node before the If that compares the email. {{ $input.email.toLowerCase() }} does not work.
8. Count or sum a list
{
"transformations": [
{ "operation": "aggregate", "source": "scores", "target": "total", "aggregateOperation": "sum" }
]
}A Data Transform aggregate also does count, average, min and max. To sum a field across a list of objects, use a Code node.
9. Read a later item of a multi-item output
{{ $node["List Orders"].output._items[2].id }} // third item
{{ $node["List Orders"].output._count }} // number of itemsWithout _items, $node["List Orders"].output.id reads the first item.
10. Use the current item inside a Loop
// Inside the Loop body
{{ $input.item.email }}
{{ $input._loopIteration.current }}The Loop puts each element under item (or the Loop's outputFieldName).
11. Check a webhook signature
Set a secret on the API/Webhook Trigger. Flero then checks the HMAC-SHA256 signature in the X-Hub-Signature-256 or X-Webhook-Secret header on every request, before the run starts.
For providers that sign differently, check the header yourself:
The If node tests {{ $trigger.headers.stripe-signature }} with isNotEmpty. Leave the false port unconnected so unsigned requests stop there.
Then compute and compare the signature with an Encryption & Hashing node (sign or verify), with the key in {{ $env.STRIPE_WEBHOOK_SECRET }}.
12. Idempotency with a processed-events table
- Seen? runs
SELECT 1 FROM processed_events WHERE id = {{ $trigger.payload.id }}. Values written as{{ }}in SQL are sent as parameters. - Already processed? tests whether Seen? returned a row. Leave its
trueport unconnected so duplicates stop there. - Record event inserts the id before the work starts, so a second delivery finds it.
Providers retry webhooks, so the same event can arrive more than once. Recording each event id in your own database means a repeat delivery is skipped, whichever worker runs it.
Related
- Data transformation nodes
- Recipes, full workflows that use these patterns
- Debugging expressions
Found something out of date? This page lives in the Flero docs content set.