Node Reference
Complete reference for all 21 node types available in the workflow canvas. Each node has a specific purpose, configuration schema, and category placement.
Core Nodes (12)
Core nodes are always available and provide the fundamental building blocks for workflow logic.
Trigger
The entry point of every workflow. Receives the event payload and makes it available to all downstream nodes via {{trigger.field}} interpolation.
Configuration
| Field | Type | Description |
|---|---|---|
event | string | The event name to listen for (e.g., order.created) |
cron | string|null | Optional cron expression for scheduled triggers |
polling_url | string|null | Optional URL for polling triggers |
{
"type": "trigger",
"config": {
"event": "order.created"
}
}
End
Terminal node that marks the workflow as complete. Every workflow must have at least one End node. It has no configuration — simply connect it as the final node in your flow.
{
"type": "end",
"config": {}
}
Branch
Conditional routing node. Evaluates conditions and routes execution to the true_target or false_target branch based on the result.
Configuration
| Field | Type | Description |
|---|---|---|
conditions_builder | array | Array of condition objects: {field, operator, value} |
true_target | string | Node ID to execute when conditions are met |
false_target | string | Node ID to execute when conditions are NOT met |
Available Operators
eq, neq, gt, gte, lt, lte, contains, in, regex
{
"type": "branch",
"config": {
"conditions_builder": [
{ "field": "{{trigger.amount}}", "operator": "gte", "value": "1000" }
],
"true_target": "node_vip_alert",
"false_target": "node_standard_flow"
}
}
Delay
Pauses the workflow execution for a specified duration. The execution enters waiting status and is resumed by the ResumeWorkflowJob after the delay period.
Configuration
| Field | Type | Range | Description |
|---|---|---|---|
seconds | integer | 1 — 604,800 | Delay duration in seconds (max 7 days) |
{
"type": "delay",
"config": {
"seconds": 172800
}
}
Loop
Iterates over an array of items and executes a set of body nodes for each item. Makes loop context variables available: {{loop.item}}, {{loop.index}}, {{loop.count}}.
Configuration
| Field | Type | Description |
|---|---|---|
items_path | string | Dot notation path to the array (e.g., trigger.order.items) |
body_nodes | array | Array of node IDs to execute per iteration |
max_iterations | integer | Safety limit. Default: 100, Maximum: 500 |
{
"type": "loop",
"config": {
"items_path": "trigger.order.items",
"body_nodes": ["node_transform_item", "node_send_notification"],
"max_iterations": 50
}
}
Transform
Data transformation node. Creates new variables from existing data using an assignments array. Supports the pipe syntax for inline transformations (upper, lower, default, date).
Configuration
| Field | Type | Description |
|---|---|---|
assignments | array | Array of {key, value} objects defining output variables |
{
"type": "action.transform",
"config": {
"assignments": [
{ "key": "greeting", "value": "Hello, {{trigger.name | upper}}!" },
{ "key": "safe_amount", "value": "{{trigger.total | default:0}}" }
]
}
}
Log Message
Writes a message to the Laravel application log. Useful for debugging workflows and recording audit information.
Configuration
| Field | Type | Description |
|---|---|---|
message | string | Message text with interpolation support |
level | string | Log level: info, warning, or error |
{
"type": "action.log",
"config": {
"message": "Order #{{trigger.order_id}} processed for {{trigger.customer.email}}",
"level": "info"
}
}
Condition
Gate node evaluated by the engine itself. If the conditions evaluate to false, every downstream node is skipped and the execution continues to the next branch. Unlike branch, it has a single outgoing path.
Configuration
| Field | Type | Description |
|---|---|---|
conditions | conditions_builder | Required. Array of condition objects: {field, operator, value} |
Available Operators
eq, neq, gt, gte, lt, lte, contains, in, regex
{
"type": "condition",
"config": {
"conditions": [
{ "field": "{{trigger.status}}", "operator": "eq", "value": "paid" }
]
}
}
Merge
Joins several parallel branches back into a single path. It waits for the referenced source nodes and combines their outputs into one payload available to downstream nodes.
Configuration
| Field | Type | Description |
|---|---|---|
sources | node_refs | Required. IDs of the nodes whose outputs are merged |
{
"type": "merge",
"config": {
"sources": ["node_send_email", "node_send_whatsapp"]
}
}
Sub-workflow
Runs another workflow as a reusable step. Lets you extract shared logic — a notification sequence, a validation routine — into one workflow and call it from many others.
Configuration
| Field | Type | Description |
|---|---|---|
workflow_id | workflow_ref | Required. The workflow to run |
input | key_value | Values mapped into the sub-workflow trigger payload |
{
"type": "subworkflow",
"config": {
"workflow_id": 12,
"input": {
"customer_email": "{{trigger.customer.email}}",
"order_id": "{{trigger.order_id}}"
}
}
}
Import Data
Reads a CSV or Excel file and emits its rows as an array. Pair it with a loop node to drive bulk operations such as mass WhatsApp reminders or email campaigns. Column headers are auto-detected and become field names.
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
file_path | file | — | Required. Accepts .csv, .xlsx, .xls, .txt |
format | select | auto | auto, csv, or xlsx |
max_rows | integer | 500 | Maximum rows to read. Max: 5,000 |
sheet_index | integer | 0 | Worksheet to read, 0-based (Excel only) |
{
"type": "action.import_data",
"config": {
"file_path": "imports/customers-july.xlsx",
"format": "auto",
"max_rows": 1000,
"sheet_index": 0
}
}
HTTP Request
Makes an HTTP request to an external URL. Includes SSRF protection that blocks requests to private/internal IP ranges (127.x, 10.x, 192.168.x, etc.).
Configuration
| Field | Type | Description |
|---|---|---|
method | string | GET, POST, PUT, PATCH, or DELETE |
url | string | Target URL (supports interpolation) |
headers | object | Key-value pairs for request headers |
body | object|string | JSON body for POST/PUT/PATCH requests |
timeout | integer | Timeout in seconds. Default: 10, Max: 30 |
{
"type": "action.http",
"config": {
"method": "POST",
"url": "https://api.example.com/orders",
"headers": {
"Authorization": "Bearer {{trigger.api_key}}",
"Content-Type": "application/json"
},
"body": {
"order_id": "{{trigger.order_id}}",
"status": "confirmed"
},
"timeout": 15
}
}
Module Nodes (9)
Module nodes require their corresponding module to be installed and configured. They extend the platform with external service integrations.
Send Email
Sends an email via the configured mail transport (SMTP or Resend API). Supports HTML content and variable interpolation in all fields.
Configuration
| Field | Type | Description |
|---|---|---|
to | string | Recipient email address |
subject | string | Email subject line |
body | string | Email body (supports HTML) |
from | string|null | Optional sender address (defaults to system config) |
{
"type": "action.email.send",
"config": {
"to": "{{trigger.customer.email}}",
"subject": "Order #{{trigger.order_id}} Confirmed",
"body": "<h1>Thank you, {{trigger.customer.name}}!</h1><p>Your order has been confirmed.</p>"
}
}
Send WhatsApp
Sends a free-form WhatsApp message. Only works within the 24-hour messaging window. Falls back to a template if the window has expired.
Configuration
| Field | Type | Description |
|---|---|---|
to | string | Recipient phone number (E.164 format) |
body | string | Message text content |
fallback_template | string|null | Template name to use if outside 24h window |
{
"type": "action.whatsapp.send",
"config": {
"to": "{{trigger.customer.phone}}",
"body": "Hi {{trigger.customer.name}}, your order #{{trigger.order_id}} has been shipped!",
"fallback_template": "order_shipped"
}
}
Send WhatsApp Template
Sends a pre-approved WhatsApp template message. Works outside the 24-hour window. Templates must be approved by Meta before use.
Configuration
| Field | Type | Description |
|---|---|---|
to | string | Recipient phone number (E.164 format) |
template_name | string | Name of the approved template |
language | string | Template language code (e.g., en_US, es) |
variables | array | Ordered array of template variable values |
{
"type": "action.whatsapp.send_template",
"config": {
"to": "{{trigger.customer.phone}}",
"template_name": "order_confirmation",
"language": "en_US",
"variables": [
"{{trigger.customer.name}}",
"{{trigger.order_id}}",
"{{trigger.total}}"
]
}
}
AI Prompt
Sends a prompt to an AI model (Claude or GPT) and returns the response. Use for classification, extraction, summarization, content generation, and more.
Configuration
| Field | Type | Description |
|---|---|---|
prompt | string | The user prompt (supports interpolation) |
system_prompt | string|null | Optional system instructions for the AI |
model | string | Model identifier (e.g., claude-3-sonnet, gpt-4o) |
temperature | float | Creativity level: 0 (deterministic) to 1 (creative) |
max_tokens | integer | Maximum tokens in the response |
{
"type": "action.ai.prompt",
"config": {
"prompt": "Classify this message into one of: complaint, question, praise, other.\n\nMessage: {{trigger.message}}",
"system_prompt": "You are a customer intent classifier. Respond with only the category name.",
"model": "claude-3-sonnet",
"temperature": 0,
"max_tokens": 50
}
}
AI Classify
Assigns a piece of text to exactly one of the categories you define. Unlike a free-form prompt, the output is constrained to your category list, so it can be used directly in a branch or condition node without extra parsing.
Configuration
| Field | Type | Description |
|---|---|---|
input | textarea | Required. Text to classify (supports interpolation) |
categories | array | Required. Exact category strings the model must choose from |
system_prompt | textarea | Optional system prompt to steer the classifier |
model | string | Leave blank to use the organization default model |
{
"type": "action.ai.classify",
"config": {
"input": "{{trigger.message}}",
"categories": ["complaint", "question", "praise", "other"],
"system_prompt": "You are a customer intent classifier."
}
}
AI Extract
Pulls structured fields out of unstructured text. You declare the fields you want and their types, and the node returns a typed object that downstream nodes can reference as {{step_id.output.field}}.
Configuration
| Field | Type | Description |
|---|---|---|
input | textarea | Required. Text to extract from (supports interpolation) |
schema | object | Required. Field definitions as name: type pairs |
system_prompt | textarea | Optional system prompt to steer the extraction |
model | string | Leave blank to use the organization default model |
{
"type": "action.ai.extract",
"config": {
"input": "{{trigger.message}}",
"schema": {
"product_name": "string",
"quantity": "number",
"delivery_address": "string"
}
}
}
Send Notification
Sends an in-app notification to the current organization's users. Notifications appear in the bell icon dropdown in the dashboard.
Configuration
| Field | Type | Description |
|---|---|---|
title | string | Notification title |
body | string | Notification body text |
type | string | info, success, warning, or error |
{
"type": "action.notify",
"config": {
"title": "New VIP Order",
"body": "Order #{{trigger.order_id}} worth ${{trigger.total}} from {{trigger.customer.name}}",
"type": "success"
}
}
Create Shipment
Creates a new shipment in the connected courier service (Deprixa Plus). Returns a tracking number that can be used by downstream nodes.
Configuration
| Field | Type | Description |
|---|---|---|
receiver_name | string | Recipient full name |
receiver_phone | string | Recipient phone number |
receiver_address | string | Delivery address |
description | string | Package description |
weight | float | Package weight in kg |
service_type | string | Shipping service level (e.g., express, standard) |
{
"type": "action.courier.create_shipment",
"config": {
"receiver_name": "{{trigger.shipping.name}}",
"receiver_phone": "{{trigger.shipping.phone}}",
"receiver_address": "{{trigger.shipping.address}}",
"description": "Order #{{trigger.order_id}}",
"weight": 2.5,
"service_type": "express"
}
}
Get Tracking
Retrieves the current tracking status and history for a shipment. Returns the latest status, location, and timeline of events.
Configuration
| Field | Type | Description |
|---|---|---|
tracking_number | string | The shipment tracking number |
{
"type": "action.courier.get_tracking",
"config": {
"tracking_number": "{{trigger.tracking_number}}"
}
}
Quick Reference Table
| # | Label | Type | Category | Module |
|---|---|---|---|---|
| 1 | Trigger | trigger | flow | core |
| 2 | End | end | flow | core |
| 3 | Branch | branch | flow | core |
| 4 | Delay | delay | flow | core |
| 5 | Loop | loop | flow | core |
| 6 | Transform | action.transform | flow | core |
| 7 | Log Message | action.log | action | core |
| 8 | Condition | condition | flow | core |
| 9 | Merge | merge | flow | core |
| 10 | Sub-workflow | subworkflow | flow | core |
| 11 | Import Data | action.import_data | action | core |
| 12 | HTTP Request | action.http | action | core |
| 13 | Send Email | action.email.send | integration | email-module |
| 14 | Send WhatsApp | action.whatsapp.send | integration | whatsapp-module |
| 15 | Send WhatsApp Template | action.whatsapp.send_template | integration | whatsapp-module |
| 16 | AI Prompt | action.ai.prompt | ai | ai-module |
| 17 | AI Classify | action.ai.classify | ai | ai-module |
| 18 | AI Extract | action.ai.extract | ai | ai-module |
| 19 | Send Notification | action.notify | action | notification-module |
| 20 | Create Shipment | action.courier.create_shipment | integration | courier-module |
| 21 | Get Tracking | action.courier.get_tracking | integration | courier-module |