Workflow Nodes - Complete Reference
๐งฉ Workflow Building Blocksโ
7 Node Types ยท Every Option ยท Configuration Guide ยท Examples
๐ Table of Contentsโ
- Overview
- Start Node
- Data Query Node
- JavaScript Node
- Condition Node
- Loop Node
- Delay Node
- End Node
- Error Handling
Overviewโ
Jet Admin workflows are built from 7 node types, each serving a specific purpose in the automation pipeline.
Node Types Summaryโ
| Node | Icon | Purpose | Required |
|---|---|---|---|
| Start | ๐ข | Entry point, input definition | โ Yes (1 per workflow) |
| Data Query | ๐ท | Execute database/API queries | โ No |
| JavaScript | ๐ | Run custom code | โ No |
| Condition | ๐ | Branch logic | โ No |
| Loop | ๐ | Iterate over arrays | โ No |
| Delay | โฑ๏ธ | Pause execution | โ No |
| End | ๐ด | Output mapping | โ Yes (at least 1) |
Common Configuration Fieldsโ
All nodes share these common fields:
| Field | Type | Required | Description |
|---|---|---|---|
| Title | String | โ Yes | Node display name |
| Description | String | โ No | Node documentation |
| Output Variable | String | โ Yes | Variable name for result |
| Timeout | Integer | โ No | Execution timeout (seconds) |
| Retry Limit | Integer | โ No | Number of retry attempts |
| Retry Delay | Integer | โ No | Delay between retries (seconds) |
| Error Handling | String | โ No | Behavior on error |
| Is Disabled | Boolean | โ No | Skip node execution |
Start Nodeโ
Purposeโ
The Start Node is the entry point for every workflow. It defines:
- Workflow metadata
- Input parameters (arguments)
- Execution triggers
Configurationโ
Basic Fieldsโ
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Title | String | โ Yes | "Start" | Node title |
| Description | String | โ No | - | Workflow description |
Input Parametersโ
Purpose: Define arguments that the workflow accepts.
Configuration Location: Input Parameters panel (right side of workflow editor)
Parameter Structure:
{
"name": "parameterName",
"type": "string|number|boolean|object|array",
"required": true|false,
"default": "defaultValue"
}
Parameter Types:
| Type | Description | Example |
|---|---|---|
| string | Text value | "user@example.com" |
| number | Numeric value | 42 |
| boolean | True/false | true |
| object | JSON object | {"key": "value"} |
| array | List of values | [1, 2, 3] |
How It Worksโ
Triggers:
- Manual - Click "Test Workflow" button
- API -
POST /api/v1/workflows/:id/execute - Widget - Linked to widget
- Cron - Scheduled execution
- Workflow - Called from another workflow
Input Access:
// In other nodes, access input parameters via:
{{ctx.input.parameterName}}
{{ctx.input.userId}}
{{ctx.input.email}}
Example Configurationโ
Workflow: User Registration
Input Parameters:
[
{
"name": "email",
"type": "string",
"required": true
},
{
"name": "name",
"type": "string",
"required": true
},
{
"name": "role",
"type": "string",
"required": false,
"default": "user"
}
]
Usage in Other Nodes:
-- In Data Query node
INSERT INTO users (email, name, role)
VALUES ({{ctx.input.email}}, {{ctx.input.name}}, {{ctx.input.role}})
RETURNING id, email, name, role;
Data Query Nodeโ
Purposeโ
Execute saved data queries against configured datasources (PostgreSQL, REST API, etc.).
Configuration Fieldsโ
General Tabโ
| Field | Type | Required | Default | Validation | Description |
|---|---|---|---|---|---|
| Title | String | โ Yes | - | Min: 1, Max: 255 | Node title |
| Description | String | โ No | - | - | Node description |
| Data Query | UUID | โ Yes | - | Valid query ID | Select query from dropdown |
| Arguments | Object | โ No | - | Map parameter values |
Output Tabโ
| Field | Type | Required | Default | Pattern | Description |
|---|---|---|---|---|---|
| Output Variable | String | โ Yes | "queryResult" | ^[a-zA-Z_][a-zA-Z0-9_]*$ | Variable name to store result |
Execution Settings Tabโ
| Field | Type | Required | Default | Min/Max | Description |
|---|---|---|---|---|---|
| Timeout | Integer | โ No | 300 | 1-3600 | Execution timeout (seconds) |
| Retry Limit | Integer | โ No | 0 | 0-10 | Number of retry attempts |
| Retry Delay | Integer | โ No | 5 | 1-300 | Delay between retries (seconds) |
| Error Handling | String | โ No | "fail_workflow" | See below | Behavior on error |
| Is Disabled | Boolean | โ No | false | - | Skip this node |
Error Handling Optionsโ
| Option | Value | Description |
|---|---|---|
| Fail Workflow | fail_workflow | Stop workflow execution immediately |
| Continue | continue | Continue to next node, result is null |
| Retry then Continue | retry_then_continue | Retry, then continue if still fails |
| Retry then Fail | retry_then_fail | Retry, then fail workflow if still fails |
Arguments Configurationโ
Purpose: Map values to query parameters.
Dynamic Mapping: Arguments are auto-populated based on selected query's parameters.
Value Sources:
// Input parameters
{{ctx.input.userId}}
// Previous node outputs
{{ctx.fetchUser.result}}
// String interpolation
"id_{{ctx.input.id}}"
// JavaScript expressions
{{ ctx.input.date || new Date().toISOString() }}
Example Configurationโ
Node: Fetch User Data
General Tab:
{
"title": "Fetch User Data",
"description": "Get user details by ID",
"dataQueryID": "query-uuid-here",
"args": {
"userId": "{{ctx.input.userId}}"
}
}
Output Tab:
{
"outputVariable": "userData"
}
Execution Settings:
{
"timeoutSeconds": 30,
"retryLimit": 2,
"retryDelaySeconds": 5,
"errorHandling": "retry_then_fail",
"isDisabled": false
}
Access Result:
// In subsequent nodes:
{{ctx.userData.result}}
{{ctx.userData.result[0].name}}
{{ctx.userData.rowCount}}
JavaScript Nodeโ
Purposeโ
Execute custom JavaScript code for data transformation, logic, or integrations.
Configuration Fieldsโ
General Tabโ
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Title | String | โ Yes | - | Node title |
| Description | String | โ No | - | Node description |
| Code | String | โ Yes | - | JavaScript code to execute |
Output Tabโ
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Output Variable | String | โ Yes | "scriptResult" | Variable name for result |
Execution Settings Tabโ
Same as Data Query Node (timeout, retry, error handling)
Available Variablesโ
| Variable | Type | Description |
|---|---|---|
| ctx | Object | All previous node outputs |
| args | Object | Workflow input parameters |
| utils | Object | Helper functions |
Utility Functionsโ
// Date formatting
utils.formatDate(date, format)
// String manipulation
utils.toUpperCase(str)
utils.toLowerCase(str)
utils.trim(str)
// Math operations
utils.sum(array)
utils.average(array)
utils.round(number, decimals)
// Object operations
utils.pick(object, keys)
utils.omit(object, keys)
utils.flatten(object)
// Array operations
utils.map(array, fn)
utils.filter(array, fn)
utils.reduce(array, fn, initial)
Code Examplesโ
Example 1: Transform Dataโ
Code:
// Transform user data
const user = ctx.fetchUser.result[0];
return {
fullName: `${user.firstName} ${user.lastName}`,
email: user.email.toLowerCase(),
age: new Date().getFullYear() - new Date(user.birthDate).getFullYear(),
isActive: user.status === 'active'
};
Output:
{
"fullName": "John Doe",
"email": "john@example.com",
"age": 30,
"isActive": true
}
Example 2: Conditional Logicโ
Code:
const order = ctx.fetchOrder.result[0];
if (order.total > 1000) {
return {
requiresApproval: true,
approvalLevel: 'manager'
};
} else if (order.total > 500) {
return {
requiresApproval: true,
approvalLevel: 'supervisor'
};
} else {
return {
requiresApproval: false
};
}
Example 3: Data Aggregationโ
Code:
const orders = ctx.fetchOrders.result;
const total = orders.reduce((sum, order) => sum + order.total, 0);
const average = total / orders.length;
const max = Math.max(...orders.map(o => o.total));
return {
totalRevenue: total,
averageOrderValue: average,
highestOrder: max,
orderCount: orders.length
};
Example 4: API Response Formattingโ
Code:
const apiResponse = ctx.callAPI.result;
return {
success: apiResponse.status === 200,
data: apiResponse.data,
message: apiResponse.message || 'Success',
timestamp: new Date().toISOString()
};
Best Practicesโ
โ DO:
- Return objects for structured data
- Use try-catch for error handling
- Keep code focused and simple
- Comment complex logic
- Use output variables meaningfully
โ DON'T:
- Perform async operations (not supported)
- Access external resources directly
- Write overly complex logic (use multiple nodes)
- Modify ctx directly (read-only)
Condition Nodeโ
Purposeโ
Branch workflow execution based on conditions and expressions.
Configuration Fieldsโ
General Tabโ
| Field | Type | Required | Description |
|---|---|---|---|
| Title | String | โ Yes | Node title |
| Description | String | โ No | Node description |
| Branches | Array | โ Yes | Condition branches |
Branch Configurationโ
Each branch has:
| Field | Type | Required | Description |
|---|---|---|---|
| Name | String | โ Yes | Branch identifier |
| Condition Type | String | โ Yes | Comparison type |
| Expression/Operands | Varies | โ Yes | Condition logic |
Condition Typesโ
| Type | Value | Operands | Description |
|---|---|---|---|
| JavaScript Expression | expression | expression | Custom JS boolean expression |
| Equals | equals | left, right | left == right |
| Not Equals | not_equals | left, right | left != right |
| Contains | contains | left, right | left contains right |
| Greater Than | greater_than | left, right | left > right |
| Less Than | less_than | left, right | left < right |
| Is Empty | is_empty | left | left is empty/null/undefined |
| Is Not Empty | is_not_empty | left | left is not empty |
| Regex Match | regex | left, pattern | left matches regex pattern |
Branch Configuration Examplesโ
JavaScript Expressionโ
Configuration:
{
"name": "High Value Order",
"conditionType": "expression",
"expression": "ctx.orderData.result.total > 1000"
}
Use Case: Complex conditions
Equalsโ
Configuration:
{
"name": "Status is Active",
"conditionType": "equals",
"leftOperand": "{{ctx.userData.result.status}}",
"rightOperand": "active"
}
Use Case: Simple equality checks
Containsโ
Configuration:
{
"name": "Email Contains Domain",
"conditionType": "contains",
"leftOperand": "{{ctx.input.email}}",
"rightOperand": "@company.com"
}
Use Case: String contains check
Greater Thanโ
Configuration:
{
"name": "Amount Over Limit",
"conditionType": "greater_than",
"leftOperand": "{{ctx.transactionData.result.amount}}",
"rightOperand": "10000"
}
Use Case: Numeric comparisons
Is Emptyโ
Configuration:
{
"name": "No Results Found",
"conditionType": "is_empty",
"leftOperand": "{{ctx.searchResults.result}}"
}
Use Case: Check for empty/null values
Regex Matchโ
Configuration:
{
"name": "Valid Email Format",
"conditionType": "regex",
"leftOperand": "{{ctx.input.email}}",
"rightOperand": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
}
Use Case: Pattern validation
Multiple Branchesโ
Configuration:
{
"branches": [
{
"id": "branch_1",
"name": "VIP Customer",
"conditionType": "greater_than",
"leftOperand": "{{ctx.customerData.result.lifetimeValue}}",
"rightOperand": "50000"
},
{
"id": "branch_2",
"name": "Regular Customer",
"conditionType": "greater_than",
"leftOperand": "{{ctx.customerData.result.lifetimeValue}}",
"rightOperand": "1000"
},
{
"id": "branch_3",
"name": "New Customer",
"conditionType": "expression",
"expression": "true"
}
]
}
Execution Flow:
- Evaluate branches in order
- Execute first matching branch
- Continue to connected node
- If no match, use default path (if configured)
Available Variables in Conditionsโ
// Previous node outputs
ctx.queryResult
ctx.scriptResult
ctx.fetchData.result
// Input parameters
ctx.input.userId
ctx.input.email
// Nested access
ctx.userData.result[0].name
ctx.orderData.result.total
Loop Nodeโ
Purposeโ
Iterate over arrays and execute child nodes for each item.
Configuration Fieldsโ
General Tabโ
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Title | String | โ Yes | - | Node title |
| Description | String | โ No | - | Node description |
| Array Expression | String | โ Yes | - | Array to iterate over |
| Loop Variable | String | โ No | "item" | Variable name for current item |
| Batch Size | Integer | โ No | 1 | Items per iteration |
| Parallel | Boolean | โ No | false | Run iterations in parallel |
Output Tabโ
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Output Variable | String | โ Yes | "loopResult" | Variable for results array |
Array Expressionโ
Purpose: Specify which array to iterate over.
Examples:
// From query result
{{ctx.fetchUsers.result}}
// From script output
{{ctx.transformData.result.items}}
// From input
{{ctx.input.userIds}}
// Nested array
{{ctx.orderData.result[0].items}}
Loop Variableโ
Purpose: Name for accessing current iteration item.
Default: item
Access in Child Nodes:
// Current item
{{ctx.item}}
// Item property
{{ctx.item.id}}
{{ctx.item.email}}
// With custom variable name
{{ctx.currentUser}}
{{ctx.orderItem}}
Batch Sizeโ
Purpose: Process multiple items per iteration.
Use Cases:
- Batch database inserts
- Bulk API calls
- Grouped processing
Example:
{
"batchSize": 10
}
Processes 10 items at a time.
Parallel Executionโ
Purpose: Run iterations concurrently.
โ ๏ธ Warning: Use with caution - may cause race conditions or API rate limit issues.
Configuration:
{
"parallel": true
}
Example Configurationโ
Loop: Process Order Items
Configuration:
{
"title": "Process Order Items",
"description": "Process each item in the order",
"arrayExpression": "{{ctx.orderData.result.items}}",
"loopVariable": "item",
"batchSize": 1,
"parallel": false,
"outputVariable": "processResults"
}
Child Nodes:
Loop: Process Order Items
โโโ Data Query: Create Inventory Record
โ Args: { itemId: "{{ctx.item.id}}", quantity: "{{ctx.item.quantity}}" }
โโโ Data Query: Update Product Stock
โ Args: { productId: "{{ctx.item.productId}}", decrease: "{{ctx.item.quantity}}" }
โโโ JavaScript: Log Processing
Code: return { processed: ctx.item.id, timestamp: new Date() };
Result Access:
// Array of all iteration results
{{ctx.processResults}}
// Individual result
{{ctx.processResults[0]}}
{{ctx.processResults[0].processed}}
Delay Nodeโ
Purposeโ
Pause workflow execution for a specified duration or until a condition is met.
Configuration Fieldsโ
General Tabโ
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| Title | String | โ Yes | - | Node title |
| Description | String | โ No | - | Node description |
| Delay Type | String | โ Yes | "seconds" | Duration or until |
| Duration | Integer | โ No | - | Milliseconds to wait |
| Until Expression | String | โ No | - | Wait until condition is true |
Delay Typesโ
Fixed Durationโ
Delay Type: seconds, milliseconds, minutes, hours
Configuration:
{
"delayType": "seconds",
"duration": 5000
}
Duration Examples:
| Type | Value | Actual Delay |
|---|---|---|
| milliseconds | 5000 | 5 seconds |
| seconds | 30 | 30 seconds |
| minutes | 5 | 5 minutes |
| hours | 1 | 1 hour |
Wait Until Conditionโ
Delay Type: until
Configuration:
{
"delayType": "until",
"untilExpression": "ctx.approvalReceived.result === true"
}
Use Cases:
- Wait for approval
- Wait for external event
- Poll for status change
Example Configurationsโ
Example 1: Rate Limitingโ
Purpose: Avoid API rate limits
Configuration:
{
"title": "Rate Limit Delay",
"description": "Wait 1 second between API calls",
"delayType": "seconds",
"duration": 1000
}
Example 2: Approval Waitโ
Purpose: Wait for manager approval
Configuration:
{
"title": "Wait for Approval",
"description": "Wait until approval is received",
"delayType": "until",
"untilExpression": "{{ctx.checkApproval.result.approved !== null}}"
}
Example 3: Staggered Executionโ
Purpose: Delay before sending notification
Configuration:
{
"title": "Delay Notification",
"description": "Wait 5 minutes before sending reminder",
"delayType": "minutes",
"duration": 5
}
End Nodeโ
Purposeโ
Terminate workflow execution and define output mapping.
Configuration Fieldsโ
General Tabโ
| Field | Type | Required | Description |
|---|---|---|---|
| Title | String | โ Yes | Node title |
| Description | String | โ No | Node description |
Output Mapping Tabโ
| Field | Type | Required | Description |
|---|---|---|---|
| Output Mappings | Object | โ No | Map variables to output |
Output Mappingโ
Purpose: Define what data is returned when workflow completes.
Structure:
{
"outputMapping": {
"success": "{{ctx.finalResult.success}}",
"userId": "{{ctx.createUser.result.id}}",
"message": "\"User created successfully\"",
"data": "{{ctx.userData.result}}"
}
}
Output Mapping Examplesโ
Example 1: Simple Success Responseโ
Configuration:
{
"outputMapping": {
"success": true,
"message": "Operation completed successfully"
}
}
Result:
{
"success": true,
"message": "Operation completed successfully"
}
Example 2: Return Created Resourceโ
Configuration:
{
"outputMapping": {
"id": "{{ctx.createUser.result.id}}",
"email": "{{ctx.createUser.result.email}}",
"name": "{{ctx.createUser.result.name}}",
"createdAt": "{{ctx.createUser.result.created_at}}"
}
}
Result:
{
"id": "uuid-123",
"email": "john@example.com",
"name": "John Doe",
"createdAt": "2024-01-01T00:00:00Z"
}
Example 3: Conditional Outputโ
Configuration:
{
"outputMapping": {
"success": "{{ctx.finalCheck.result.passed}}",
"data": "{{ctx.processData.result}}",
"error": "{{ctx.finalCheck.error || null}}",
"requiresAction": "{{ctx.finalCheck.result.requiresAction}}"
}
}
Error Handlingโ
Node-Level Error Handlingโ
Each node can configure error handling behavior:
Fail Workflow (Default)โ
Behavior: Stop execution immediately
Configuration:
{
"errorHandling": "fail_workflow"
}
Use Case: Critical operations that must succeed
Continueโ
Behavior: Continue to next node, result is null
Configuration:
{
"errorHandling": "continue"
}
Use Case: Non-critical operations
Retry then Continueโ
Behavior: Retry configured times, then continue
Configuration:
{
"errorHandling": "retry_then_continue",
"retryLimit": 3,
"retryDelaySeconds": 5
}
Use Case: Flaky external services
Retry then Failโ
Behavior: Retry configured times, then fail workflow
Configuration:
{
"errorHandling": "retry_then_fail",
"retryLimit": 3,
"retryDelaySeconds": 5
}
Use Case: Important but potentially transient failures
Retry Behaviorโ
Retry Logic:
- Attempt execution
- On failure, check retry limit
- If retries remaining, wait delay duration
- Retry with exponential backoff
- If still fails, apply error handling
Exponential Backoff:
Attempt 1: Immediate
Attempt 2: After 5 seconds
Attempt 3: After 10 seconds (5 ร 2)
Attempt 4: After 20 seconds (5 ร 4)
Next Stepsโ
- Workflow Edges - Connections and conditions
- Workflow Execution - Run and monitor workflows
- Examples - Complete workflow examples
- API Reference - Execute via API