Reference · Tools

Data Table

Permanently save, retrieve, update, and delete structured data across workflow executions in built-in tables

Action Core Nodes v1

Data Table gives your workflows a built-in database — typed columns, automatic system fields, and full CRUD operations without connecting to any external service. Use it to track form submissions across runs, maintain a running list of processed records, or gate workflow logic on whether a row already exists.

Node type
Action
Parameters
26
Outputs
Output, Error
Credentials
None required

Data Table

Save and query structured data persistently across workflow executions

Overview

Data Table provides persistent tabular storage within the workflow platform. It supports typed columns (string, number, boolean, date), CRUD operations on rows, table management, conditional pass-through (row exists/not exists), filtering with multiple condition types, sorting, pagination, and bulk insert optimization. System columns (id, createdAt, updatedAt) are added automatically. This is an internal storage mechanism — no external API or credentials required.

Category: Core Nodes
Tool Name: data_table
Version: 1

Appearance: Icon: lucide-Database | Color: #FF6D5A

Node Type

Action — processes input items and produces output

Input / Output

DirectionPort(s)
InputInput
OutputOutput, Error

Credentials

This tool does not require any credentials.

Resources

ResourceValue
Rowrow
Tabletable

Operations

Rows (resource is row):

OperationValueDescription
DeletedeleteRowsDelete row(s)
GetgetGet row(s)
If Row ExistsrowExistsMatch input items that are in the data table
If Row Does Not ExistrowNotExistsMatch input items that are not in the data table
InsertinsertInsert a new row
UpdateupdateUpdate row(s) matching certain fields
UpsertupsertUpdate row(s), or insert if there is no match

Tables (resource is table):

OperationValueDescription
CreatecreateCreate a new data table
DeletedeleteDelete a data table
ListlistList all data tables
UpdateupdateUpdate a data table name

Parameters

Row: Insert

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Column Mapping ModeoptionsNodefineBelowWhether to map input item fields automatically or define column values explicitly. Auto-map copies input JSON and strips system columns (id, createdAt, updatedAt).
Options: autoMapInputData, defineBelow
Column ValuesjsonNo{}JSON object with column names as keys and values to set. Example: {“name”: “John”, “age”: 30, “active”: true}. (shown when Column Mapping Mode is defineBelow)
Optimize BulkbooleanNofalseWhether to improve bulk insert performance by not returning inserted data (returns count only).

Row: Get

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Must MatchoptionsNoanyConditionWhether rows must match any condition (OR) or all conditions (AND).
Options: anyCondition, allConditions
Filter ConditionsjsonNo[]Array of filter conditions. Each condition: { “keyName”: “columnName”, “condition”: “eq|neq|gt|gte|lt|lte|like|ilike|isEmpty|isNotEmpty|isTrue|isFalse”, “keyValue”: “value” }. The keyValue field is not needed for isEmpty, isNotEmpty, isTrue, and isFalse conditions.
Return AllbooleanNofalseWhether to return all results or only up to a given limit.
LimitnumberNo50Max number of results to return. (shown when Return All is false)
Order BybooleanNofalseWhether to sort the results by a column.
Order By ColumnstringNocreatedAtThe column name to sort by. Must match an existing column in the data table. (shown when Order By is true)
Order By DirectionoptionsNoDESCSort direction for the column. (shown when Order By is true)
Options: ASC, DESC

Row: Update

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Must MatchoptionsNoanyConditionWhether rows must match any condition (OR) or all conditions (AND).
Options: anyCondition, allConditions
Filter ConditionsjsonNo[]Array of filter conditions selecting the rows to update. At least one condition is required.
Column Mapping ModeoptionsNodefineBelowWhether to map input item fields automatically or define column values explicitly. Auto-map copies input JSON and strips system columns (id, createdAt, updatedAt).
Options: autoMapInputData, defineBelow
Column ValuesjsonNo{}JSON object with column names as keys and values to set. Example: {“name”: “John”, “age”: 30, “active”: true}. (shown when Column Mapping Mode is defineBelow)
Dry RunbooleanNofalseWhether to simulate the operation and return affected rows without committing changes.

Row: Upsert

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Must MatchoptionsNoanyConditionWhether rows must match any condition (OR) or all conditions (AND).
Options: anyCondition, allConditions
Filter ConditionsjsonNo[]Array of filter conditions deciding whether a matching row already exists. At least one condition is required.
Column Mapping ModeoptionsNodefineBelowWhether to map input item fields automatically or define column values explicitly. Auto-map copies input JSON and strips system columns (id, createdAt, updatedAt).
Options: autoMapInputData, defineBelow
Column ValuesjsonNo{}JSON object with column names as keys and values to set. Example: {“name”: “John”, “age”: 30, “active”: true}. (shown when Column Mapping Mode is defineBelow)
Dry RunbooleanNofalseWhether to simulate the operation and return affected rows without committing changes.

Row: Delete

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Must MatchoptionsNoanyConditionWhether rows must match any condition (OR) or all conditions (AND).
Options: anyCondition, allConditions
Filter ConditionsjsonNo[]Array of filter conditions selecting the rows to delete. At least one condition is required.
Dry RunbooleanNofalseWhether to simulate the operation and return affected rows without committing changes.

Row: If Row Exists

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Must MatchoptionsNoanyConditionWhether rows must match any condition (OR) or all conditions (AND).
Options: anyCondition, allConditions
Filter ConditionsjsonNo[]Array of filter conditions the item is tested against.

Row: If Row Does Not Exist

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table. You can find table IDs in the data tables management page.
Must MatchoptionsNoanyConditionWhether rows must match any condition (OR) or all conditions (AND).
Options: anyCondition, allConditions
Filter ConditionsjsonNo[]Array of filter conditions the item is tested against.

Table: Create

ParameterTypeRequiredDefaultDescription
Table NamestringYesThe name of the data table to create.
ColumnsjsonNo[]Array of column definitions for the new table. Each column: {“name”: “columnName”, “type”: “string|number|boolean|date”}. System columns (id, createdAt, updatedAt) are added automatically.
Reuse Existing TablesbooleanNotrueWhether to return an existing table with the same name instead of throwing an error.

Table: List

ParameterTypeRequiredDefaultDescription
Return AllbooleanNotrueWhether to return all tables or only up to a given limit.
LimitnumberNo50Max number of tables to return. (shown when Return All is false)
Filter by NamestringNoFilter data tables by name (case-insensitive).
Sort FieldoptionsNonameField to sort the table list by.
Options: createdAt, name, updatedAt
Sort DirectionoptionsNoascSort direction for the table list.
Options: asc, desc

Table: Update

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table to operate on.
New NamestringYesThe new name for the data table.

Table: Delete

ParameterTypeRequiredDefaultDescription
Data TablestringYesThe ID or name of the data table to operate on.

All Operations

ParameterTypeRequiredDefaultDescription
Max ConcurrencynumberNo10Maximum number of items to process concurrently.

Output Data

Except for the two conditional operations, this node replaces the item JSON with the operation’s result and does not forward binary data. Read anything you still need from the item before this node, or send it down a parallel branch.

Resource and operationItems out and what is on them
Row: insertOne item holding the inserted row, including the system columns id, createdAt and updatedAt. With Optimize Bulk on, a count result is returned instead of the row data.
Row: getOne item per matching row. A query that matches nothing produces no output items at all.
Row: updateOne item per updated row.
Row: upsertOne item per row that was updated or inserted.
Row: deleteRowsOne item per deleted row.
Row: rowExistsThe original input item, unchanged, when at least one row matches. When nothing matches the item is dropped and produces no output.
Row: rowNotExistsThe original input item, unchanged, when no row matches. When something matches the item is dropped.
Table: createOne item holding the data table record, including its id and name. With Reuse Existing Tables on and a name that already exists, the existing table’s record is returned instead.
Table: listOne item per data table.
Table: updateOne item: { "success": true, "name": "<the new name>" }.
Table: deleteOne item: { "success": true, "deletedTableId": "<the table id>" }.

