DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS
TABLES·OVERVIEW

Tables

Tables are how structured data lives in your Onnie workspace. Each table has typed columns, one or more saved views, and is the substrate everything else builds on: Tasks are records in a Tasks table, Pages can embed records, Onniebots read and write records, and Routines mutate records as automations run.

What a Table is

A Table is a collection of records (rows) shaped by fields (typed columns). Every field enforces its type at save time — a number field won't accept freeform text, a date field stores an ISO timestamp. On top of the data, you define views that filter, sort, group, and reorder columns without changing the underlying records.

A table contains:

  • Records — each row is a JSON object of { fieldName: value } pairs stored in a single fields column.
  • Fields — typed column definitions; name, type, settings, and optional metadata.
  • Views — named configurations of filters, sorts, visible fields, and column widths.
  • Computed fields — formula or AI-derived columns that evaluate automatically when a record changes.
  • References — fields (or inline text) that link a record to another record or to any other entity in the workspace.

Field types

Every column you add to a table has one of these types. See Fields for the full treatment.

Field typeWhat it holds
TEXTShort freeform string
LONGTEXTMulti-line text; optionally markdown-flagged
EMAILEmail address; renders as a clickable badge
PHONEPhone number; parsed via libphonenumber-js with a country flag
URLWeb address; renders as a clickable badge
NUMBERNumeric value; configurable currency, separators, decimal places
SERIALAuto-incrementing integer; read-only
BOOLEANTrue / false checkbox
DATETIMEDate, time, or datetime; timezone-aware in full datetime mode
SELECTSingle choice from a configured option list
MULTISELECTMultiple choices from the same option list
FILEOne or more file attachments (uploads via Cloudflare R2)
REFERENCELink to another record or workspace entity
FORMULADeterministic expression over other fields; evaluated synchronously
AIModel-generated value derived from other fields; evaluated asynchronously

FORMULA and AI fields are read-only in the grid — they recompute automatically. See Formulas and AI fields.

The types fall into a few natural families. All types except SERIAL, FORMULA, and AI accept manual input — the three exceptions are always read-only because their values are generated automatically. The distinction matters when you are choosing a type: if you need users to enter or edit the value directly, pick from the editable types; if you need a derived or system-assigned value, pick from the three read-only types.

Basic data — TEXT, LONGTEXT, EMAIL, PHONE, URL, NUMBER, BOOLEAN, and DATETIME cover the everyday building blocks. All accept manual input and can be cleared by the user. These eight types are appropriate for any value a person would type or pick directly.

  • Reach for TEXT for single-line values: names, titles, short identifiers, codes. TEXT is the lightest field — no special rendering beyond the raw string.
  • Reach for LONGTEXT when you expect paragraphs, multi-line notes, or markdown content. LONGTEXT fields unlock the rich-text editor and render markdown in read mode. If you are unsure which to use, prefer LONGTEXT — it degrades gracefully to a single line when the content is short.
  • EMAIL, PHONE, and URL are TEXT variants that add display formatting (clickable badges, phone country-flag parsing) and type-specific filter operators, without restricting what the cell stores.
  • NUMBER supports configurable formatting: currency symbol, thousands separators, and decimal places are all per-field settings. Aggregates (sum, average) are available in the grid footer for NUMBER columns.
  • BOOLEAN renders as a checkbox. It supports is true and is false filter operators, and is the natural type for any yes/no field.
  • DATETIME stores a date, a time, or both depending on the field's include_time setting. Full datetime mode is timezone-aware; date-only mode stores a calendar date without a time component.

AutoSERIAL is an auto-incrementing integer assigned by the database when a record is created.

The field is always read-only; you cannot set, clear, or reuse a SERIAL value. Typically a table has at most one SERIAL field — multiple are technically allowed but rarely useful. SERIAL is typically used as a human-readable record number alongside the internal UUID primary key. SERIAL values are sequential and permanent — deleting a record does not reclaim or reuse its number.

ChoiceSELECT and MULTISELECT constrain input to a fixed option list you define on the field.

SELECT allows one choice at a time; MULTISELECT allows many simultaneously. Both support per-option colors, and options can be reordered or renamed without affecting stored values. Board view requires exactly one SELECT field as its grouping column. Use SELECT when each record has a single state (e.g., a status); use MULTISELECT when records can belong to multiple categories at once (e.g., tags).

AttachmentsFILE stores one or more uploaded files per cell (uploads go to Cloudflare R2).

Multiple files can be attached to a single record. Filtering on a FILE field is limited to emptiness checks and MIME type matching. Images are previewed inline in the grid; other file types show a filename and download link.

ComputedFORMULA and AI derive their value from other fields rather than accepting user input. Both are always read-only in the grid — there is no manual-edit path.

  • FORMULA evaluates a deterministic expression synchronously whenever a depended-on field changes. Results land sub-second. The expression syntax supports arithmetic, comparisons, logical operators, ternary, and a built-in math + text function library, with {{Column Name}} placeholders.
  • AI sends a free-form instruction (also with {{Column Name}} placeholders) to an AI model. Evaluation is asynchronous; the cell shows a pulse indicator until the model responds. AI fields consume credits and can be configured to run on create, on update, or manually.

Neither FORMULA nor AI fields can reference each other — cross-runtime dependencies are rejected at save time.

RelationalREFERENCE links a record to another record in the same or a different table, or to any other entity in the workspace (a page, a bot, a task). References are anchored on the target's UUID, so a renamed target updates its displayed label automatically. You can also embed references inline in LONGTEXT cells by pressing @ in the editor, which inserts a [label](ref:type:id) token.

The Onnie AI follows REFERENCE fields when reasoning about your data — a customer record that references a set of Task records gives the AI full context without duplicating information across tables. Designing your schema around explicit references rather than duplicated text makes AI responses more accurate and workspace search more precise.

Views

A view is a saved lens on a table. It stores filters, sorts, visible fields, column widths, grouping, and (for board views) the column that drives swimlanes. Changing a view's configuration never touches the records themselves.

See Views for the full list of view types and configuration options.

Calculated and AI fields

Two field types compute their value automatically rather than accepting user input:

  • FORMULA — a deterministic expression with {{Column Name}} placeholders that evaluates synchronously when a depended-on field changes. Result is available sub-second.
  • AI — a free-form instruction string (also with {{Column Name}} placeholders) sent to an AI model. Evaluates asynchronously; the cell shows a pulse indicator until the result lands.

Both types share the same placeholder syntax and dependency graph. Neither can reference the other (cross-runtime dependencies are rejected at save time).

See Formulas and AI fields for expression syntax, AI field types, recompute triggers, and credit accounting.

References between Tables

A Reference field points a record at another record in the same or a different table — or at any other entity in the workspace (a page, a bot, a task). When the target is renamed, the displayed label updates automatically because references are anchored on the entity's UUID.

You can also embed references inline in LONGTEXT cells using the [label](ref:type:id) syntax — typed by pressing @ in the editor.

See References for the wire format, entity types, alias IDs, and what happens when a referenced entity is deleted.

How Tables connect to the rest of Onnie

  • Tasks live in a Tasks table — the Tasks module is a first-class table view with status, assignee, due date, and priority fields.
  • Pages can embed individual records or link to a table view, letting you annotate structured data with rich text.
  • Onniebots and Superagent read and write records directly — a bot can look up a customer row, update a status field, or add a new record as part of a conversation.
  • Routines mutate records on a schedule or in response to events — for example, marking overdue Tasks as late or syncing data from an external source.
  • The Onnie AI reasons about your workspace by following references from any text surface into the structured records they point at.