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 — or create one to get started.
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 view is empty you'll see No tables yet (Active) or No archived tables (Archived).
Finding a table
Once a view holds more than five tables, a search box appears above the list (Search tables...). Type part of a name to narrow the list. If nothing fits you'll see No table matches “…”. — clear the box to get the full list back.
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
- At most 50 characters
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 pick tables by name when you point a workflow block at them, 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. |
A table can have up to 50 columns. The form tells you when a column name is missing or doesn't fit the rule, or when two columns share a name:
Each column needs a valid name (letters, numbers, underscores; not starting with a number).
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.
Paging
The grid shows 100 rows per page. The line under the grid tells you where you are — for example 1–100 of 250 rows — and when the table has more rows than one page holds, Previous and Next move between pages.
Search rows
The magnifier button in the table header (Search rows) opens a search box above the grid. It is there for every table that has at least one string, date or number column — archived tables included. The box's placeholder names the columns it looks in, for example Search title, amount, due_date….
| Column type | How it is searched |
|---|---|
| string, date | Rows whose value contains what you typed. 2026-08 finds every row dated in August 2026 |
| number | Rows whose value is exactly the number you typed. Only used when what you typed is a number |
| boolean, json | Not searched |
The search covers the whole table, not just the page you are on. While it is active the line under the grid counts the matches — 1–3 of 3 matching rows — and when nothing fits you see No row matches “…”.
Close the search with the × next to the box, the magnifier button, or Escape. Closing it clears what you typed, so the grid goes back to showing every row.
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.
How a value looks while you are only reading the grid depends on the column type:
| Column type | Shown as |
|---|---|
| string, number | The value itself |
| boolean | A check mark for true, a cross for false |
| date | The date and time in your own language's format |
| json | A short summary — { } 3 for an object with three fields, [ ] 5 for a list of five items. Hover the cell to see the full value |
Click the cell and you get the value as it is stored — true, the date as typed, or the full JSON text — ready to edit.
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.
Delete a row
Click the trash icon at the end of the row. The row is removed straight away — there is no confirmation. If it can't be removed you'll see Could not delete the row.
Add a column
You can add columns to a table at any time, even when it already holds rows.
- Open the table and click Add column in the header. A New column bar opens above the grid.
- Type the column name and choose its type.
- Click Add, or press Enter. Cancel or Escape closes the bar.
You'll see Column “{column}” added. The new column is empty in every existing row and is optional.
The bar tells you why Add is disabled:
| Message | What it means |
|---|---|
| Name must start with a letter or underscore and use only letters, numbers, and underscores. | The name breaks the naming rule |
| A column name can be at most 50 characters (this one is 62). | The name is too long |
| This table already has a column named “…”. | Column names must be unique. Upper and lower case don't count as a difference |
| This table already has the maximum of 50 columns. | The table is full — remove a column you don't need first |
Under the fields, the bar carries a reminder worth reading before you add anything:
New columns start empty and optional. A column can be removed again while no row holds a value for it — but once one does, it can no longer be renamed, retyped, or removed.
If someone else changed the table while the bar was open, you'll see Someone else changed this table — it has been refreshed. Add your column again.
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 the tooltip A table needs at least one column — 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. The row search helps you find the rows that still hold a value.
If removal fails for any other reason, you'll see Could not remove the column. If someone else changed the table in the meantime: Someone else changed this table — it has been refreshed. Try removing the column again.
There is no way to rename a column or change its type. 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 in the Archive table? dialog.
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, Add column, row deletion and column removal are unavailable
- You can still page through it and search its rows
- 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 Blocks.
| 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. If you have no tables yet, the dropdown says No tables yet — create one in the Tables section first.
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
Filter, Sort, Limit and Offset sit behind Show additional fields.
| 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 Blocks.
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>.
A row carries its id and, under data, its column values. So the id of a row you just inserted is <blockName.row.id> — the value a later Table — Update Row or Table — Get Row needs as its Row ID — and one of its columns is <blockName.row.data.columnName>.
Data coming from the trigger is referenced as <input.NAME>, and workflow variables as <variable.NAME>. See Variables 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. An Agent block in a workflow can list your tables and look records up on its own, as part of answering a request — without you wiring every lookup into the canvas by hand. To write a row, use a Table — Insert Row or Table — Update Row block.
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 |
| Could not add the row. | The row couldn't be created — try again |
| "{column}" still holds a value in {n} row(s)… | The column you tried to remove isn't empty — clear those cells first |
| Someone else changed this table — it has been refreshed. | The table was changed elsewhere while you were editing its columns — repeat what you were doing |
| No row matches “…”. | The row search found nothing. Remember that number columns need the exact number and boolean / json columns aren't searched |
| A row you expect isn't on screen | It may be on another page — use Next, or search for it |
| 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. And a column that holds values can't be retyped, so the first choice sticks. - 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.