Building Flows in the Flow Editor
Learn how to create and manage workflows using RAPFlow's visual Flow Editor
Flow Editor Overview
The Flow Editor consists of several key areas:
- Palette (Left Side): Contains all available blocks organized by category
- Workspace (Center): The main canvas where you build your flows by dragging and connecting blocks
- Sidebar (Right Side): Configure selected blocks, view help, debug messages, and manage configuration
- Toolbar (Top): Save, deploy, and manage your flows
Core Concepts
Understanding these fundamental concepts will help you build effective workflows:
Blocks (Nodes)
A Block is the basic building block of a flow. Blocks are triggered by either receiving a message from the previous block in a flow, or by waiting for some external event, such as an incoming HTTP request or a timer. They process that message or event, and then may send a message to the next blocks in the flow.
A block can have at most one input port and as many output ports as it requires.
Messages
Messages are what pass between the blocks in a flow. They are plain JavaScript objects that can have any set of properties. By convention, they have a payload property containing the most useful information.
Message Structure
{
"payload": "The main data content",
"topic": "Optional message topic",
"headers": { "Content-Type": "application/json" },
"_msgid": "unique-message-identifier"
}Important Message Behavior
⚠️ Critical: Message Property Override
The msg.payload property will be overridden by each block as it processes the message. If you want a property to persist throughout the entire flow, you should store it in one of these locations:
- Global Context:
global.set('key', value)- accessible across all flows - Flow Context:
flow.set('key', value)- accessible within the current flow - Custom Message Properties:
msg['any_key']- will not be overridden by blocks
Example:
// ❌ This will be overridden by the next block
msg.payload = "important data";
// ✅ These will persist throughout the flow
msg["important_data"] = "this will not be overridden";
flow.set("flow_data", "persists in this flow");
global.set("shared_data", "persists across all flows");Setting Required Input for Next Block:
If the next block requires specific input parameters, you can set those keys in the payload:
// Set required input parameters for the next block
msg.payload = {
input_text: "text to process",
model: "gpt-4",
temperature: 0.7,
max_tokens: 100,
};This ensures the next block receives all the required parameters it needs to function properly.
Function Block Output Behavior
When using Function blocks, be aware that:
- Return Statement: If you return a value, it will replace the entire message object
- Message Mutation: If you modify
msgproperties and don't return anything, the modified message continues - Property Loss: Returning a new object may lose other message properties
Examples:
// ✅ Safe: Modify existing message
msg.payload = "new payload";
msg.customProperty = "added property";
return msg; // or just return; (implicit)
// ⚠️ Risky: Returning new object loses other properties
return { payload: "new payload" }; // Loses _msgid, topic, etc.
// ✅ Safe: Preserve all properties while updating payload
return { ...msg, payload: "new payload" };Message Property Types
Message properties can contain any valid JavaScript type:
- Boolean:
true,false - Number:
0,123.4 - String:
"hello" - Array:
[1,2,3,4] - Object:
{ "a": 1, "b": 2 } - Null:
null
Working with JSON
If a message property contains a JSON string, it must be parsed to a JavaScript object before accessing its properties:
// Parse JSON string to object
const data = JSON.parse(msg.payload);
msg.payload = data.someProperty;Flows
A Flow is represented as a tab within the editor workspace and is the main way to organize blocks. The term "flow" is also used to describe a single set of connected blocks. So a flow (tab) can contain multiple flows (sets of connected blocks).
Wires
Wires connect the blocks and represent how messages pass through the flow. You create wires by dragging from the output port of one block to the input port of another.
Message Sequences
A message sequence is an ordered series of messages that are related in some way. For example, the Split block can turn a single message whose payload is an Array, into a message sequence where each message has a payload corresponding to one of the array elements.
Understanding msg.parts
Each message in a sequence has a property called msg.parts. This is an object that contains information about how the message fits in the sequence:
msg.parts.id: A unique identifier for the sequencemsg.parts.index: The message's position within the sequencemsg.parts.count: If known, the total number of messages in the sequence
Working with Sequences
Several core blocks can work across message sequences:
- Split: Turns a single message into a sequence of messages
- Join: Turns a sequence of messages into a single message
- Sort: Sorts the sequence based on a property value
- Batch: Creates new sequences of messages from those received
Debugging Messages
The easiest way to understand the structure of a message is to pass it to a Debug block and view it in the Debug sidebar. The Debug block can be configured to display any property or the whole message, providing a structured view to explore message contents.
Conditional Routing with Switch Block
The Switch block allows you to route messages to different output paths based on conditions. This is useful for creating branching logic in your flows.
Switch Block Configuration
- Select the Switch block from the palette
- Configure conditions in the properties panel:
- Set the property to check (e.g.,
msg.payload,msg.topic,msg.category) - Define the condition (equals, contains, regex, etc.)
- Set the value to match against
- Set the property to check (e.g.,
Common Switch Patterns
Route by Message Topic:
// Route messages based on their topic
msg.topic = "urgent"; // Goes to output 1
msg.topic = "normal"; // Goes to output 2
msg.topic = "low"; // Goes to output 3Route by Payload Content:
// Route based on payload values
msg.payload = "error"; // Goes to error handling
msg.payload = "success"; // Goes to success processing
msg.payload = "pending"; // Goes to pending queueRoute by Data Type:
// Route based on payload data type
msg.payload = "text data"; // String processing
msg.payload = [1, 2, 3]; // Array processing
msg.payload = { key: "value" }; // Object processingSwitch Block Outputs
- Output 1, 2, 3...: Routes messages that match specific conditions
- Otherwise: Routes messages that don't match any defined conditions
- All: Routes all messages regardless of conditions (useful for logging)
Best Practices
- Use Clear Conditions: Make your switch conditions explicit and easy to understand
- Handle Default Cases: Always configure the "Otherwise" output for unmatched messages
- Test All Paths: Ensure each output path is properly connected and tested
- Document Logic: Use comments to explain complex routing logic
Configuration Nodes
A Configuration Node is a special type of block that holds reusable configuration that can be shared by regular blocks in a flow. For example, database connection settings or API credentials.
Config nodes do not appear in the main workspace, but can be seen by opening the Configuration nodes sidebar.
Basic Flow Building Process
1. Starting a New Flow
- Open the Flow Editor by navigating to your project
- Click on "Open Flow Editor" to access the visual workflow builder
- The editor will open with an empty canvas ready for building if this project does not have any flows
2. Adding Blocks to Your Flow
- Browse the Palette: Look through the left panel to find the blocks you need
- Drag and Drop: Click and drag blocks from the palette onto the canvas
- Connect Blocks: Click and drag from one block's output port to another block's input port
- Configure Blocks: Select a block to view its configuration options in the properties panel
3. Connecting Blocks
Blocks are connected using wires that carry data between them:
- Output Ports: Located on the right side of blocks
- Input Ports: Located on the left side of blocks
- Data Flow: Information flows from left to right through your workflow
To connect blocks:
- Click on an output port (right side of a block)
- Drag to the input port of the target block (left side)
- Release to create the connection
4. Configuring Block Properties
Each block has configurable properties:
- Select a Block: Click on any block in your flow
- Properties Panel: View configuration options on the right side
- Required Fields: Fill in any required configuration parameters
- Optional Settings: Adjust optional parameters as needed
5. Testing Your Flow
Before deploying, test your flow:
- Save: Click the "Save" button to save your changes in the Flow Editor
- Trigger: Use inject blocks or http in block to start your flow
- Debug: Use debug blocks to monitor data flow and troubleshoot issues
- Iterate: Modify and save as needed
Flow Design Best Practices
Start Simple
- Begin with basic flows and gradually add complexity
- Test each component before adding the next
- Use debug blocks to monitor data flow
Organize Your Flow
- Group related blocks together
- Use comments to document complex logic
- Keep flows readable with clear naming conventions
Error Handling
- Use catch blocks to handle errors gracefully
- Implement fallback logic for critical processes
- Add logging and debugging capabilities
HTTP Flow Error Handling
When using HTTP In and HTTP Response blocks in your flows, it's important to implement proper error handling:
- Add Catch Blocks: Connect catch blocks to your HTTP In block to catch errors during flow execution
- Error Response: Errors caught by catch blocks will be returned as the flow response to the client
- Graceful Degradation: Implement fallback responses for different error scenarios
Performance Considerations
- Minimize unnecessary data transformations
- Use batch processing for large datasets
- Consider flow execution order for optimal performance
Common Flow Patterns
Document Processing Pipeline
Input → OCR → Text Processing → Classification → OutputData Validation Workflow
Input → Validation → Transform → Store → NotifyAI Analysis Flow
Document → Extract → Analyze → Score → DecisionConsuming Flows with HTTP Endpoints
To make your flows accessible as web services or APIs, wrap them with HTTP blocks:
Creating HTTP Endpoints
- Start with HTTP In: Add an
http inblock to receive requests - Build Your Flow: Add your processing blocks (OCR, AI, etc.)
- End with HTTP Response: Add an
http responseblock to send results back
Basic HTTP Flow Pattern
http in → [your processing blocks] → http responseDeployment
- Save Your Flow: Click the "Save" button in the Flow Editor to save your changes
- Navigate to Flow AI Screen: Go to the Flow AI section of your project
- Find Your Flow Project: Locate the flow project containing your saved flows
- Click Deploy: Click the "Deploy" button on your flow project to deploy all flows
- Copy Consumer API: Once deployed, you can copy the consumer API endpoint for integration
Once deployed, your flow will be accessible via HTTP requests at the configured endpoint. You need to send an API key for running this flow through the API.
API Request Handling
Request Body Processing
When you make an API request to your deployed flow:
- Request body is automatically sent to the
msg.payloadin the HTTP In block - Headers are available in
msg.headers - Query parameters are accessible in
msg.query
Flow Execution Timeout
Default Timeout Duration: 8 minutes
- Maximum Duration: HTTP flows have a default maximum execution time of 8 minutes
- Timeout Response: If the flow exceeds this duration, the response will be:
"flow timeout max duration exceeded" - Planning Consideration: Design your flows to complete within this timeframe or implement asynchronous processing for longer operations
File Upload Handling
Single File Upload
To send a single file to your flow:
- Use Form Data: Send the file using
multipart/form-data - Header Key: Use
fileas the form field name - File Processing: The file is automatically uploaded to platform common storage
- Access in Flow: The file path is available in
msg.payload.filename
Example:
// In your flow, access the uploaded file
const filePath = msg.payload.filename;
// Use this path with blocks that require file processing (OCR, document processing, etc.)Multiple File Upload
When sending multiple files:
- All files will have the same name as specified in the request body
- File paths are available in
msg.payload.filename(array of file paths) - Process each file by iterating through the array
Example:
// Handle multiple files
if (Array.isArray(msg.payload.filename)) {
// Process each file
msg.payload.filename.forEach((filePath, index) => {
// Process file at filePath
});
} else {
// Single file
const filePath = msg.payload.filename;
}Generating API Keys
To generate a new API key in RAPFlow:
- Go to the API Keys section in the sidebar
- Click on "Generate API Key"
- Add a name and description for your API key
- Select the organization
- Click "Create" to generate the new API key
- Use the newly created API key when calling the flow API
API Request Examples:
import requests
import time
# URL and headers
url = "https://workshop.rapidautomation.ai/console-api/v1/queue/flow/submit/chat-tech-docs/68c81a53ee4bfa9f0220a4d5"
headers = {
'x-api-key': '<api key copied from RAPFlow>'
}
# Make the initial request
response = requests.post(url, headers=headers)
result = response.json()
print("Initial response:", result)
# Poll for results using resultUrl
if 'resultUrl' in result:
result_url = result['resultUrl']
print(f"Polling for results at: {result_url}")
while True:
poll_response = requests.get(result_url, headers=headers)
poll_result = poll_response.json()
if poll_result.get('status') == 'completed':
print("Final result:", poll_result)
break
elif poll_result.get('status') == 'failed':
print("Flow execution failed:", poll_result)
break
else:
print(f"Status: {poll_result.get('status', 'processing')}")
time.sleep(2) # Wait 2 seconds before next pollNext Steps
- Explore the Blocks Reference to learn about all available components
- Check out Use Cases for real-world examples
- Review the FAQ for common questions and troubleshooting
Need help? Check our troubleshooting guide or reach out to support.