A table is data your flows read and write between runs: posts already answered, products found, daily counts, leads from a form. There are two kinds:
| Kind | Made by | Example |
|---|---|---|
| Yours | Dataset › Tables › New table | "Leads", columns you pick |
| A node's own (the System tab) | The node's definition in code; its rows appear when the node first runs | x/collect/post: posts the group took or replied to |
Rows: scope, key, label
Every row has, besides its columns:
| Field | Meaning |
|---|---|
scope | Whose row it is: account or group (set when the table keeps rows per account or per campaign group, else both are empty). |
test | Written by a test run. Test rows are kept apart from the real ones, so a test never touches real rows. |
key | Unique within its scope (a post id, 2026-10-28|<subId>). Claiming a key twice fails, which is how two campaigns never take the same post. |
label | What happened to it: claimed, replied, removed, deleted… A node table gives each label a tone for the dashboard. |
origin | The campaign (campaignId) whose run wrote it, and the account (accountId) it's about. A campaign's Records tab shows its own rows. |
expiresAt | Gone after this (a claim's hold, or the table's row lifetime). |
Scope
A table's scope decides which rows a run sees:
| Scope | A run sees | Used for |
|---|---|---|
Everyone's (global) | All rows | Your own tables |
Per account (account) | Rows of the account the node uses | Shopee earnings per Shopee account |
Per group (group) | Rows of its campaign's group (default outside a campaign) | 𝕏 and Threads posts and authors shared by campaigns in one group |
Open a table to see each row's scope, key and label. Clear test data removes what test runs wrote.
The Tables page
Dataset › Tables has two tabs (?tab=), and its address holds the state (?page, ?size, ?q, ?sort, ?dir), so a list can be shared and Back works:
| Tab | Shows |
|---|---|
| Yours | Your tables: search by name, sort, edit columns, delete |
| System | The nodes' own tables, read-only: scope, how long rows are kept, rows (real and from tests), the campaigns that wrote them, the last write |
Open a table for its rows (?show=all\|real\|test), a page at a time. On a table of yours you can add and edit rows; on a node's own you can browse and delete.
Node tables
A node definition declares the tables it owns (table in ); they live in code (lib/flow/table, one registry for every node), not in the database, are named <node type>/<name> and keep their definition's columns (you can browse and delete rows, not change columns). Their rows are kept in the database. Built-in nodes reach them through one helper, flowTableCall (lib/flow/table/call), bundled into the node. Built in:
| Table | Scope | Rows kept | Labels | Row action | Metric |
|---|---|---|---|---|---|
x/collect/post | group | 90 days | claimed (not listed on the dashboard), replied, quoted, removed, deleted, failed | Delete reply (on replied, quoted) | Replies, Quotes |
x/collect/author | group | 90 days | – | – | – |
x/post/post | account | kept | posted, quoted, removed | – | Posts, Quotes |
threads/collect/post | group | 90 days | claimed (not listed on the dashboard), replied, quoted, removed, deleted, failed | Delete reply (on replied, quoted) | Replies, Quotes |
threads/collect/author | group | 90 days | – | – | – |
threads/post/thread | account | kept | pending (last reply held back), done | – | Threads |
shopee/search/product | account | 1 day | – | – | – |
shopee/affiliate/link | account | 30 days | – | – | – |
shopee/report/earning | account | 400 days | – | – | Commission, Orders |
Create your own table
Dataset › Tables › New table: a Name and its Columns, each with a type:
| Type | Stores |
|---|---|
| Text | "hello" |
| Number | 42 |
| Yes or no | true |
| Date | "2026-10-28T06:10:21.000Z" |
| JSON | any object or list |
Open a table to browse, add, edit and delete rows by hand. The names id, key, label and campaignId are row fields, not columns.
Use it in a flow: the Data table node
| Field | Meaning |
|---|---|
table | One of your tables, or a node's own (System), e.g. x/collect/post. |
operation | find · insert · update · upsert · delete |
where | JSON { column: value }, or { "id": "<row id>" }, { "key": … }, { "label": … } (a value or a list) |
data | JSON { column: value } (or a list for insert), optionally with key and label |
limit | Maximum rows for find (default 100) |
sort, direction | Sort column, desc (newest/largest first) or asc |
Examples:
{ "operation": "find", "where": { "key": "{{ nodes.loop.output.item.id }}" }, "limit": 1 }
{ "operation": "insert", "data": { "key": "{{ nodes.loop.output.item.id }}", "label": "seen", "url": "{{ nodes.loop.output.item.url }}" } }
{ "operation": "upsert", "where": { "key": "{{ nodes.input.output.keyword }}" }, "data": { "link": "{{ nodes.affiliate.output.link }}" } }
Node output (row is the first row, for convenience):
{ "rows": [{ "id": "6ae1…", "key": "2115091199661146286", "label": "seen", "url": "https://x.com/…", "createdAt": "2026-10-28T06:11:18.000Z" }], "row": { "id": "6ae1…", "key": "2115091199661146286", "label": "seen", "url": "https://x.com/…", "createdAt": "2026-10-28T06:11:18.000Z" }, "count": 1 }
A find with no rows leaves through the empty dot; everything else through next.
Test runs write too, as test rows. They read and write their own rows, never the real ones; clear them with Clear test data.
From a script node
await fetch(`${api.link}/api/run/table`, {
method: "POST",
headers: { authorization: `Bearer ${api.token}`, "Content-Type": "application/json" },
body: JSON.stringify({ table: "6ae1…", operation: "find", where: { key: "123" }, limit: 1, sort: { column: "repliedAt", direction: "desc" } }),
});
A node's own table by key, and a claim (insert only keys not taken in the scope, held for 15 minutes):
body: JSON.stringify({ table: "x/collect/post", operation: "claim", data: [{ key: "2115…", label: "claimed", url: "…" }], holdMs: 900_000 })
See the .
FAQ
What happens to flows when I delete a table?
The table and all its rows are removed, and Data table nodes using it fail until you pick another. A node's own table can't be deleted: delete its rows, or Clear test data.
Can I change columns later?
Yours, yes, with Edit columns. Existing rows keep their values; a removed column stops being read and written. A node's own table has its columns from its definition.
Why don't my test runs see real rows?
On purpose: they read and write test rows, so a test can't skip a post a real run took, nor block one.