A row comes back with your own columns plus the three system columns:

{
  "id": 17,
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30,
  "active": true,
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-01-15T10:00:00.000Z"
}

Date values always come back as ISO 8601 strings, so they are safe to compare and to pass to other nodes.

Dry Run changes nothing in storage but still emits the rows the operation would have touched, which makes it a safe way to preview a destructive filter before running it for real.

deleteRows, update and upsert require at least one filter condition — an empty Filter Conditions array fails the item rather than matching every row.

Because rowExists and rowNotExists drop non-matching items, they act as filters in the middle of a branch rather than as data sources.

Usage Examples

  • Insert a row into a data table from workflow data
  • Query rows from a data table with filters and sorting
  • Delete rows matching specific conditions
  • Update rows that match a filter
  • Upsert: update if exists, insert if not
  • Check if a row exists before proceeding
  • Create a new data table with typed columns
  • List all available data tables
  • Rename or delete a data table

Example Configuration

Insert a row straight from the incoming item’s fields:

{
  "type": "data_table",
  "parameters": {
    "resource": "row",
    "operation": "insert",
    "dataTableId": "users_table",
    "columnsMappingMode": "autoMapInputData"
  }
}

Insert a row with values you set explicitly:

{
  "type": "data_table",
  "parameters": {
    "resource": "row",
    "operation": "insert",
    "dataTableId": "users_table",
    "columnsMappingMode": "defineBelow",
    "columnsValue": {
      "name": "John Doe",
      "email": "john@example.com",
      "age": 30,
      "active": true
    }
  }
}

Query rows with two conditions, a limit and a sort:

{
  "type": "data_table",
  "parameters": {
    "resource": "row",
    "operation": "get",
    "dataTableId": "users_table",
    "matchType": "allConditions",
    "filterConditions": [
      {
        "keyName": "active",
        "condition": "isTrue"
      },
      {
        "keyName": "age",
        "condition": "gte",
        "keyValue": "18"
      }
    ],
    "returnAll": false,
    "limit": 50,
    "orderBy": true,
    "orderByColumn": "name",
    "orderByDirection": "ASC"
  }
}

Preview an update without committing it:

{
  "type": "data_table",
  "parameters": {
    "resource": "row",
    "operation": "update",
    "dataTableId": "users_table",
    "matchType": "anyCondition",
    "filterConditions": [
      {
        "keyName": "email",
        "condition": "like",
        "keyValue": "@example.com"
      }
    ],
    "columnsMappingMode": "defineBelow",
    "columnsValue": {
      "status": "verified"
    },
    "dryRun": true
  }
}

Delete inactive rows that have never logged in:

{
  "type": "data_table",
  "parameters": {
    "resource": "row",
    "operation": "deleteRows",
    "dataTableId": "users_table",
    "matchType": "allConditions",
    "filterConditions": [
      {
        "keyName": "active",
        "condition": "isFalse"
      },
      {
        "keyName": "last_login",
        "condition": "isEmpty"
      }
    ]
  }
}

Let only items that already exist in the table continue:

{
  "type": "data_table",
  "parameters": {
    "resource": "row",
    "operation": "rowExists",
    "dataTableId": "users_table",
    "matchType": "allConditions",
    "filterConditions": [
      {
        "keyName": "email",
        "condition": "eq",
        "keyValue": "{{ $json.email }}"
      }
    ]
  }
}

Create a typed table, reusing it if it already exists:

{
  "type": "data_table",
  "parameters": {
    "resource": "table",
    "operation": "create",
    "tableName": "products",
    "tableColumns": [
      {
        "name": "name",
        "type": "string"
      },
      {
        "name": "price",
        "type": "number"
      },
      {
        "name": "in_stock",
        "type": "boolean"
      },
      {
        "name": "launch_date",
        "type": "date"
      }
    ],
    "createIfNotExists": true
  }
}

