Expression Engine
Orchka uses JSONata as its expression language, allowing you to transform and manipulate data as it flows between nodes.
Syntax
Expressions are written inside double curly braces:
{{ expression }}Accessing Data
Input Data ($input)
Access data from the previous node using $input:
{{ $input.propertyName }}Examples:
{{ $input.user.name }} // Nested property
{{ $input.items[0] }} // Array index
{{ $input.items[0].id }} // Nested array access
{{ $input.response.data.users }} // Deep nestingPrevious Nodes
Access data from any previous node by name:
{{ $nodes.HTTP_Request.data.result }}
{{ $nodes.AI_Agent.response }}Common Operations
String Operations
{{ $uppercase($input.name) }} // JOHN
{{ $lowercase($input.name) }} // john
{{ $trim($input.text) }} // Remove whitespace
{{ $substring($input.text, 0, 10) }} // First 10 chars
{{ $replace($input.text, "old", "new") }} // Replace text
{{ $input.first & " " & $input.last }} // ConcatenationNumeric Operations
{{ $input.price * 1.1 }} // Multiply
{{ $sum($input.items.price) }} // Sum array
{{ $average($input.scores) }} // Average
{{ $round($input.value, 2) }} // Round to 2 decimals
{{ $floor($input.num) }} // Floor
{{ $ceil($input.num) }} // CeilingArray Operations
{{ $count($input.items) }} // Array length
{{ $filter($input.items, function($v) { $v.active = true }) }}
{{ $map($input.items, function($v) { $v.name }) }}
{{ $sort($input.items, function($a, $b) { $a.date > $b.date }) }}
{{ $append($input.arr1, $input.arr2) }} // Merge arrays
{{ $distinct($input.tags) }} // Unique valuesConditional Logic
{{ $input.status = "active" ? "Yes" : "No" }}
{{ $exists($input.email) ? $input.email : "N/A" }}
{{ $input.score >= 90 ? "A" : $input.score >= 80 ? "B" : "C" }}Date & Time
{{ $now() }} // Current timestamp
{{ $toMillis($input.date) }} // To milliseconds
{{ $fromMillis($input.timestamp) }} // From millisecondsObject Operations
{{ $keys($input.user) }} // Get object keys
{{ $lookup($input.users, "id") }} // Lookup by key
{{ $merge([$input.defaults, $input.custom]) }} // Merge objects
{{ $spread($input.items) }} // Spread array to objectReal-World Examples
API Response Transformation
// Input from HTTP Request
{
"data": {
"users": [
{ "id": 1, "name": "Alice", "email": "alice@example.com" },
{ "id": 2, "name": "Bob", "email": "bob@example.com" }
]
}
}Expression to extract names:
{{ $map($input.data.users, function($u) { $u.name }) }}
// Result: ["Alice", "Bob"]Building API Request Body
{
"user": "{{ $input.username }}",
"timestamp": "{{ $now() }}",
"items": "{{ $filter($input.products, function($p) { $p.inStock = true }) }}"
}Conditional Message
{{ $input.count > 0 ? "Found " & $string($input.count) & " results" : "No results found" }}Best Practices
- Use descriptive paths -
$input.user.profile.nameis clearer than$input.a.b.c - Handle missing data - Use
$exists()or default values - Test expressions - Use the expression preview in the settings panel
- Keep it simple - Break complex transformations into multiple nodes
Debugging
Use the Node Detail Modal to:
- View input data from previous nodes
- Preview expression results
- See the actual output after execution