Tables
Pages made of rows and columns, for lists of records that share the same fields. Each row is searchable on its own, and agents can filter and sort them.
Updated
Some context isn't prose. A price list, a list of accounts, a product catalogue, a set of integrations with their status: records that all have the same fields. Written as a Markdown page, a list like that is hard to search (a long table gets chopped into chunks that lose their header) and impossible to filter. A table is a page whose body is rows and columns instead.
A table is still a page. It lives in a folder, has a type, tags, a usage note and owners, can be a private note, and goes through the same draft-and-publish flow. What changes is the body, and what agents can do with it.
Making a table
Three ways:
- New table in the sidebar (the grid icon next to New page, or New table in a folder's menu). It starts with two columns to rename.
- Import a CSV. A CSV becomes a table unless you choose otherwise. See Importing what you have.
- Turn a page into a table. A page whose body holds a Markdown table offers Turn into a table beneath the editor. The table's header becomes the columns, its rows the rows, and any text around it stays as the description. A table can go back the same way.
Agents can make tables too, with create_table, when they're handed a list of records. See When agents write back.
The grid
Click a cell to edit it. Enter saves and moves down, Tab moves across, Escape puts the old value back. Paste a block of cells from a spreadsheet into a cell and it fills to the right and down, adding rows as needed. Add row at the bottom adds one; the bin at the end of a row removes it.
Double-click a column name to rename it. The ⋯ on a column header has the rest: its type (text, number, date, link or choice; the type decides how rows sort and compare), whether it's the column that names each row, its position, and removing it. The + at the right adds a column.
The box above the grid filters rows as you type, and clicking a column header sorts by it. Neither changes anything; they're for finding your way around. CSV downloads the draft rows.
Rows save as you go, like page text. Dots in the left margin mark rows added or changed since the last publish, and a line above the grid counts them. Rows you remove stay published until you publish again, and Restore removed brings them back before then.
The description
Above the grid is the table's description, a short Markdown body. Write what's in the table and when to use it: "One row per plan. Prices in USD, excluding tax. Enterprise is a starting price." It matters more than it looks: the description is what gets the table found for a task, and what agents read before they trust a row. A table with no description is found only by the words in its rows.
What agents get
When you publish, each row becomes its own section, titled by its name column ("Price list › Enterprise") with its cells as "Column: value" lines. search and get_context return the rows that match a task, with a note saying how many rows the table has and how to get the rest.
For everything search can't do, agents have query_table: filter rows by column (equals, contains, greater than, in a list, empty…), sort by a column, pick columns, and page through. "Every account in EMEA with ARR over 50k" is one call. read_page returns the description and as many rows as fit in a few thousand tokens, and get_file returns the whole table as a CSV, generated when you publish.
A table is never sent whole as a rule or pinned page beyond what fits; a pinned table comes back as its description plus the first rows and a pointer to query_table.
The same is available over the REST API: a page read includes the table's columns and first rows, and /pages/{page}/rows filters and sorts.
Agents editing tables
Connections that can edit get add_rows, update_rows and delete_rows alongside create_table. Changes land in the draft, like page edits: agents keep getting the published rows until someone publishes. read_draft shows a table's columns and rows with their ids, which is how an agent names the row it wants to change. Every change is listed under Activity → Agent edits and can be undone.
An agent's edit_page and rewrite_page still work on a table page: they change the description.
Automations can write rows over the REST API too. PUT /pages/{page}/rows?key=URL syncs a whole list in one call: rows are matched on a column you choose instead of row ids, rows that haven't changed are left alone, and with "mode": "replace" rows that are no longer in the list are removed.
When to use a table, and when not to
Use a table when every record has the same fields and someone might want to sort or filter them: accounts, plans, SKUs, features and their status, integrations, events, contacts.
Keep a page when each item needs its own explanation (competitors with a paragraph of positioning each, case studies), when the content is rules or guidance, or when it's a short lookup table inside prose. A Markdown table of eight rows in a page is fine.
Agents are told the same thing in their tool descriptions, and a workspace's agent instructions can add a house rule ("all customer and pricing data goes in tables").
Limits
| Rows per table | 5,000 |
| Columns | 50 |
| Cell size | 4,000 characters |
Rows returned by one query_table call |
500 (default 50) |