List tables whose name contains “user”:

{
  "type": "data_table",
  "parameters": {
    "resource": "table",
    "operation": "list",
    "returnAll": false,
    "limit": 20,
    "filterName": "user",
    "sortField": "name",
    "sortDirection": "asc"
  }
}

Rename a table:

{
  "type": "data_table",
  "parameters": {
    "resource": "table",
    "operation": "update",
    "dataTableId": "old_table_name",
    "newName": "new_table_name"
  }
}

Delete a table:

{
  "type": "data_table",
  "parameters": {
    "resource": "table",
    "operation": "delete",
    "dataTableId": "table_to_delete"
  }
}

Error Handling

ModeBehavior
stopHalts workflow on first error
continueSkips failed items, passes successful ones through
errorPortRoutes failed items to Error output port

Tips

Persistent tabular storage for saving, querying, updating, and deleting structured data across workflow executions without external databases.

Common Patterns

  • CRUD workflow — create the table (table / create), insert data (row / insert), then query it (row / get).
  • Conditional processing — use rowExists or rowNotExists to branch workflow logic based on data presence.
  • Bulk operations — turn Optimize Bulk on when inserting many rows, and Dry Run on when testing an update or delete filter.
  • Advanced filtering — combine several conditions and set Must Match to allConditions for AND logic or anyCondition for OR logic.

Parameter Dependencies

  • Resource determines which Operation options are available.
  • Most row operations need a Data Table and support filtering via Must Match and Filter Conditions.
  • Insert, update and upsert use Column Mapping Mode to decide how data reaches the columns.
  • Get supports pagination (Return All, Limit) and sorting (Order By, Order By Column, Order By Direction).
  • Table operations have their own parameters — Table Name when creating, New Name when renaming.

Filter conditions

  • Comparison: eq, neq, gt, gte, lt, lte.
  • Text: like and ilike (case-insensitive).
  • Presence and boolean: isEmpty, isNotEmpty, isTrue, isFalse — these take no keyValue.

Frequently asked questions

Do I need to connect any credentials or external database to use Data Table?

No. Data Table is entirely internal to the platform — no credentials, API keys, or external database connections are required. Storage is managed by BusyBot itself, so you can start inserting rows immediately after creating a table with the Table → Create operation.

What order do I need to set up a table before I can insert rows?

You must create the table first using the Table resource with the Create operation, providing a Table Name. Only after the table exists can you use row operations like Insert, Get, Update, or Delete against it. Skipping this step will cause subsequent row operations to fail.

What are 'rowExists' and 'rowNotExists' operations actually for?

These operations let you branch your workflow based on whether matching rows are found. Instead of returning row data, they route execution to the Output path if the condition is met or the Error path if it isn't — so you can, for example, skip processing a record you've already stored, or trigger an alert when expected data is missing.

When should I turn on 'Optimize Bulk' for inserts, and what does 'Dry Run' do?

Enable Optimize Bulk whenever you're inserting a large number of rows at once — it batches the writes for better performance. Dry Run is useful during development for Update and Delete operations: it evaluates your filter conditions and shows you which rows would be affected without actually modifying any data.

How do I write a filter that matches rows meeting multiple conditions at the same time?

Add multiple Filter Conditions and set Must Match to 'allConditions' for AND logic (every condition must be true) or 'anyCondition' for OR logic (at least one must be true). Available comparisons include eq, neq, gt, gte, lt, lte, like, ilike, isEmpty, isNotEmpty, isTrue, and isFalse — note that the presence and boolean operators (isEmpty, isTrue, etc.) do not take a value, just a column name.

Build with the Data Table node

Drop it into a workflow, wire it to an agent, or call it on a schedule.

Open BusyBot

Last updated . Spotted something wrong? Tell us.