How to Build a Flow
Flows are visual workflows that connect triggers to actions. When something happens (a device reads a tag, a timer fires, a webhook arrives), your flow executes a series of steps — logging data, calling APIs, updating records, branching on conditions, and more. This guide walks you through building a flow from scratch.
Prerequisites
- A Vesbite account
- At least one adopted device or configured integration (depending on what your flow will do)
Creating a New Flow
Step 1: Navigate to Flows
Click Flows in the sidebar to see your existing workflows. Each flow shows its name, status (Draft or Published), and last modified date.
Step 2: Create a Flow
Click Create Flow in the top-right corner. A new flow opens in the visual builder with an empty canvas.
The Flow Canvas
Here’s an interactive example of a flow running a periodic health check. Press Run to watch execution flow through each node:
The canvas is your workspace for building flows. Here are the controls:
| Action | How |
|---|---|
| Pan | Click and drag on empty canvas space |
| Zoom | Scroll wheel, or use the zoom controls in the bottom-left corner |
| Fit to view | Click the fit-to-view button in the bottom-left controls to zoom and pan so all nodes are visible |
| Select a node | Click on it |
| Select multiple nodes | Hold Shift and click, or drag a selection box |
| Delete a node | Select it and press Delete or Backspace |
| Move a node | Click and drag it |
Adding a Trigger
Every flow starts with a trigger — the event that kicks off the workflow.
Step 1: Open the Activity Picker
Click Add First Trigger in the center of an empty canvas (or click the + button if you already have nodes). The activity picker drawer slides in from the right.
Step 2: Browse or Search
The activity picker organizes triggers and actions into categories:
| Category | Contains |
|---|---|
| Devices | Device Event (tag reads, status changes), Invoke Device Action, Update Device Settings |
| Core | Timer, Cron, Manual Trigger, Set Variable, Log, Delay, Branch, HTTP Request |
| Integrations | Airtable, SendGrid, Salesforce, HubSpot, database queries, and more |
Use the search bar at the top to find specific activities by name, or browse by category.
Step 3: Select a Trigger
Click a trigger to add it to the canvas. Available trigger types:
| Trigger | When It Fires |
|---|---|
| Device Event | When a device emits an event (e.g., a tag is read, a button is pressed) |
| Timer | After a set delay from when the flow is published |
| Cron | On a recurring schedule (e.g., every 5 minutes, daily at 9am) |
| Manual | When you click the Run button in the flow builder |
Step 4: Configure the Trigger
Double-click the trigger node to open its settings panel on the left side of the screen. Configure the trigger’s options:
- Device Event trigger: Select the device and the event type to listen for
- Cron trigger: Enter a cron expression or use the visual scheduler
- Timer trigger: Set the delay duration
- Manual trigger: No configuration needed
Click Save to apply the trigger configuration.
Adding Action Nodes
From the + Button
Click the + button that appears below any node. The activity picker opens showing only actions (not triggers). Select an action to add it below the current node. It is automatically connected.
From the Activity Picker
You can also open the activity picker at any time by clicking the add activity button in the toolbar. Drag an activity from the picker onto the canvas to place it freely, then connect it manually.
Available Action Types
Core Actions
| Action | What It Does |
|---|---|
| Set Variable | Store a value for use in later nodes. Variables persist for the duration of the flow run. |
| Log | Write a message to the flow’s run log. Useful for debugging. |
| Delay | Pause execution for a specified duration before continuing. |
| HTTP Request | Make an HTTP call to any URL. Configure method, headers, body, and parse the response. |
| Branch | Split the flow into two paths based on a condition. See Use Branching. |
Device Actions
| Action | What It Does |
|---|---|
| Invoke Device Action | Send a command to a device (e.g., Start Reading, Encode Tag). |
| Update Device Settings | Push new settings to a device (e.g., change TX power). |
Integration Actions
| Action | What It Does |
|---|---|
| Airtable | Create, read, update, or delete records in an Airtable base. |
| SendGrid | Send emails via SendGrid. |
| Salesforce | Create, read, update, or delete Salesforce records. |
| Database Query | Run SQL or NoSQL queries against PostgreSQL, MySQL, MongoDB, or SQL Server. |
See Set Up an Integration for connecting these services.
Connecting Nodes
Nodes have handles — small circles on their edges — that define how data flows between them.
| Handle | Position | Purpose |
|---|---|---|
| Input | Top of the node | Receives the flow of execution from a previous node |
| Output | Bottom of the node | Passes execution to the next node |
| Error | Bottom-right of the node (red) | Routes execution when the node encounters an error |
To connect two nodes manually:
- Hover over the output handle at the bottom of the source node
- Click and drag to the input handle at the top of the target node
- Release to create the connection (edge)
To remove a connection, click the edge line and press Delete.
Configuring Nodes
Opening the Settings Panel
Double-click any node to open its settings panel on the left side of the canvas. The panel shows the node’s name, description, and all configurable inputs.
Input Types
Node inputs accept different types of values depending on the field:
| Input Type | Description |
|---|---|
| Literal value | A fixed value you type directly (text, number, boolean) |
| Expression | A dynamic Vex expression that is evaluated at runtime. Toggle between literal and expression mode using the mode switcher on each field. |
| Connection selector | A dropdown to pick an integration connection (appears on integration nodes) |
| Code editor | A full Monaco editor for SQL queries, JSON bodies, or other code (appears on HTTP Request, Database Query, and similar nodes) |
| Dropdown | Select from a list of predefined options |
Using the Expression Editor
When you switch a field to expression mode, it opens a Monaco-based editor with:
- Autocomplete — Type
{{to start an expression and see suggestions for variables, outputs, and filters - Variable chips — Visual pills that represent variables and outputs, making expressions easier to read
- Variable picker — A sidebar panel listing all available variables and outputs from previous nodes that you can click to insert
See Use Expressions for a complete guide to the expression syntax.
Saving, Publishing, and Running
Auto-save
Your flow is automatically saved as a draft as you work. You will see a “Saved” indicator in the toolbar. Drafts are not active — they do not execute when triggers fire.
Publishing
To make your flow active:
- Click the workflow menu (three dots) in the toolbar
- Select Publish
- Your flow is now live. The status badge changes from “Draft” to “Published.”
Once published, the flow executes whenever its trigger condition is met.
Unpublishing
To deactivate a flow without deleting it, open the workflow menu and select Unpublish. The flow returns to draft status and stops executing.
Running Manually
Click the Run button in the toolbar to execute the flow immediately, regardless of its trigger type. This is useful for testing. The run log opens automatically so you can watch execution in real time.
Monitoring Runs
After a flow runs (manually or via trigger), you can view the run history:
- Click the Runs tab in the flow builder
- Each run shows its status (Success, Failed, Running), start time, and duration
- Click a run to see the execution log, including inputs and outputs for each node
Version History
Vesbite keeps a history of your flow’s published versions. To view or restore a previous version:
- Open the workflow menu
- Select Version History
- Browse previous versions by date
- Click Restore to revert to a previous version (this creates a new draft)
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Ctrl+S / Cmd+S | Save flow |
Ctrl+Shift+S / Cmd+Shift+S | Save and publish |
Ctrl+Enter / Cmd+Enter | Run flow |
Ctrl+/ / Cmd+/ | Show keyboard shortcut help |
Delete / Backspace | Delete selected node or edge |
Ctrl+Z / Cmd+Z | Undo |
Ctrl+Shift+Z / Cmd+Shift+Z | Redo |
Ctrl+A / Cmd+A | Select all nodes |
Tips for Effective Flows
Start with a Manual trigger for testing. Build and test your flow logic with a Manual trigger first. Once everything works, swap it for a Device Event or Cron trigger for production.
Use Set Variable to simplify expressions. If you reference the same complex expression in multiple nodes, store it in a variable with Set Variable first, then reference {{ variables.myVar }} everywhere else.
Add Log nodes during development. Drop Log nodes between steps to see intermediate values in the run log. Remove them before publishing to production.
Handle errors with error handles. Every node has an error handle (red circle). Connect it to a recovery path — send an alert, log the error, or retry the operation.
Keep flows focused. Build one flow per use case rather than one giant flow that does everything. Smaller flows are easier to debug and maintain.
Use Branch nodes for conditional logic. Route your flow based on data values rather than trying to handle every case in a single path. See Use Branching.
Next Steps
- Use Expressions — Learn the Vex expression language for dynamic values
- Use Branching — Add conditional logic to your flows
- Set Up an Integration — Connect external services
- Trigger Device Actions — Control devices from your flows