Workflow Nodes Reference
This page documents every node available in the Vesbite workflow editor. Nodes are organized into four categories: Triggers (start a workflow), Core Actions (general-purpose logic), Device Actions (interact with devices), and Integration Actions (connect to external services).
Every node produces an output accessible via expressions: {{ output("activityId").property }}.
Here’s an interactive example combining several node types – click Run to see how execution flows through the graph:
Triggers
Triggers determine when and how a workflow starts. Each workflow has exactly one trigger.
Manual Trigger
Starts the workflow on demand via the UI or API.
Category: Core URI: vesbite://triggers/core/manual
Inputs: None.
Outputs:
| Field | Type | Description |
|---|---|---|
triggeredAt | string | ISO 8601 timestamp of when the trigger fired |
triggerType | string | Always "manual" |
When to use: Testing workflows during development, on-demand operations that a user initiates manually, or one-off tasks.
Timer Trigger
Starts the workflow on a recurring interval.
Category: Core URI: vesbite://triggers/core/timer
Inputs:
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| Interval (seconds) | number | Yes | 60 | Seconds between each trigger fire |
Outputs:
| Field | Type | Description |
|---|---|---|
triggeredAt | string | ISO 8601 timestamp |
triggerType | string | Always "timer" |
intervalSeconds | number | The configured interval |
When to use: Periodic polling, recurring checks, or any operation that should repeat at a fixed interval. Minimum resolution is 1 second.
Scheduled (Cron) Trigger
Starts the workflow on a cron schedule. Evaluates at each minute boundary.
Category: Core URI: vesbite://triggers/core/cron
Inputs:
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| Cron Expression | string | Yes | 0 * * * * | Standard 5-field cron expression |
Cron expression format:
+------------ minute (0-59)
| +---------- hour (0-23)
| | +-------- day of month (1-31)
| | | +------ month (1-12)
| | | | +---- day of week (0-6, Sunday=0)
| | | | |
* * * * *Supported syntax:
| Syntax | Meaning | Example |
|---|---|---|
* | Every value | * * * * * (every minute) |
*/n | Every n-th value | */5 * * * * (every 5 minutes) |
n | Specific value | 0 9 * * * (at 9:00 AM) |
a,b,c | List of values | 0 9,12,17 * * * (at 9 AM, noon, 5 PM) |
a-b | Range of values | 0 9 * * 1-5 (9 AM, weekdays only) |
Common examples:
| Expression | Schedule |
|---|---|
*/5 * * * * | Every 5 minutes |
0 * * * * | Every hour, on the hour |
0 9 * * * | Daily at 9:00 AM UTC |
0 9 * * 1-5 | Weekdays at 9:00 AM UTC |
0 0 1 * * | First day of every month at midnight |
30 8 * * 1 | Every Monday at 8:30 AM UTC |
Outputs:
| Field | Type | Description |
|---|---|---|
triggeredAt | string | ISO 8601 timestamp (rounded to the minute) |
triggerType | string | Always "cron" |
cronExpression | string | The evaluated cron expression |
When to use: Scheduled reports, daily data syncs, maintenance tasks, or any operation tied to clock time.
Device Event Trigger
Starts the workflow when a device emits a specific event type.
Category: Devices URI: vesbite://triggers/devices/{definitionId}/{eventName}
Each device definition generates its own Device Event trigger nodes in the workflow editor – one per event type defined in the device schema.
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Device | dropdown | No | Specific device to listen to. Leave empty for any device of this type. |
Outputs:
The output fields match the event’s payload schema. For example, a tagread event trigger outputs:
| Field | Type | Description |
|---|---|---|
epc | string | Tag EPC |
tid | string | Tag ID |
rssi | number | Signal strength |
antenna | number | Antenna port |
| (additional fields) | As defined in the event’s payload schema |
How event data is accessed:
{{ output("triggerActivityId").epc }}
{{ output("triggerActivityId").rssi }}The trigger unwraps the device event payload so fields are available directly on the output object.
When to use: Reacting to device data in real time – logging tag reads to a database, sending alerts on GPIO changes, triggering business logic when a sensor reports a value.
Core Actions
General-purpose nodes for workflow logic.
Set Variable
Stores a value in the workflow context for use by later nodes.
Category: Core URI: vesbite://actions/core/set-variable
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Variable Name | string | Yes | Name of the variable to set |
| Value | expression | Yes | The value to assign (supports Vex expressions) |
Outputs:
| Field | Type | Description |
|---|---|---|
variableName | string | The name that was set |
value | any | The value that was stored |
Example use case: Store an intermediate computation result, then reference it in multiple downstream nodes with {{ variables.myVar }}.
Log Message
Writes a message to the workflow execution log for debugging.
Category: Core URI: vesbite://actions/core/log
Inputs:
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| Message | string | Yes | The message to log (supports expressions) | |
| Log Level | dropdown | No | Information | Severity: Trace, Debug, Information, Warning, Error, Critical |
Outputs:
| Field | Type | Description |
|---|---|---|
message | string | The rendered message |
level | string | The log level used |
timestamp | string | ISO 8601 timestamp |
Example use case: Log the EPC of each tag read during development: Tag read: {{ output("trigger").epc }}.
Delay
Pauses workflow execution for a specified duration. The workflow is suspended and resumed after the delay.
Category: Core URI: vesbite://actions/core/delay
Inputs:
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| Duration (seconds) | number | Yes | 20 | Number of seconds to pause |
Outputs:
| Field | Type | Description |
|---|---|---|
startedAt | string | ISO 8601 timestamp when the delay started |
completedAt | string | ISO 8601 timestamp when the delay ended |
durationSeconds | number | Actual elapsed seconds |
Example use case: Wait 5 seconds after starting a reader before checking for tag reads, or add a cooldown between retries.
HTTP Request
Makes an HTTP request to an external URL and returns the response.
Category: Core URI: vesbite://actions/core/http-request
Inputs:
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| URL | string | Yes | Target URL (supports expressions) | |
| Method | dropdown | No | GET | HTTP method: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
| Body | code (JSON) | No | Request body for POST/PUT/PATCH |
Outputs:
| Field | Type | Description |
|---|---|---|
body | string | Response body as text |
statusCode | number | HTTP status code (e.g., 200, 404) |
isSuccess | boolean | true if status code is 2xx |
Example use case: POST tag read data to an external webhook:
- URL:
https://api.example.com/tags - Method:
POST - Body:
{ "epc": "{{ output("trigger").epc }}" }
Branch
Routes workflow execution down one of two paths based on a boolean condition.
Category: Core URI: vesbite://actions/core/branchHandles: True, False
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Condition | boolean/variable | Yes | The condition to evaluate |
Outputs:
| Field | Type | Description |
|---|---|---|
result | boolean | The evaluated condition value |
branch | string | "True" or "False" |
The Branch node has two output handles. Connect downstream nodes to the True handle for when the condition is truthy, and the False handle for when it is falsy.
Example use case: Check if a tag’s RSSI is above a threshold, then take different actions for strong vs. weak reads.
Device Actions
Nodes that interact with physical devices. These nodes are dynamically generated from device definitions.
Invoke Device Action
Sends a command to a device and returns the result.
Category: Devices URI: vesbite://actions/devices/{definitionId}/{actionName}
Each device definition generates Invoke Device Action nodes for every action in its schema. They appear in the workflow editor grouped under the device type.
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Device | dropdown | Yes | The specific device to invoke the action on |
| Parameters | code (JSON) | No | Action parameters as a JSON object (supports expressions) |
Outputs:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the action succeeded |
deviceId | string | The target device ID |
payload | string | JSON string of the device’s response data |
Example use case: Start reading on an RFID reader, then process the response to confirm the session began.
Update Device Settings
Pushes new settings values to a device.
Category: Devices URI: vesbite://actions/devices/{definitionId}/update-settings
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Device | dropdown | Yes | The device to update |
| Settings | code (JSON) | Yes | JSON object of settings to apply |
Outputs:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the settings update succeeded |
message | string | Success or error message |
deviceId | string | The target device ID |
Example use case: Dynamically adjust reader transmit power based on the time of day or tag population estimates.
Integration Actions
Airtable
Requires an Airtable connection. All Airtable nodes share the Connection and Base ID inputs.
List Bases
Lists all Airtable bases the authenticated user can access.
URI: vesbite://actions/integrations/airtable/list-bases
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Offset | string | No | Pagination offset |
Outputs: Airtable API response containing bases array with id, name, and permissionLevel for each base.
Get Base Schema
Returns the schema (tables and fields) for a base.
URI: vesbite://actions/integrations/airtable/get-base-schema
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | The base to inspect |
Outputs: Airtable API response containing tables array with field definitions.
List Records
Retrieves records from a table with optional filtering and pagination.
URI: vesbite://actions/integrations/airtable/list-records
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Fields | checklist | No | Specific fields to return (empty = all) |
| Filter Formula | string | No | Airtable formula (e.g., {Status} = 'Active') |
| Max Records | number | No | Maximum records to return |
| Page Size | number | No | Records per page (max 100). Default: 100 |
| Offset | string | No | Pagination offset from a previous response |
| View | string | No | View ID or name to filter by |
Outputs: Airtable API response with records array and optional offset for pagination.
Get Record
Retrieves a single record by ID.
URI: vesbite://actions/integrations/airtable/get-record
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Record ID | string | Yes | Record ID (e.g., recXXXXXXXXXXXXXX) |
Outputs: Single record object with id, fields, and createdTime.
Create Record
Creates a single record in a table.
URI: vesbite://actions/integrations/airtable/create-record
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Fields | code (JSON) | Yes | Record fields as JSON object |
| Typecast | boolean | No | Convert string values to field types. Default: false |
Outputs: The created record object with id, fields, and createdTime.
Example use case: Log each RFID tag read to an Airtable table:
{ "EPC": "{{ output('trigger').epc }}", "Antenna": "{{ output('trigger').antenna }}", "Timestamp": "{{ output('trigger').timestamp }}" }Update Record
Updates a single record.
URI: vesbite://actions/integrations/airtable/update-record
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Record ID | string | Yes | Record to update |
| Fields | code (JSON) | Yes | Fields to update |
| Typecast | boolean | No | Convert string values to field types |
Outputs: The updated record object.
Delete Record
Deletes a single record.
URI: vesbite://actions/integrations/airtable/delete-record
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Record ID | string | Yes | Record to delete |
Outputs: Confirmation with id and deleted: true.
Create Records (Batch)
Creates multiple records in a single API call (max 10 per request).
URI: vesbite://actions/integrations/airtable/create-records
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Records | code (JSON) | Yes | Array of { fields: {...} } objects |
| Typecast | boolean | No | Convert string values to field types |
Outputs: Array of created records.
Update Records (Batch)
Updates multiple records in a single API call.
URI: vesbite://actions/integrations/airtable/update-records
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Records | code (JSON) | Yes | Array of { id, fields: {...} } objects |
| Typecast | boolean | No | Convert string values to field types |
Outputs: Array of updated records.
Delete Records (Batch)
Deletes multiple records in a single API call.
URI: vesbite://actions/integrations/airtable/delete-records
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Airtable OAuth connection |
| Base ID | dropdown | Yes | Target base |
| Table | dropdown | Yes | Target table |
| Record IDs | string | Yes | Comma-separated record IDs |
Outputs: Array of { id, deleted: true } objects.
SendGrid
Send Email
Sends an email through SendGrid.
URI: vesbite://actions/integrations/sendgrid/send-email
Requires a SendGrid connection.
Inputs:
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | SendGrid API key connection |
| From | string | Yes | Sender email address |
| To | string | Yes | Recipient email address |
| Subject | string | Yes | Email subject line |
| Body | text (multiline) | Yes | Plain text body |
| HTML Body | text (multiline) | No | HTML body (optional) |
Outputs:
| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP status code from SendGrid |
success | boolean | Whether the send succeeded |
body | string | Response body from SendGrid |
Example use case: Send an alert email when a high-value tag is read, including the tag EPC and timestamp in the email body.
Database Nodes
All database nodes require a connection configured in the Integrations page.
PostgreSQL
Run QueryURI: vesbite://actions/integrations/postgres/run-query
Executes a SELECT query and returns rows.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | PostgreSQL connection |
| Query | code (SQL) | Yes | SQL SELECT statement |
| Parameters | code (JSON) | No | Named parameters (e.g., {"name": "value"}) |
| Output | Type | Description |
|---|---|---|
rowCount | number | Number of rows returned |
rows | array | Array of row objects |
Execute Non-QueryURI: vesbite://actions/integrations/postgres/execute-non-query
Executes INSERT, UPDATE, or DELETE and returns the affected row count.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | PostgreSQL connection |
| SQL Statement | code (SQL) | Yes | SQL statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
affectedRows | number | Number of rows affected |
Execute ScalarURI: vesbite://actions/integrations/postgres/execute-scalar
Executes a query and returns the first column of the first row.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | PostgreSQL connection |
| Query | code (SQL) | Yes | SQL query returning a single value |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
value | any | The scalar result |
MySQL
Run QueryURI: vesbite://actions/integrations/mysql/run-query
Same interface as PostgreSQL Run Query.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | MySQL connection |
| Query | code (SQL) | Yes | SQL SELECT statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
rowCount | number | Number of rows returned |
rows | array | Array of row objects |
Execute Non-QueryURI: vesbite://actions/integrations/mysql/execute-non-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | MySQL connection |
| SQL Statement | code (SQL) | Yes | SQL statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
affectedRows | number | Number of rows affected |
SQL Server
Run QueryURI: vesbite://actions/integrations/sqlserver/run-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | SQL Server connection |
| Query | code (SQL) | Yes | SQL SELECT statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
rowCount | number | Number of rows returned |
rows | array | Array of row objects |
Execute Non-QueryURI: vesbite://actions/integrations/sqlserver/execute-non-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | SQL Server connection |
| SQL Statement | code (SQL) | Yes | SQL statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
affectedRows | number | Number of rows affected |
Oracle
Run QueryURI: vesbite://actions/integrations/oracle/run-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Oracle connection |
| Query | code (SQL) | Yes | SQL SELECT statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
rowCount | number | Number of rows returned |
rows | array | Array of row objects |
Execute Non-QueryURI: vesbite://actions/integrations/oracle/execute-non-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Oracle connection |
| SQL Statement | code (SQL) | Yes | SQL statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
affectedRows | number | Number of rows affected |
Snowflake
Run QueryURI: vesbite://actions/integrations/snowflake/run-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Snowflake connection |
| Query | code (SQL) | Yes | SQL SELECT statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
rowCount | number | Number of rows returned |
rows | array | Array of row objects |
Execute Non-QueryURI: vesbite://actions/integrations/snowflake/execute-non-query
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Snowflake connection |
| SQL Statement | code (SQL) | Yes | SQL statement |
| Parameters | code (JSON) | No | Named parameters |
| Output | Type | Description |
|---|---|---|
affectedRows | number | Number of rows affected |
MongoDB
Find DocumentsURI: vesbite://actions/integrations/mongodb/find-documents
Queries documents from a collection.
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| Connection | connection | Yes | MongoDB connection | |
| Database | string | Yes | Database name | |
| Collection | string | Yes | Collection name | |
| Filter | code (JSON) | No | {} | MongoDB query filter (e.g., {"status": "active"}) |
| Limit | number | No | 100 | Maximum documents to return |
| Output | Type | Description |
|---|---|---|
count | number | Number of documents returned |
documents | array | Array of document objects |
Insert DocumentURI: vesbite://actions/integrations/mongodb/insert-document
Inserts a document into a collection.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | MongoDB connection |
| Database | string | Yes | Database name |
| Collection | string | Yes | Collection name |
| Document | code (JSON) | Yes | JSON document to insert |
| Output | Type | Description |
|---|---|---|
insertedId | string | The _id of the inserted document |
Redis
Get ValueURI: vesbite://actions/integrations/redis/get-value
Retrieves a string value by key.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Redis connection |
| Key | string | Yes | The key to retrieve |
| Output | Type | Description |
|---|---|---|
key | string | The requested key |
value | string or null | The stored value, or null if the key does not exist |
exists | boolean | Whether the key exists |
Set ValueURI: vesbite://actions/integrations/redis/set-value
Stores a string value at a key.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Redis connection |
| Key | string | Yes | The key to set |
| Value | string | Yes | The value to store |
| Expiration (seconds) | number | No | Optional TTL in seconds |
| Output | Type | Description |
|---|---|---|
key | string | The key that was set |
success | boolean | Whether the operation succeeded |
Elasticsearch
Search DocumentsURI: vesbite://actions/integrations/elasticsearch/search-documents
Searches an index.
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| Connection | connection | Yes | Elasticsearch connection | |
| Index | string | Yes | Index name | |
| Query | code (JSON) | No | match_all | Search query as JSON |
| Size | number | No | 10 | Maximum results |
| Output | Type | Description |
|---|---|---|
total | number | Total matching documents |
hits | array | Array of matched documents |
Index DocumentURI: vesbite://actions/integrations/elasticsearch/index-document
Indexes (upserts) a document.
| Input | Type | Required | Description |
|---|---|---|---|
| Connection | connection | Yes | Elasticsearch connection |
| Index | string | Yes | Index name |
| Document ID | string | No | Document ID (auto-generated if omitted) |
| Document | code (JSON) | Yes | JSON document to index |
| Output | Type | Description |
|---|---|---|
id | string | The document ID |
index | string | The index name |
result | string | Operation result (e.g., "created", "updated") |
See Also
- Vex Expressions Reference – Expression syntax for node inputs and accessing outputs
- Events Reference – Device event types that feed into Device Event triggers
- Actions Reference – Device action definitions used by Invoke Device Action nodes
- How to Build a Flow