Tables & field types
Tables are the building blocks of your app — customers, projects, invoices, or anything your team tracks. This article covers creating a table (blank, from a template type, or with AI) and designing its fields: every field type, how to configure choices and cross-table connections, and what really happens when you delete a field.
Create a table
On the Tables page, click New table (in an empty workspace it reads Create first table). Give it a Table name and pick a Template type — Custom starts blank, while every other type comes pre-built with its typical fields. Click Create and add fields → and you land straight in the field editor.
Only workspace Admins can create tables. If you don't see the buttons, ask an Admin of your workspace.
Start from a template type
Each template type pre-builds the fields that kind of table usually needs, so you're editing a working table instead of a blank one:
• Customer — Email, Phone, Status (Lead / Active / Inactive), Notes.
• Project — Status (Planned / Active / Blocked / Complete), Start Date, Due Date, Budget.
• Task — Status (Todo / In Progress / Blocked / Done), Priority (Low / Medium / High / Urgent), Due Date, Done.
• Asset — Serial, Status (In Service / Maintenance / Retired), Acquired, Value.
• Event — Start (required), End, Status (Scheduled / Confirmed / Completed / Cancelled), Notes.
• Invoice — Amount (required), Issued, Due, Status (Draft / Sent / Paid / Overdue).
• Document — URL, Type (Contract / Proposal / Spec / Report / Other), Status (Draft / Review / Final).
Template fields are ordinary fields — delete them or add more alongside them freely afterwards. The type itself is chosen at creation and can't be switched later.
Build with AI
Click Build with AI to describe what you're tracking in plain words — the AI designs the tables, fields, and the relations between them, and you review the plan before anything is created. Click ✦ Design my schema or press Ctrl/⌘ + Enter to generate the plan.
On the plan screen, click ↻ Redesign to try a different description, or approve the plan to create the tables — RowFold then opens the Schema graph so you can see the new tables and their connections.
Like New table, this is available to workspace Admins, and you need a workspace open first.
Add fields
Open the field editor from a table card's Fields button, or from the table itself: click the field count under its name, open Fields & setup, or choose Add a field to this table at the bottom of Columns. In the Add field panel, type a Name — RowFold generates the field's key from it automatically, and once the field is saved you can read that key in the API key column. Pick a Type, tick Required on forms if every record needs a value (required fields show a * in the list), then click Add field.
Fields appear in the grid in the order you add them, and the ↑ ↓ arrows on each row move one up or down afterwards.
The first field is what your records are called — its value is the record's name everywhere it appears: the grid's first column, relation chips, search results, notifications. There is no separate name field to add. Because of that, the first field has to be a type that can identify one record — text, a number, a date, an email, or an auto number — so a link, a file, a calculation, or a repeating choice like a Select or a yes/no can't lead the table. RowFold blocks the move and says why. Reordering fields so a different one comes first renames every record in the table, so those two arrows ask you to confirm.
Changing fields you already have
Edit the existing fields directly in the list — rename them, switch a type, change a Select's options, tick Required on forms. Change as many as you like: the rows you have touched are highlighted, and one Save changes at the bottom of the list saves all of them together. If any single change can't be applied — a formula that doesn't compile, or a type the first field isn't allowed to be — nothing is saved at all, the reason appears against that row, and everything else you typed stays on screen so you can fix the one and save again.
Renaming the table itself
The Name & icon card renames the table and sets the emoji the left rail draws beside it. Faster still: right-click the table in the left rail and choose Rename table… or Change icon…. Both need Admin.
Renaming changes the label only — in the rail, the grid header, relation chips, search and notifications. The table's API key and every field key stay exactly as they are, so saved views, reports, automations and anything talking to the API keep working. The icon button opens a picker: search it by what the table is about — “invoice”, “delivery”, “booking” — or paste any emoji you already have. Remove icon drops back to the first letter of the name.
When you're done, Open grid view takes you to your data.
Field types at a glance
• Text — a short, single line of text.
• LongText — longer free-form notes.
• Number — a plain number.
• Currency — a money amount, displayed with money formatting.
• Date — a calendar date, displayed in your date format.
• Boolean — a yes/no value, shown as a checkmark when on.
• Select — one choice from a list you define in Options (comma-separated), shown as a chip.
• MultiSelect — several choices from your Options list, shown as multiple chips.
• Email — an email address, edited with an email-style input.
• Url — a web link.
• Phone — a phone number.
• Relation — links a record to one or more records in another table (see the next section).
• Lookup — shows a value pulled from the record a Relation points to.
• Rollup — aggregates values from records in another table that link back to this one.
• Formula — computes a value from an expression over this record's own fields — see Formula fields.
• Percent — a 0–100 value, drawn with a small progress bar in the grid.
• Rating — a star rating out of five.
• Progress — a number for tracking completion, shown as a plain value.
• People — an owner or assignee, entered as a name.
• Doc — a whole document on every record, written on its own page — see Docs.
Dates that carry a time
A Date field holds a date on its own by default. Tick Include a time on the field and its cells hold a time of day too, with the editors and pickers following automatically. Sorting, filtering, grouping and relative windows like in the next 7 days keep working exactly as they did.
Turning the setting back off leaves every stored time alone, and still visible. A configuration box must never quietly rewrite your records, and hiding the times would be indistinguishable on screen from having wiped the column.
Underneath it sits the setting that actually needs a decision: Show in each viewer's time zone.
• Off (the default) — the time belongs to a place. A shift, an on-site appointment, a delivery slot: 9:00 AM at the site, whoever is looking. Converting it would be wrong, and with a draggable calendar it would be destructive.
• On — the time belongs to the people in it. A call, a remote session, a cross-border booking: two people in two places need the same moment shown in their own terms.
Nothing in the data can tell those two apart, which is why the field has to be told. Storage never changes either way.
Connect tables with Relation, Lookup, and Rollup
Relation fields link to other tables. Lookup fields pull a value from a linked record. Rollup fields aggregate values from records that link to this one.
• Relation — choose which table this connects to. In the grid, each link renders as a chip you can click to peek at the linked record.
• Lookup — pick the route to follow from a dropdown (directly-linked tables first, deeper routes grouped by how many relationships they cross), then pick which field it should pull in from a second dropdown of that table's fields. Everything is chosen by name — there is nothing to type.
• Rollup — pick the route to the records you want to total, choose an Aggregation (Sum, Count, Average, Min, or Max), and pick the number to aggregate from a dropdown — not needed for Count. A Formula counts as a number here. If each line carries a calculated line total, the order can sum that directly, with no helper field in between — and it doesn't matter what that formula is built from. It can reach through a link ({Order.Rate}) or read the line's own Lookup and Rollup fields; it is evaluated on the line exactly as it is in the line's own cell. The only formula that can't be totalled is one that doesn't currently compile.
Both Lookup and Rollup can also filter which records they include: once a route is picked, an Only include records where… section appears — add conditions like Stage is Won or Amount greater than 1000, chosen from the far-end table's real fields with the same operators grid and report filters use. "Sum of Amount across Deals where Stage is Won" becomes one field, no helper views needed — and unlike other tools, the conditions work however many relationships deep the route travels.
A condition can also test something one link past the records it is filtering — the dropdown lists those as Order → Type. That is what lets a discriminator live where it belongs: model purchases and sales as one Orders table with a Type, and a product can still total Sum of Quantity across Order Lines, only where Order → Type is Purchase. Without it you would have to copy the type onto every line just to make the filter legal. Pair two such rollups with a formula that subtracts them and a reorder level, and stock keeps itself up to date.
The config appears automatically when you pick one of these types in the Type dropdown. If the table you want isn't linked yet, choose + New link to… at the bottom of the route picker — the Relation field is created for you as part of saving the Lookup or Rollup.
Formula fields: compute a value from an expression
A Formula field computes its value from an expression instead of storing one. Type it in curly braces to reference other fields, combine them with operators and functions, and RowFold recalculates the result every time the record — or a field it depends on — changes.
• Reference a field on this table by name: {Amount} * {Probability} / 100.
• Do date maths with - and + — {Check Out} - {Check In} is the number of days between two dates, and {Start} + 7 is the date a week later. When the field carries a time the answer keeps the part-day, so wrap it: ROUND({Check Out} - {Check In}, 0) for nights, DATEDIF({Check In}, {Check Out}, "hours") for hours (it also takes "minutes", and is exact where multiplying a day count by 24 leaves a rounding tail).
• Reach straight through a link — no Lookup field required first: {Company.Region} follows the Company relation field and reads Region off the linked record. Chain it as many hops deep as the schema allows: {Company.Region.Manager}. And there's no syntax to memorise — in the Insert a field list, click the › beside a link field to browse the linked table and insert the whole reference with one click.
• Use functions across text, math, dates, and logic — ROUND(...), IF(...), CONCAT(...), DATEDIF(...), and more. The Function reference in the Add field panel lists every one with its exact usage.
• Combine with a Rollup for totals across a to-many relation — a formula can reference an existing Rollup field by name ({Total Line Items}) alongside its own math, but can't aggregate a to-many relation directly; that's still what Rollup is for. It also works the other way round: a Rollup can total a Formula, so an order total can sum a calculated line total sitting on each line — whatever that formula is built from, including one that reaches through a link or reads the line's own Rollup.
Formulas are checked as you type — an unknown field name gets an immediate "did you mean" suggestion, and a problem is reported with the exact spot in the expression, not just a generic error. Typing { opens field suggestions (keep typing to filter, dots walk through links), and typing a function name offers completions with their signatures — Enter or Tab accepts.
Prefer plain English? Describe what you want in the ✨ Or describe it box — "profit margin as a percent" — and press Write it for me. The formula is generated and validated against your real schema before it lands in the box, so it can never hand you something that doesn't compile. It counts as one AI action.
Unlike Lookup and Rollup, a formula's expression can be edited any time from its row in the field list — there's no need to delete and recreate it.
Show a computed value as money, a percentage or a bar
Most field types carry their own formatting: a Currency field shows money, a Progress field draws a bar. A Formula or a Rollup has already spent its type saying "this is calculated", so it gets to say how it should look separately — with the Show as setting on the field.
Pick one of:
• Number — thousands separators, e.g. 1,234.5.
• Currency — money in your currency and locale, e.g. £1,234.50. A line total of {Qty} * {Unit Price} reads like the Currency column beside it instead of like a bare number.
• Percent — a trailing %, e.g. 42%. The number isn’t scaled: a formula producing 42 reads as 42%.
• Progress — the same percentage plus the filled bar you get from a Progress field, so {Done} / {Total} * 100 looks like progress.
• Duration — minutes as hours and minutes, e.g. 150 becomes 2:30.
For Number, Currency and Percent you can also set Decimals, which is worth doing on anything involving division — that’s how a value acquires fourteen decimal places. Leave it on Auto and the format decides.
This changes the display only. The underlying number is untouched, so filters, sorting, totals and rollups over the field all keep working on the real value — a currency-formatted formula still sorts as a number, not as text.
The format follows the value everywhere it goes: the grid, the peek drawer, the record page, reports and their CSV and PDF exports, generated documents, dashboard tiles, and the grid’s own CSV export. Like the expression itself, it can be changed any time from the field’s row in the field list — no need to delete and recreate.
Lookup fields deliberately have no Show as setting: a lookup re-presents a field that already has a type of its own, and letting the copy restate the formatting is how the two drift apart.
Delete a field
Click the × at the end of a field's row and confirm Delete this field?. The column disappears from the grid and forms right away, but your records are untouched — the values that were stored under that field are hidden, not erased.
Because values are kept, adding a new field later with the identical key brings the old data back into view. New fields are added at the end of the column order, so deleting and re-adding a field also moves it last.
Table emoji and accent color
Every table gets an emoji and an accent color automatically from its template type: Customer 🧑 mint, Project 📁 violet, Task ✅ amber, Asset 📦 sky, Event 📅 rose, Invoice 💸 coral, Document 📄 ink, and Custom 🧱 violet.
They appear on the table's card, at the top of the grid, and in accents like the fill of Percent bars. A table without an emoji shows the first letter of its name instead.
The emoji is yours to change: right-click the table in the left rail and choose Change icon…, or use the Name & icon card in the field editor. Both open the same picker — search by what the table is about, take one you used recently, or paste any emoji — and Remove icon goes back to the first letter. The accent color is set by the template type and is not editable.
Name tables and fields so they read like English
Names are the one thing in a workspace that's hard to change later — every report, rollup, and AI prompt refers to your tables and fields by name, so a clean name keeps everything downstream clean. Four rules keep them honest:
• Tables are plural nouns. Customers, Deals, Bookings — so one record reads naturally as "a Customer."
• Fields are descriptive singular phrases. Just Email, not cust_email — the table already supplies the scope.
• No abbreviations. Spell it out: Expected close, not Exp Cls. It saves more time than it costs.
• Relation fields name the other side, not the action. The field on Deals that points at Companies is simply Company — not company_id or linked_company.
The payoff is readability: "Sum of Amount across Deals where Stage is Closed Won" is a sentence you can trust; SUM(deal_amt) WHERE stg = 'CW' is a guess at meaning. Watch for names that signal a deeper problem — Status1 / Status2 usually wants two real names like Stage and Health, and a Misc or Other field is often a sign you need a new table or to split an existing one.
Know when to split a table
A table starts as one concept; as it grows you'll feel one of three signs that it's really two concepts wearing one costume. Splitting early is cheap — splitting late is painful.
• Half the fields are empty for half the rows. If Tasks has renewal_amount and contract_term filled in only for renewal rows, that's two things — split into Tasks and Renewals, with a relation between them if they belong together.
• You keep filtering by one field. If you filter Contacts by type = "Customer" every single time, that field is doing a table's job — split into Customers and Leads, each with its own fields and relations.
• Two distinct lifecycles. If some rows run "Open → In progress → Won → Lost" and others run "Draft → Submitted → Paid," they follow different state machines and belong in different tables, even when they share a few fields.
To split safely: create the new table with its unique fields, add a relation back to the original if they stay connected, move the rows with filter → Export CSV → import, update any reports that pointed at the old table, then soft-delete the moved rows (they wait in the Trash if you need them). And resist the urge when it isn't warranted — if two kinds of row share most fields and the same lifecycle, a Select field is plenty. The test: would you write different paragraphs about them?
Auto-number fields: invoice and order numbers that mind themselves
An Auto number field gives every record a permanent sequential number — perfect for invoices, orders, tickets, and quotes. Choose a starting number when you create the field (say 1000); existing records are numbered immediately, oldest first, and every new record takes the next number automatically no matter how it arrives: typed into the grid, imported, created by an automation, the API, a connector, or the AI.
The numbers are read-only by design — nobody can edit, reuse, or accidentally clear one — and they sort and filter like any other number. Records imported with their own numbers keep them.
Attachment fields: files on the record
An Attachment field holds files — contracts on a deal, photos on an inspection, CVs on a candidate. Add files from anywhere the clip appears — click it in the grid, on a board or gallery card, in the record drawer or on the record page, and the same panel opens: every file listed, images previewed, download or remove, and one way in for new ones. You can drop files straight onto the cell or card instead. A greyed clip means no files yet, which is still the way to add the first. 10 MB per file, up to 10 files per field; tick One file only on the field if a second would be a mistake — a signed contract, a profile photo — and a new upload replaces the old one instead of piling up. Files are stored privately (Azure Blob storage in production) and downloads run through the same permission checks as everything else — a hidden field's files stay hidden. Executable file types are refused outright.
AI fields: a column a model writes
An AI field is a column a model writes for you. You give the field an instruction once, and it applies to every record — “In one line, is this project on track? Status {{record.status}}, {{record.openTasks}} open tasks.”
The {{record.something}} bits pull in that record's own values. They are the same tokens automations use, so a linked record arrives as its name rather than an internal id, and you can reach through a link with a dot — {{record.company.region}}. The field editor lists your fields as buttons; clicking one inserts the right token, so there is nothing to memorise.
Nothing happens until you ask
Cells stay empty until you fill them. That is deliberate — it means opening a big table never quietly spends your AI allowance.
• One cell: hover it and click the ✦.
• Many at once: tick the rows, then Fill with AI in the bar at the bottom. It tells you how many cells it will write before it writes any, then runs in the background — the rows fill in as they finish, and you get a notification at the end. Up to 500 rows per run; filter the view down if you need more.
You can always correct it
An AI cell is ordinary text once written: type over it whenever the model gets something wrong. RowFold remembers which cells you have corrected, so a bulk fill skips them and tells you how many it left alone. If you do want them replaced, it asks first — a correction is never lost to a stray click.
Because the value is real text, everything else works on it normally: filter by it, sort by it, group by it, search it, export it, read it through the API.
What it costs
One cell is one AI action from your workspace's monthly allowance, so a 200-row fill is 200 actions. If the allowance runs out mid-run the fill stops and tells you where it got to, rather than failing silently on every remaining row.
Changing the prompt later doesn't rewrite cells you have already filled — regenerate the ones you want updated.
Deleting a table, and getting it back
Right-click a table in the sidebar and choose Delete table…. It is admin-only, and nothing is destroyed: the table keeps every record and waits in Trash until an admin restores it. There is no countdown — a deleted table stays until you put it back.
It will refuse if something still points at the table, and say what. A published form, mailbox, chat widget or booking page that writes here; a switched-on automation; a link on another table; or a lookup or rollup somewhere else that reads through this table. Each of those either keeps writing to something nobody can see, or leaves a column on a table you did not delete with nothing to read — so the delete stops and lists them. Each name is a link to the page where you change it: the form or mailbox itself, the automation, or the exact field on the other table.
Things that merely stop working do not block it, because they come back whole when you restore: reports built on the table, its print templates, and any paused automation. Those are listed in the confirmation so nothing is a surprise.
Tips
• Fields show up in the grid in the order you add them — plan your column order before you start adding.
• Lookup and Rollup routes can cross several relationships — the route picker groups them by distance ("Directly linked", "2 relationships away", …).
• A record is named by its table's <strong>first</strong> field — put the one that identifies a record (its name, title, or number) at the top.
• Templates are a starting point: delete their fields or add your own freely after the table is created.
• Add a Relation field before a Lookup — the Lookup can only follow Relations that already exist on the table.
• In a Formula, {Field Name} works across a link too — {Company.Industry} needs no Lookup field first.
• An AI field never generates on its own — no cell is written until you click ✦ on it or run a bulk fill, so opening a big table costs nothing.
• A Date field can carry a time — tick <em>Include a time</em> on the field. Turning it off never erases times already stored.
Good to know
• Fields follow creation order and are reordered with the <strong>↑ ↓</strong> arrows; deleting then re-adding a field moves it to the end.
• Deleting the first field hands the name to whichever field is next — RowFold refuses if that one is a link, a file or a calculation, since nothing could name the records afterwards.
• Deleting a field hides its stored values but does not erase them; a new field with the identical key shows the old data again.
• A Lookup whose route crosses a to-many relation reaches many records and lists every value it finds — when you wanted one number, that's a Rollup (the builder offers the switch when it spots this).
• Select and MultiSelect options are one comma-separated line, so an individual choice can't contain a comma.
• A table's Template type is fixed at creation — you can reshape its fields, but you can't switch it to another type later.
• A Formula can reach through a link (Relation) field, but not through another link's Lookup, Rollup, Formula, or Attachment field — pull that value in with a Lookup first, then reference the Lookup.
• A bulk fill skips cells you have edited by hand unless you explicitly tell it to overwrite them — so if a row looks stale after a fill, check whether someone corrected it earlier.
Who can do what
• Only workspace Admins see the New table and Build with AI buttons, and the server re-checks the Admin role when the create form is submitted.
• The Tables page lists only tables from workspaces you belong to.
• Any member of a table's workspace can open the field editor and add or delete fields — this is not restricted to Admins.
• Members of an empty workspace who aren't Admins see a note asking them to have an Admin create the first table.