Documentation Index
Fetch the complete documentation index at: https://docs.dualship.run/llms.txt
Use this file to discover all available pages before exploring further.
Nodes are the building blocks of a flow. Each node performs a specific operation and can read from or write to the execution context.
Node Structure
Every node follows this structure:
{
"id": "unique_id",
"type": "node_type",
"log": true,
"config": { }
}
| Field | Type | Required | Description |
|---|
id | string | Yes | Unique identifier within the flow |
type | string | Yes | One of the 12 supported node types |
log | boolean | No | Enable runtime logging for this node (default: true) |
config | object | Yes | Configuration specific to the node type |
Runtime Logging
Every node supports the log field to control runtime logging:
{
"id": "sensitive_transform",
"type": "transform",
"log": false,
"config": { ... }
}
When log is enabled (default), the system captures:
- Input: Request data and trigger context before execution
- Output: Node result after successful execution
- Errors: User-friendly error messages (sensitive details are sanitized)
Set log: false to disable runtime logging for a node. This is useful for:
- Nodes processing sensitive data (passwords, tokens, PII)
- High-frequency operations where logging overhead matters
- Reducing log storage for verbose nodes
Node Categories
Control Flow
Control how execution proceeds through your flow.
| Node | Description |
|---|
| condition | If/else-if/else branching based on expressions |
| switch | Multi-way branching with pattern, range, or exact matching |
| parallel | Execute multiple branches concurrently |
| loop | Iterate over arrays, counts, or while conditions |
| try | Error handling with catch and finally blocks |
Data Manipulation
Store and transform data in the execution context.
| Node | Description |
|---|
| set | Store a value in the context |
| transform | Reshape data and compute new values |
HTTP/Network
Make outbound HTTP requests to external services.
| Node | Description |
|---|
| http | Make HTTP requests with full control over method, headers, body |
Queue
Send messages for asynchronous processing.
| Node | Description |
|---|
| enqueue | Send messages to queue handlers for background processing |
Response/Abort
Control how the flow responds or terminates.
| Node | Description |
|---|
| response | Send an HTTP response and end the flow |
| abort | Stop execution immediately with an error response |
Timing
Control execution timing.
| Node | Description |
|---|
| delay | Pause execution for a specified duration |
Validation
Validate incoming data.
| Node | Description |
|---|
| request | Validate data against a schema with 32 built-in rules |
Logging
Write custom log entries.
| Node | Description |
|---|
| log | Write custom entries to runtime logs |
Node Outputs
After a node executes, its output is stored in the context under {node_id}.output:
After “fetch_user” node executes:
{
"fetch_user": {
"output": {
"status_code": 200,
"body": { "id": 1, "name": "John" }
}
}
}
Access outputs in subsequent nodes:
{{fetch_user.output.body.name}} -> "John"
{{fetch_user.output.status_code}} -> 200
Execution Flow
Sequential
By default, nodes execute in order:
Node 1 -> Node 2 -> Node 3
Branching
Control flow nodes specify which nodes to execute next:
{
"id": "check",
"type": "condition",
"config": {
"conditions": [
{ "if": "{{amount}} > 100", "then": ["high_value"] }
],
"else": ["standard"]
}
}
Skip Behavior
When a branch is taken, sibling branches are skipped. The executor tracks which nodes to skip to prevent unintended execution.
Common Patterns
[
{
"id": "fetch",
"type": "http",
"config": { "url": "https://api.example.com/data" }
},
{
"id": "transform",
"type": "transform",
"config": {
"output": {
"items": "{{fetch.output.body.results}}",
"count": "{{fetch.output.body.results | count}}"
}
}
}
]
Validate and Process
[
{
"id": "validate",
"type": "request",
"config": {
"source": "request.body",
"schema": { "email": "required|email" }
}
},
{
"id": "process",
"type": "http",
"config": { "url": "https://api.example.com/users", "method": "POST" }
}
]
Conditional Response
[
{
"id": "check",
"type": "condition",
"config": {
"conditions": [
{ "if": "{{data.status}} == active", "then": ["success"] }
],
"else": ["error"]
}
},
{
"id": "success",
"type": "response",
"config": { "status": 200, "body": { "ok": true } }
},
{
"id": "error",
"type": "response",
"config": { "status": 400, "body": { "ok": false } }
}
]
Next Steps
Explore each node type in detail: