Table

Use the Table block to read and write structured data in Sim. Data persists across runs and is scoped to the workspace. Operations insert, update, upsert, query, or delete rows, with filters, sorting, and batch writes.

Create tables

Tables are created from the Tables section in the sidebar. Each table requires:

  • Name: An ASCII letter or underscore followed by letters, digits, or underscores (e.g., customer_leads)
  • Description: Optional description of the table's purpose
  • Schema: Define columns with name, type, and optional constraints

Column types

See Table column types for the supported types and their storage behavior.

Column constraints

  • Required: Column must have a value (cannot be null)
  • Unique: Values must be unique across all rows (enables upsert matching)

Use the block

Create and manage custom data tables. Store, query, and update structured data within workflows. Query Rows accepts a plain predicate — {"field":"wins","op":"gte","value":10} — for one condition. Use all (AND) or any (OR) groups for multiple or nested conditions. Operators: eq, ne, gt, gte, lt, lte, in, nin, like, ilike, nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. Order is a sort spec [{"field":"wins","direction":"desc"}]. Query Rows returns every matching row when Limit is omitted (fails if the result exceeds the fixed 5 MiB row-data budget — add a filter or a Limit). With a Limit, responses page: a non-null nextCursor means more rows exist — pass it back as the cursor. Columns to Return narrows each row to the selected columns (by stable id or name; one that no longer exists is skipped); leave it empty for every column.

Actions

Insert Row

Insert a new row into a table. IMPORTANT: You must use the "data" parameter (not "values", "row", "fields", or other variations) to specify the row contents.

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
dataobjectYesRow data as JSON object

Output

ParameterTypeDescription
successbooleanWhether row was inserted
rowjsonInserted row data
messagestringStatus message

Batch Insert Rows

Insert multiple rows into a table at once (up to 1000 rows)

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
rowsarrayYesArray of row data objects (max 1000 rows)

Output

ParameterTypeDescription
successbooleanWhether rows were inserted
rowsarrayInserted rows data
insertedCountnumberNumber of rows inserted
messagestringStatus message

Upsert Row

Insert or update a row based on unique column constraints. If a row with matching unique field exists, update it; otherwise insert a new row. IMPORTANT: You must use the "data" parameter (not "values", "row", "fields", or other variations) to specify the row contents.

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
dataobjectYesRow data to insert or update
conflictTargetstringNoUnique column to match on. Required only when the table has more than one unique column.

Output

ParameterTypeDescription
successbooleanWhether row was upserted
rowjsonUpserted row data
operationstringOperation performed: insert or update
messagestringStatus message

Update Row

Update an existing row in a table. Supports partial updates - only include the fields you want to change. IMPORTANT: You must use the "data" parameter (not "values", "row", "fields", or other variations) to specify the fields to update.

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
rowIdstringYesRow ID to update
dataobjectYesUpdated row data

Output

ParameterTypeDescription
successbooleanWhether row was updated
rowjsonUpdated row data
messagestringStatus message

Update Rows by Filter

Update multiple rows that match filter criteria. Data is merged with existing row data.

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
filterobjectYesFilter criteria using operators like $eq, $ne, $gt, $lt, $contains, $ncontains, $startsWith, $endsWith, $in, $nin, $empty, etc.
dataobjectYesFields to update (merged with existing data)
limitnumberNoMaximum number of rows to update (default: no limit, max: 1000)

Output

ParameterTypeDescription
successbooleanWhether rows were updated
updatedCountnumberNumber of rows updated
updatedRowIdsarrayIDs of updated rows
messagestringStatus message

Delete Row

Delete a row from a table

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
rowIdstringYesRow ID to delete

Output

ParameterTypeDescription
successbooleanWhether row was deleted
deletedCountnumberNumber of rows deleted
messagestringStatus message

Delete Rows by Filter

Delete multiple rows that match filter criteria. Use with caution - supports optional limit for safety.

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
filterobjectYesFilter criteria using operators like $eq, $ne, $gt, $lt, $contains, $ncontains, $startsWith, $endsWith, $in, $nin, $empty, etc.
limitnumberNoMaximum number of rows to delete (default: no limit, max: 1000)

Output

ParameterTypeDescription
successbooleanWhether rows were deleted
deletedCountnumberNumber of rows deleted
deletedRowIdsarrayIDs of deleted rows
messagestringStatus message

Query Rows

Query rows with a typed predicate filter and cursor pagination. A single filter can be a plain condition: \{"field":"wins","op":"gte","value":10\}. Use all (AND) or any (OR) groups for multiple or nested conditions. Operators: eq, ne, gt, gte, lt, lte, in, nin, like, ilike, nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. Order is a sort spec, e.g. [\{"field":"wins","direction":"desc"\}]. Omit limit to return the entire result — the query fails if it exceeds the fixed 5 MiB row-data budget (narrow with a filter or set a limit). With a limit, a page can end early at the byte budget: a non-null nextCursor means more rows exist — pass it back as cursor to continue; never infer completion from page size.

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
filterjsonNoPredicate condition, e.g. \{"field":"wins","op":"gte","value":10\}. Use all or any for multiple conditions; omit to match all rows.
columnsarrayNoStable column IDs or table column names to include in each row data object. Omit or pass an empty array to return all columns. A reference that matches no column is ignored.
orderjsonNoSort spec, e.g. \[\{"field":"wins","direction":"desc"\}\].
limitnumberNoMaximum rows per page. Omit to return the entire matching result — fails if it exceeds the fixed 5 MiB row-data budget. With a limit, pages may byte-cut early and set nextCursor when more remain.
cursorstringNoOpaque pagination cursor returned by a prior query. Omit for the first page.

