Node Anatomy
Understand the structure of an ActionFlows node: its inputs, outputs, handles, configuration, and how data flows through it on the canvas.
Node Anatomy
A node is the unit of work on the canvas. This page covers inputs, outputs, handles, and how data moves through a node.
What You'll Learn: The complete structure of nodes, why they're different from competitors, and how to design workflows that don't break at runtime.
What is a Node?
A node is the fundamental unit of computation in ActionFlows. Think of it as a pure function with explicit inputs, outputs, and side effects.
┌─────────────────────────────────────────┐
│ NODE STRUCTURE │
├─────────────────────────────────────────┤
│ │
│ INPUT │ OUTPUT│
│ HANDLES ────→│ [COMPUTATION] ├────→ HANDLES
│ │ │
│ (LEFT SIDE) │ (Process) │ (RIGHT SIDE)
│ │ │
└─────────────────────────────────────────┘
Properties:
✓ Receives typed inputs (left side)
✓ Performs single task (AI call, decision, data fetch)
✓ Produces typed outputs (right side)
✓ No state between executions (isolation)In professional terms: Nodes are pure functions with deterministic side effects. Given the same inputs, they always produce the same outputs.
The Core Difference: ActionFlows vs Traditional Platforms
Traditional Approach: The Runtime Error Problem
Step 1: Start
↓ outputs loose JSON
Step 2: Node B receives it
↓ tries to parse
Step 3a: If parse fails
↓ ERROR AT RUNTIME (RED)
(you don't catch it until the workflow runs)
Step 3b: If parse succeeds
↓ proceed (hope the structure is right)The Problem:
Developer builds flow → Publishes to production → Flow runs on real data → Data structure is different than expected → Node fails silently or crashes → Customer support ticket created → Developer debugging at 2am
Cost: Debugging time, customer trust, system reliability.
Node Anatomy: Inputs & Outputs
Every node has left-side inputs and right-side outputs. These are called handles.
Input Handles (Data Flows In)
Start Input (Green Dot)
Control flow trigger that signals "Run this node when previous completes". This is implicit and not manually configured. Every node has one except Start nodes.
Data Inputs (Named Circles)
Specific data parameters like "Prompt", "Email Body", or "Topic". These can be connected from other nodes or hardcoded as static values.
Each input has a declared type:
Input Type System
├─ Text (string, email, URL)
├─ Number (integer, float, percentage)
├─ Boolean (true/false)
├─ Object (structured data with schema)
├─ Array (list of items)
├─ File (image, PDF, document)
└─ Enum (predefined options)
Type Checking Rule:
Text output → Text input ALLOWED
Number output → Text input BLOCKED (type mismatch)
Object output → Object input ALLOWED (if schema matches)Output Handles (Data Flows Out)
Every node produces at least one output. The type depends on node category:
AI Nodes Output:
Generate Text
├─ Generated Text (Text): AI response
├─ Token Count (Object): {input: 145, output: 287}
└─ Cost (Number): 0.003 USDConnection Rules (The Platform's Safety Guardrails)
The Canvas Enforces Type Safety
You cannot connect incompatible handles. The platform makes it physically impossible to create invalid connections.
CONNECTION VALIDATION
Valid Connections (enabled, clickable):
├─ Text output → Text input
├─ Number output → Number input
└─ Object {customer} → Object {customer} input
Invalid Connections (dimmed, blocked):
├─ Number output → Text input (cannot click)
├─ Array output → Object input (cannot click)
└─ File output → Text input (cannot click)
Hovering over handle shows:
"Expected type: Text"
"This output: Number"
"INCOMPATIBLE"Visual Feedback:
- Green checkmark = connection valid
- Red X = connection invalid
- Hover shows expected vs. actual type
Node Categories: Anatomy & Patterns
Start Nodes (Triggers)
No inputs. They initiate execution.
START NODES
├─ Start
│ └─ Output: user_input (any type user provides)
│
├─ Start
│ ├─ from (Text)
│ ├─ subject (Text)
│ ├─ body (Text)
│ └─ attachments (Array of Files)
│
├─ flow webhook on Start
│ └─ payload (Object: raw request data)
│
├─ Schedule Trigger
│ ├─ timestamp (Number)
│ └─ schedule_metadata (Object)
│
└─ Database Watch
└─ record_changed (Object)Why Multiple Triggers Matter: Different integrations provide different data shapes. Explicit types prevent silent failures downstream.
AI Nodes
Inputs: Model choice, prompt, parameters, context data
Outputs: Generated content plus metadata (tokens, cost)
GENERATE TEXT NODE
Inputs:
├─ Model (Enum dropdown)
│ ├─ Claude Sonnet 4.5 (USD 3 per million input)
│ ├─ Claude Haiku 4.5 (USD 1 per million input)
│ ├─ GPT-4o (USD 2.50 per million input)
│ └─ Mistral Large (USD 2 per million input)
│
├─ Prompt (Text: your instruction)
│ └─ Can reference other outputs
│
├─ Temperature (Number: 0-2)
│ └─ 0 = deterministic, greater than 0 = creative
│
├─ Max Tokens (Number)
│ └─ Controls response length and cost
│
└─ System Prompt (Text: optional)
└─ Instructions that apply to all calls
Outputs:
├─ Generated Text (Text)
│ └─ The AI response
│
├─ Token Count (Object)
│ ├─ input_tokens: 145
│ ├─ output_tokens: 287
│ └─ total_tokens: 432
│
└─ Cost (Number)
└─ USD amount for this executionKey Difference from Competitors:
n8n/Make:
AI call completes
Output: {response: "text"}
(cost hidden from flow)ActionFlows:
AI call completes
Outputs:
├─ text: "response"
├─ token_count: {input, output}
└─ cost: 0.003
You can use these in downstream logic:
"If cost greater than 0.01, send alert"
"Log token usage to database"Control Nodes (Decision Logic)
If Node: Branching Logic
Inputs:
├─ Condition (Boolean)
│ └─ Example: sentiment score greater than 0.8
│
└─ Left and Right paths (implicit)
└─ One executes, other skipped
Outputs:
├─ TRUE branch
│ └─ Executes if condition passes
│
└─ FALSE branch
└─ Executes if condition fails
Visual Flow:
[Condition Check]
│
┌──┴──┐
│ │
TRUE FALSE
│ │
[Path1][Path2]
│ │
└──┬──┘
[Merge]Integration Nodes
Slack Node
Inputs: channel, message, blocks (formatting)
Outputs: message_id, status, timestamp
Cost: Free (integration only)
Database Node
Inputs: operation, table, data, conditions
Outputs: record, records, row_count, error
Cost: Depends on your database pricing
HTTP Request Node
Inputs: URL, method, headers, body
Outputs: response, status_code, headers, error
Cost: Free (external API pricing applies)
Email Node
Inputs: recipient, subject, body, attachments
Outputs: message_id, status, delivered_at
Cost: Free (email provider pricing applies)
Data Flow Through Nodes: Explicit Mapping
When you connect two nodes, you create an explicit mapping of which output feeds which input.
Email to Analyze to Slack
Step 1: Start fires
Output:
├─ sender: "[email protected]"
├─ subject: "Need help with order"
└─ body: "My order hasn't arrived..."
Step 2: Generate Text (AI Analysis)
Inputs:
├─ Prompt: "Analyze email and extract: sentiment, urgency, topic"
├─ Email context: from email trigger body
Outputs:
├─ analysis: {sentiment: "frustrated", urgency: "high", topic: "shipping"}
└─ cost: 0.002
Step 3: Slack Notification
Inputs:
├─ channel: "#support"
├─ message: "Priority ticket: frustrated customer with shipping issue"
Result:
Slack receives the complete messageWhat is Happening:
data_flow = {
email.body → Generate Text
→ analysis.sentiment → Slack
→ analysis.urgency → Slack
}
Every connection explicit. No hidden mappings.Variable References: The Syntax
Within any text field, reference outputs from other nodes with this syntax.
Syntax: {{nodeId.outputName}}
Examples:
├─ {{startNodeId.body}}
│ JSON body from a flow webhook, or a mapped start output
├─ {{generateTextNodeId.text}}
│ text output from Generate Text
└─ {{databaseNodeId.records}}
array output; use the chip path UI for nested fieldsThe inspector inserts chips when you drop an output handle. Do not type a fictional Email Trigger node name.
Node Execution and State
Determinism Guarantee
Identical inputs result in identical outputs. Always.
Execution 1:
Input: "What is 2 plus 2?"
Model: Claude (temperature: 0)
Output: "4"
Execution 2 (same everything):
Input: "What is 2 plus 2?"
Model: Claude (temperature: 0)
Output: "4"
Execution 3 (change temperature to 0.7):
Input: "What is 2 plus 2?"
Model: Claude (temperature: 0.7)
Output: "The answer is four." ← different wording, same meaningWhy this matters:
- Predictable behavior
- Easier debugging
- Safe for production
- Cost predictability
No State Between Executions
Each execution is ISOLATED.
Run 1: node outputs "Hello"
Run 2: node outputs "Hi" (different prompt)
Run 3: node outputs "Hello" (same as Run 1)
There is NO memory:
"Hey, I ran before and output Hello"
Each run starts fresh.
If you NEED memory (count visits, track status):
Use Database node to store and retrieveExecution Context (Implicit Access)
During execution, a node has access to:
Automatic Access:
├─ Its own inputs
├─ Previous node outputs
├─ Environment variables (credentials, API keys)
├─ Execution metadata
│ ├─ run_id (unique ID for this execution)
│ ├─ timestamp (when it ran)
│ ├─ attempt_number (for retries)
│ └─ user_id (who triggered it)
All automatic. You do not manually configure.Advanced Patterns
Pattern One: Conditional Branching
Email Received
↓
AI Sentiment Analysis
├─ Score greater than 0.8 (happy customer)
│ └─ Route to: Slack celebrations
│
├─ Score 0.3 to 0.8 (neutral)
│ └─ Route to: general-responses
│
└─ Score less than 0.3 (upset customer)
└─ Route to: urgent-support
↓
Alert manager and create ticketImplementation:
If node checks: sentiment score greater than 0.8
├─ YES → Slack celebrations
└─ NO → Check next condition
If score greater than 0.3
├─ YES → Slack general
└─ NO → Priority support flowPattern Two: Parallel Execution (Speed Multiplier)
Customer Email Arrives
↓
Three tasks RUN IN PARALLEL:
├─ Branch 1: AI sentiment analysis
│ └─ Executes: 2 seconds
│
├─ Branch 2: Database lookup (customer history)
│ └─ Executes: 300 milliseconds
│
└─ Branch 3: API call (inventory check)
└─ Executes: 1.5 seconds
MERGE waits for slowest (2 seconds)
↓
All results available simultaneously
↓
Create comprehensive response
If serial (sequential):
└─ 2 seconds plus 0.3s plus 1.5s equals 3.8 seconds
If parallel (all together):
└─ maximum time equals 2 seconds
Saves: 1.8 seconds per execution
On 1,000 executions: 30 minutes savedPattern Three: Looping with Intelligence
Batch Process 1,000 Customer Records
↓
Loop Node
├─ For each record:
│ ├─ AI analysis (2 seconds times 1,000 equals 33 mins)
│ ├─ Save result to database
│ └─ Count successes and failures
│
└─ Outputs per iteration:
├─ item (current record)
├─ index (1 to 1,000)
└─ completed (when loop done)
↓
After loop: Summary
├─ Processed: 1,000 records
├─ Successful: 998
├─ Errors: 2
└─ Total cost: USD 15.40Node Performance: Critical Considerations
Execution Speed
- AI Nodes: 1 to 10 seconds per call (slow)
- Database: 100 to 500 milliseconds (medium)
- Control: less than 10 milliseconds (fast)
Strategy: Minimize AI calls. Batch when possible.
Token Cost
- Short prompt: USD 0.001
- Long context: USD 0.05 to 0.50
- Image generation: USD 0.02 to 0.20 per image
Strategy: Use cheaper models (Haiku). Cache results.
Memory Limits
- Array size: Max 10,000 items
- Text: Max 1,000,000 characters
- API response: Max 50 megabytes
Strategy: Paginate large queries. Stream results.
Optimization Examples
Bad: AI in Every Loop Iteration
Loop through 100 customer emails:
├─ Iteration 1: AI analysis (3s) equals USD 0.005
├─ Iteration 2: AI analysis (3s) equals USD 0.005
├─ Iteration 3: AI analysis (3s) equals USD 0.005
├─ and so on
└─ Iteration 100: AI analysis (3s) equals USD 0.005
Total time: 5 minutes
Total cost: USD 0.50Problem: Slow and expensive. Long wait times for user.
Side-by-Side: ActionFlows vs n8n
Type Safety
n8n:
Node outputs JSON (untyped)
Connected node receives it
If structure wrong equals runtime error
You debug in productionActionFlows:
Node declares output type
Connected node declares required type
If mismatch equals linter error (before publish)
You fix it in developmentWinner: ActionFlows (catch errors early)
Node Design Best Practices
Keep Nodes Focused
One node equals one job. Not mixing concerns.
GOOD:
├─ Start (just reads email)
├─ AI Analysis (just analyzes)
└─ Slack Send (just sends)
BAD:
└─ Start that also analyzes plus sends to SlackUse Descriptive Names
GOOD: "Classify Support Ticket Sentiment"
BAD: "AI Process"
GOOD: "Extract Customer Email from HTML"
BAD: "Extract Data"Self-documenting flows are easier to maintain.
Handle Errors Explicitly
Every node that can fail should branch:
├─ Success path
└─ Error path (log, alert, retry)
Do not ignore errors. Route them explicitly.Test Before Production
1. Configure the node on the Actionflow Studio canvas
2. Run the whole flow with sample data
3. Verify outputs on the node and in Run Output
4. Check cost on that run
5. Adjust wiring or prompts, then run againMap Data Deliberately
Do not rely on implicit data passing.
GOOD: Explicitly reference node outputs
BAD: Assume system figures it out
Explicit equals safer plus easier to debugQuick Reference: Node Anatomy Cheat Sheet
| Term | Definition | Example |
|---|---|---|
| Input Handle | Data enters here | Prompt input |
| Output Handle | Data exits here | Generated Text |
| Data Type | Kind of data | Email Body equals Text |
| Connection | Link output to input | Text output to Text input |
| Mapping | Assign outputs to inputs | result to message |
| Start Input | Execution trigger | When to run this node |
| Pure Function | Same input equals same output | Deterministic |
| Side Effect | External action | Send email |
| Determinism | Repeatable behavior | Temperature equals zero |
| State Isolation | No memory between runs | Each run is fresh |
| Execution Context | Auto available metadata | run_id, timestamp |
| Type Validation | Check compatibility | No runtime surprises |
| Streaming Output | Real-time feedback | User sees response live |
| Parallel Execution | Multiple nodes together | Faster workflows |
| Error Handling | Explicit error routing | Try to success or error |
Next: Explore Node Types in Depth
AI Nodes
Generate Text, Generate Image, Transcribe Audio, Generate JSON. Model selection, streaming, structured outputs.
Control Nodes
If, Loop, Merge, Wait, Uniq. Decision logic, iteration, synchronization, branching.
Integration Nodes
Slack, Email, Database, HTTP Request, Webhooks. Connect to external systems.
Actionflow Studio
Actionflow Studio is the flow editor. Configure the node, then run the whole graph to see outputs and cost.
You now understand node anatomy.
This foundation powers everything in ActionFlows. When you build workflows, you are orchestrating these principles. Start building.
What is ActionFlows AI
An introduction to ActionFlows AI: the platform for building AI-powered automations visually with nodes, triggers, integrations, and models.
Handles
Understand node handles in ActionFlows: the connection points that let you wire nodes together and control how data and execution flow across the canvas.