Tables
Tables are your own structured data stores inside Arketic — simple, typed spreadsheets that workflows and AI agents can read from and write to.
Use a table whenever a workflow needs to remember something between runs: leads collected from a form, tickets waiting for review, a status you look up later, or a list your agent should be able to search. Each table has named columns, each column has a type, and every value is checked against that type before it is saved.

Where tables live
Open Workflows → Tables.
The screen is split in two:
| Area | What it shows |
|---|---|
| Left rail | Your list of tables, with the row count for each one |
| Main area | The selected table's data grid — its columns and rows |
Click a table in the left rail to open it. Before you pick one, the main area simply says Select a table.
Active and archived
Above the list there are two small tabs: active and archived.
- active — the tables your workflows use day to day. The New button is only available here.
- archived — tables you have put away. Their rows are kept, but the table is read-only.
Switching between the two clears whatever table you had selected, so you always start fresh in the new view.
If a scope is empty you'll see No tables yet (active) or No archived tables (archived).
Create a table
- Make sure you are on the active tab.
- Click New. The New table form opens in the main area.
- Type a Name (for example
leads). - Define your Columns.
- Click Create table.
Naming rules
Table and column names follow the same rule:
- Start with a letter or an underscore
- Use only letters, numbers and underscores — no spaces, dashes or punctuation
If the name doesn't fit, the form tells you why and Create table stays disabled:
Name must start with a letter or underscore and use only letters, numbers, and underscores.
Name tables after the kind of record they hold — leads, tickets, invoices. You will type these names when you point a workflow block at the table, and clear names make workflows much easier to read later.
Columns
Every new table starts with one column called title (type string, required). Add more with + Add column.
Each column row has three parts:
| Part | What it does |
|---|---|
| Name | The column name (placeholder column_name). Same naming rule as the table. |
| Type | A dropdown — see the types below. |
| Delete (trash icon) | Removes the column. Disabled when only one column is left — a table always needs at least one. |
Column names must also be unique within the table. The form will tell you if two columns share a name:
Column names must be unique.
Column types
| Type | Use it for | A value is accepted when… |
|---|---|---|
| string | Text — names, notes, statuses, IDs | Anything |
| number | Amounts, scores, counts | It is a number |
| boolean | Yes/no flags | It is true or false |
| date | Dates and timestamps | It is a recognisable date, e.g. 2026-07-23 |
| json | Structured data — an object, a list, nested fields | It is valid JSON |
Types are not decoration. They are enforced every time a value is written — from the grid, from a workflow block, or from an agent. Picking the right type up front is what keeps the table clean months later.
If the table can't be created, you'll see:
Could not create the table (name may be taken).
Table names must be unique, so try another one.
Work with rows
Open a table to see its data grid. The header shows the table name, the row count, and a reminder that this table is available to your workflows. Column headers show the column name with its type beside it in small capitals.
The grid loads up to 200 rows at a time.
Add a row
Click Add row. A new row appears immediately, with sensible starter values already filled into any required columns so the row is valid from the moment it exists. Then click into the cells and replace those values with your own.
If the table has no rows yet, the grid shows No rows yet with an Add first row button.
Edit a cell
Click any cell to edit it in place.
| Key | What happens |
|---|---|
| Enter | Saves the value |
| Escape | Cancels and leaves the cell unchanged |
| Clicking away | Saves the value |
Empty cells show a dash (—). Clearing a cell and saving removes that value from the row rather than storing an empty one.
Type checking on every edit
Before a value is saved it is converted to the column's type. If it doesn't fit, the edit is rejected and you get a short message naming the column and the problem:
| Column type | Message when the value doesn't fit |
|---|---|
| number | must be a number |
| boolean | must be true or false |
| date | must be a date |
| json | invalid JSON |
If the save is refused for a different reason, you'll see:
Could not save — a required value may be missing or mistyped.
That usually means a required column was left empty.
Values in a json column are displayed as JSON text, so what you see in the cell is exactly what you can edit and save back.
Delete a row
Click the trash icon at the end of the row. If it can't be removed you'll see Could not delete the row.
Remove a column
Every column header carries a small × next to its type badge. Click it to remove that column from the table.
A table always needs at least one column, so the icon is disabled — with a tooltip explaining why — when it's the last one left.
The confirmation spells out exactly what happens:
Remove column "{column}"?
"{column}" is removed from "{table}" for every row. This only goes through while no row holds a value for it — if any row does, nothing is changed and you are told which.
Click Remove column to confirm, or Cancel to back out. On success you'll see Column "{column}" removed.
The safety rule
A column can be removed only while no row holds a value for it — checked column by column, not table by table. A table can hold plenty of rows and still let you remove one of its columns, as long as that particular column is empty in every one of them.
If any row still has a value there, nothing is removed, and you're told exactly which column is blocking it and how many rows are affected:
"{column}" still holds a value in {n} row(s). Clear those cells first, or keep the column.
To make a column removable, clear its value in every row first — an emptied cell removes the value entirely rather than storing a blank one, which is exactly what this check requires.
If removal fails for any other reason, you'll see Could not remove the column.
A column's name or type can't be changed once it's created. If you need something different, remove the column — once it's empty — and add a new one in its place.
If a workflow block still writes to a column you remove — for example a Table — Insert Row or Table — Update Row block with that column in its Row data — that block's next write will be rejected. Update those blocks first.
Rename a table
Click the pencil icon next to the table name in the grid header, type the new name, then press Enter to save or Escape to cancel. Clicking away also saves.
The same naming rule applies, and names must stay unique — otherwise:
Could not rename — the name may already be taken.
Archive and restore
Archiving takes a table out of your working list without losing anything.
Archive
- Open the table.
- Click Archive.
- Confirm.
The confirmation spells out exactly what happens:
Archive "{name}"? It leaves the active list but its {n} row(s) are kept — restore it anytime from the Archived view.
You'll see Table archived, and the table moves to the archived tab.
What changes when a table is archived
- It shows an Archived badge instead of the rename pencil
- Cells can no longer be edited
- Add row and row deletion are unavailable
- An empty archived table reads This table is archived
Restore
Switch to the archived tab, open the table, and click Restore. You'll see Table restored and the table returns to the active list, fully editable again.
Archive is the safe way to retire a table you no longer use. Before archiving, check whether any workflow block still points at it — those steps will no longer be able to write to it.
Use a table in a workflow
Tables become useful when a workflow reads and writes them. Four blocks do exactly that. Find them in the block palette under the Data category — see Creating Workflows.
| Block | What it does |
|---|---|
| Table — Insert Row | Adds a new row |
| Table — Query Rows | Finds the rows that match a filter |
| Table — Get Row | Fetches one specific row |
| Table — Update Row | Changes an existing row |
In every one of them, the table is picked from a Table dropdown that lists your tables by name — you never type an identifier by hand.
Table — Insert Row
| Field | What to put in it |
|---|---|
| Table | The table to write to |
| Row data | The row as { columnName: value } — each value must match its column's type |
Output: the created row.
Table — Query Rows
| Field | What to put in it |
|---|---|
| Table | The table to search |
| Filter | Which rows to match — { field: value } for an exact match, or { field: { $gte: 18 } } for a comparison |
| Sort | Ordering, e.g. { createdAt: "desc" } |
| Limit | How many rows to return, from 1 to 1000 (default 100) |
| Offset | How many rows to skip — use it to page through a large result |
Outputs: the matching rows, and the total number of matches.
Filter comparisons you can use:
| Operator | Meaning |
|---|---|
$eq / $ne | Equals / does not equal |
$gt / $gte | Greater than / greater than or equal |
$lt / $lte | Less than / less than or equal |
$in / $nin | Is one of / is not one of a list |
$contains | Contains the given value |
Combine several conditions with $or and $and.
Querying a table is exact matching, not a search for "something similar". A row comes back only when it genuinely matches the filter. If you want meaning-based search over your company's content instead, that's the Knowledge and search blocks — see Creating Workflows.
Table — Get Row
| Field | What to put in it |
|---|---|
| Table | The table to read from |
| Row ID | The id of the row you want |
Output: the row.
Table — Update Row
| Field | What to put in it |
|---|---|
| Table | The table to write to |
| Row ID | The id of the row to change |
| Row data | The new values as { columnName: value }, matched against the column types |
Output: the updated row.
Passing table data to the next step
Blocks reuse each other's results through references. A later block reads an earlier one's output as <blockName.field> — so a Query Rows block's results become available as <blockName.rows>, and the match count as <blockName.total>.
Data coming from the trigger is referenced as <input.NAME>, and workflow variables as <variable.NAME>. See Variables and Creating Workflows for the full picture.
A typical shape looks like this:
- A trigger starts the run with some incoming data
- Table — Query Rows looks for a matching record
- A Condition block checks whether anything came back
- Table — Insert Row or Table — Update Row writes the result
Tables as agent tools
Your tables are also available to AI agents as tools. An agent in a workflow can look records up and write them back on its own, as part of answering a request — without you wiring every lookup into the canvas by hand.
That makes a table a good place to keep the facts an agent needs to stay consistent across conversations and runs.
Give columns names an agent can interpret — status, owner_email, due_date — rather than col1 or f2. The names are what the agent reads to decide which column to use.
Troubleshooting
| What you see | What it usually means |
|---|---|
| Could not create the table (name may be taken). | Another table already uses that name — pick a different one |
| Could not rename — the name may already be taken. | Same reason, on rename |
| {column}: must be a number (or true or false / a date / invalid JSON) | The value doesn't match the column's type — correct the value or reconsider the column type |
| Could not save — a required value may be missing or mistyped. | A required column ended up empty |
| Cells won't respond to clicks | The table is archived — restore it first |
| Couldn't load tables. / Couldn't load rows. | A temporary loading problem — use Try again |
| A workflow step can't find the table | Confirm the block's Table dropdown still points at the right table, and that it hasn't been archived |
Good habits
- One table per kind of record. A
leadstable and aticketstable beat one table trying to be both. - Pick types deliberately. A
numbercolumn catches a bad value at the moment it's written, instead of a month later. - Use
datefor dates. Storing dates as text makes sorting and comparing unreliable. - Keep a required
title. It gives every row a human-readable label in the grid. - Archive, don't abandon. Retiring a table into the archived view keeps its history without cluttering the active list.