Skip to main content

Workflow Nodes - Complete Reference

๐Ÿงฉ Workflow Building Blocksโ€‹

7 Node Types ยท Every Option ยท Configuration Guide ยท Examples


๐Ÿ“‹ Table of Contentsโ€‹


Overviewโ€‹

Jet Admin workflows are built from 7 node types, each serving a specific purpose in the automation pipeline.

Node Types Summaryโ€‹

NodeIconPurposeRequired
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:

FieldTypeRequiredDescription
TitleStringโœ… YesNode display name
DescriptionStringโŒ NoNode documentation
Output VariableStringโœ… YesVariable name for result
TimeoutIntegerโŒ NoExecution timeout (seconds)
Retry LimitIntegerโŒ NoNumber of retry attempts
Retry DelayIntegerโŒ NoDelay between retries (seconds)
Error HandlingStringโŒ NoBehavior on error
Is DisabledBooleanโŒ NoSkip 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โ€‹

FieldTypeRequiredDefaultDescription
TitleStringโœ… Yes"Start"Node title
DescriptionStringโŒ 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:

TypeDescriptionExample
stringText value"user@example.com"
numberNumeric value42
booleanTrue/falsetrue
objectJSON object{"key": "value"}
arrayList of values[1, 2, 3]

How It Worksโ€‹

Triggers:

  1. Manual - Click "Test Workflow" button
  2. API - POST /api/v1/workflows/:id/execute
  3. Widget - Linked to widget
  4. Cron - Scheduled execution
  5. 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โ€‹

FieldTypeRequiredDefaultValidationDescription
TitleStringโœ… Yes-Min: 1, Max: 255Node title
DescriptionStringโŒ No--Node description
Data QueryUUIDโœ… Yes-Valid query IDSelect query from dropdown
ArgumentsObjectโŒ No-Map parameter values

Output Tabโ€‹

FieldTypeRequiredDefaultPatternDescription
Output VariableStringโœ… Yes"queryResult"^[a-zA-Z_][a-zA-Z0-9_]*$Variable name to store result

Execution Settings Tabโ€‹

FieldTypeRequiredDefaultMin/MaxDescription
TimeoutIntegerโŒ No3001-3600Execution timeout (seconds)
Retry LimitIntegerโŒ No00-10Number of retry attempts
Retry DelayIntegerโŒ No51-300Delay between retries (seconds)
Error HandlingStringโŒ No"fail_workflow"See belowBehavior on error
Is DisabledBooleanโŒ Nofalse-Skip this node

Error Handling Optionsโ€‹

OptionValueDescription
Fail Workflowfail_workflowStop workflow execution immediately
ContinuecontinueContinue to next node, result is null
Retry then Continueretry_then_continueRetry, then continue if still fails
Retry then Failretry_then_failRetry, 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โ€‹

FieldTypeRequiredDefaultDescription
TitleStringโœ… Yes-Node title
DescriptionStringโŒ No-Node description
CodeStringโœ… Yes-JavaScript code to execute

Output Tabโ€‹

FieldTypeRequiredDefaultDescription
Output VariableStringโœ… Yes"scriptResult"Variable name for result

Execution Settings Tabโ€‹

Same as Data Query Node (timeout, retry, error handling)

Available Variablesโ€‹

VariableTypeDescription
ctxObjectAll previous node outputs
argsObjectWorkflow input parameters
utilsObjectHelper 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โ€‹

FieldTypeRequiredDescription
TitleStringโœ… YesNode title
DescriptionStringโŒ NoNode description
BranchesArrayโœ… YesCondition branches

Branch Configurationโ€‹

Each branch has:

FieldTypeRequiredDescription
NameStringโœ… YesBranch identifier
Condition TypeStringโœ… YesComparison type
Expression/OperandsVariesโœ… YesCondition logic

Condition Typesโ€‹

TypeValueOperandsDescription
JavaScript ExpressionexpressionexpressionCustom JS boolean expression
Equalsequalsleft, rightleft == right
Not Equalsnot_equalsleft, rightleft != right
Containscontainsleft, rightleft contains right
Greater Thangreater_thanleft, rightleft > right
Less Thanless_thanleft, rightleft < right
Is Emptyis_emptyleftleft is empty/null/undefined
Is Not Emptyis_not_emptyleftleft is not empty
Regex Matchregexleft, patternleft 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:

  1. Evaluate branches in order
  2. Execute first matching branch
  3. Continue to connected node
  4. 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โ€‹

FieldTypeRequiredDefaultDescription
TitleStringโœ… Yes-Node title
DescriptionStringโŒ No-Node description
Array ExpressionStringโœ… Yes-Array to iterate over
Loop VariableStringโŒ No"item"Variable name for current item
Batch SizeIntegerโŒ No1Items per iteration
ParallelBooleanโŒ NofalseRun iterations in parallel

Output Tabโ€‹

FieldTypeRequiredDefaultDescription
Output VariableStringโœ… 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โ€‹

FieldTypeRequiredDefaultDescription
TitleStringโœ… Yes-Node title
DescriptionStringโŒ No-Node description
Delay TypeStringโœ… Yes"seconds"Duration or until
DurationIntegerโŒ No-Milliseconds to wait
Until ExpressionStringโŒ No-Wait until condition is true

Delay Typesโ€‹

Fixed Durationโ€‹

Delay Type: seconds, milliseconds, minutes, hours

Configuration:

{
"delayType": "seconds",
"duration": 5000
}

Duration Examples:

TypeValueActual Delay
milliseconds50005 seconds
seconds3030 seconds
minutes55 minutes
hours11 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โ€‹

FieldTypeRequiredDescription
TitleStringโœ… YesNode title
DescriptionStringโŒ NoNode description

Output Mapping Tabโ€‹

FieldTypeRequiredDescription
Output MappingsObjectโŒ NoMap 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:

  1. Attempt execution
  2. On failure, check retry limit
  3. If retries remaining, wait delay duration
  4. Retry with exponential backoff
  5. 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โ€‹