Output

ParameterTypeDescription
successbooleanWhether the query succeeded
rowsarrayQuery result rows
rowCountnumberNumber of rows returned
totalCountnumberTotal rows matching the predicate (computed on the first page only)
limitnumberLimit used in the query
nextCursorstringCursor to fetch the next page, or null on the last page

Get Row

Get a single row by ID

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.
rowIdstringYesRow ID to retrieve

Output

ParameterTypeDescription
successbooleanWhether row was retrieved
rowjsonRow data
messagestringStatus message

Get Schema

Get the schema configuration of a table

Inputs and outputs

Input

ParameterTypeRequiredDescription
tableIdstringYesTable ID in the execution workspace. In a workflow, the table must belong to the same workspace as the workflow.

Output

ParameterTypeDescription
successbooleanWhether schema was retrieved
namestringTable name
columnsarrayColumn definitions (each includes its stable id)
columnCountnumberNumber of columns
rowCountnumberNumber of rows in the table
maxRowsnumberMax rows per table for the workspace's plan
messagestringStatus message

Filter operators

A filter is a predicate. One condition is an object naming a column, an operator, and a value:

{"field": "status", "op": "eq", "value": "active"}
OperatorDescriptionExample
eqEquals{"field": "status", "op": "eq", "value": "active"}
neNot equals{"field": "status", "op": "ne", "value": "deleted"}
gtGreater than{"field": "age", "op": "gt", "value": 18}
gteGreater than or equal{"field": "score", "op": "gte", "value": 80}
ltLess than{"field": "price", "op": "lt", "value": 100}
lteLess than or equal{"field": "quantity", "op": "lte", "value": 10}
inIn array{"field": "status", "op": "in", "value": ["active", "pending"]}
ninNot in array{"field": "type", "op": "nin", "value": ["spam", "blocked"]}
contains / ncontainsContains, or does not contain (case-insensitive){"field": "email", "op": "contains", "value": "@gmail.com"}
like / nlikePattern match, * wildcard (case-sensitive){"field": "name", "op": "like", "value": "Dr.*"}
ilike / nilikePattern match, * wildcard (case-insensitive){"field": "name", "op": "ilike", "value": "*jo*"}
startsWithStarts with (case-insensitive){"field": "name", "op": "startsWith", "value": "Dr."}
endsWithEnds with (case-insensitive){"field": "file", "op": "endsWith", "value": ".pdf"}
isNull / isNotNullCell is (not) null{"field": "phone", "op": "isNull"}
isEmpty / isNotEmptyCell is (not) empty{"field": "phone", "op": "isEmpty"}

Most columns are scalar (string, number, boolean, date) or opaque JSON; use ilike with *value* for substring matching on text.

Select columns accept only a subset of these operators, and a query using any other operator on one is rejected rather than returning no rows:

ColumnAllowed operators
Single-selecteq, ne, in, nin, isEmpty, isNotEmpty, isNull, isNotNull
Multi-selectcontains, ncontains, isEmpty, isNotEmpty, isNull, isNotNull

A multi-select cell holds a list of options, so match it with contains (by option name) rather than ilike.

Combine filters

Wrap conditions in all for AND:

{
  "all": [
    {"field": "status", "op": "eq", "value": "active"},
    {"field": "age", "op": "gte", "value": 18}
  ]
}

Use any for OR:

{
  "any": [
    {"field": "status", "op": "eq", "value": "active"},
    {"field": "status", "op": "eq", "value": "pending"}
  ]
}

Groups nest, so mixed logic is a group inside a group:

{
  "all": [
    {"field": "status", "op": "eq", "value": "active"},
    {"any": [
      {"field": "plan", "op": "eq", "value": "pro"},
      {"field": "score", "op": "gte", "value": 90}
    ]}
  ]
}

Omit the filter entirely to match every row.

Sort specification

Order is a list of column/direction pairs, applied in order:

[{"field": "createdAt", "direction": "desc"}]

Multi-column sorting:

[
  {"field": "priority", "direction": "desc"},
  {"field": "name", "direction": "asc"}
]

Pagination

Omit Limit to return every matching row in one response; queries exceeding the fixed 5 MiB row-data budget fail. Narrow with a filter, select fewer columns, or set a limit.

With a Limit, results page. A page can end at the limit or early at the row-data budget (5 MiB by default; self-hosted operators can configure TABLE_MAX_PAGE_BYTES), so a short page does not mean the end. Pass the returned nextCursor back as Cursor to fetch the next page and stop only when nextCursor is null — never infer completion from the row count.

Built-in columns

Every row automatically includes:

ColumnTypeDescription
idstringUnique row identifier
createdAtdateWhen the row was created
updatedAtdateWhen the row was last modified

These can be used in filters and sorting.

Limits

ResourceLimit
Tables per workspaceDepends on workspace plan and deployment settings
Rows per tableDepends on workspace plan and deployment settings
Columns per table1,000
Max row size400 KiB by default; configurable on self-hosted deployments
Text value sizeConstrained by the row byte limit
Query limit1,000 rows
Batch insert size1,000 rows
Bulk update/delete1,000 rows

Workspace access

  • Tables are scoped to workspaces and accessible from any workflow within that workspace
  • Data persists across workflow executions
  • Use unique constraints to enable upsert functionality
  • Use the visual filter and sort builders to construct queries without writing JSON