Skip to main content

Automation Nodes

Automation nodes are extensions that add custom functionality to the visual Automation Builder. Users drag your node onto the canvas, configure it, and connect it to other nodes to build automated workflows.

Three node types are supported:

TypePurposeExample
TriggerStart an automation from a webhook or scheduled checkShopify order webhook, periodic check of node configuration
ActionProcess data when the automation runsTransform an incoming order payload
LogicBranch the flow based on a conditionCheck if order total exceeds a threshold

Each automation node extension declares exactly one node. Multiple nodes require multiple extensions.

Architecture​

Automation nodes run server-side in a V8 isolate inside the Automation Worker service. The execution flow:

  1. The Automation Builder stores the node graph (nodes + edges) in the database
  2. When a trigger fires (webhook, poll, or manual), the Automation Engine walks the graph
  3. For each extension node, the Engine dispatches to the Automation Worker via HTTP
  4. The Worker executes your handler in a sandboxed V8 isolate
  5. The handler result flows back: action output feeds downstream nodes, logic branches route the flow

The Automation Builder does not render a config UI for extension nodes yet: selecting one shows a note instead of your editor surface or a form. See Config Panel.

Manifest​

Automation node extensions use category: "automation_node" and require a node_type field plus a node configuration object:

{
"$schema": "https://lumio.vision/schemas/lumio.config.schema.json",
"extension_id": "your-uuid-here",
"name": "My Custom Action",
"category": "automation_node",
"version": "1.0.0",
"node_type": "action",
"node": {
"input_schema": {
"type": "object",
"properties": {
"message": { "type": "string", "title": "Message" }
},
"required": ["message"]
},
"output_schema": {
"type": "object",
"properties": {
"success": { "type": "boolean" }
}
},
"icon": "send",
"color": "#3b82f6"
},
"targets": ["editor"],
"server": true
}

Key manifest rules:

  • category must be "automation_node"
  • node_type must be "trigger", "action", or "logic"
  • targets must include "editor"
  • server must be true (nodes execute server-side)
  • Trigger nodes require node.trigger_mode ("webhook", "polling", or "both")
  • Action and logic nodes must NOT have trigger_mode or poll_interval_seconds

Handler file​

Your server handler lives in server/handler.ts. Each node type uses a different SDK wrapper:

  • Action: defineAutomationAction
  • Trigger: defineAutomationTrigger
  • Logic: defineAutomationLogic

See the dedicated guide for each node type:

Context API​

Every handler receives a ctx object:

PropertyTypeDescription
ctx.fetch(url, options)FunctionOutbound requests are denied for automation nodes, including hosts in the manifest allowlist
ctx.cache.get(key)FunctionCache is not connected for automation nodes
ctx.cache.set(key, value, ttl?)FunctionCache is not connected for automation nodes
ctx.installConfigRecord<string, unknown>Extension-level config (from extension_installs.config)
ctx.nodeConfigRecord<string, unknown>Per-node-instance config (from automation_nodes.config)
ctx.inputDataRecord<string, unknown>Data from upstream node or webhook/poll payload
ctx.authObject{ accountId, extensionId, installId }

Timeouts​

Node TypeTimeoutRationale
Action5000msAllows bounded data processing
Logic2000msShould be fast computation
Trigger (poll)5000msAllows bounded scheduled checks
Trigger (webhook)1000msJust parsing/validation

The timeout is enforced inside the Automation Worker on the isolate's own thread, including any pending async work. See Handler runtime limits.

The worker runs a node only for an install of the account that owns the automation, and only for the extension named in the node. Installs of a suspended extension are not run.

Next steps​