# SeaTable

Work with a SeaTable base, or query it with SQL.

## Connect SeaTable

1. In the sidebar, open **Connections** and press **Add connection**.
2. Type `seatable` and choose **SeaTable**.
3. Fill in the fields. Each one says **Required** or **Optional**.
4. Press **Test and save**. GoRunner checks the connection before it saves anything.

The sheet asks for **API token** and **Server**.

[Connections](https://docs.gorunner.io/build/connections) says how to sign in again, rename or delete it. In a product that embeds GoRunner, **Add connection** can be missing: then [your provider makes connections](https://docs.gorunner.io/embed/customer-connections) for you.

## Start a workflow

Add a trigger and choose **SeaTable**. The trigger uses the same connection as the steps.

### On Row Added/Updated

Polls the table about once a minute and fires for each new or changed row. Each row arrives keyed by its column names, with change_type set to added or updated.

- **Table · Required**: The table to watch.
- **View · Optional**: Watch only the rows in this view: a filtered view keeps a big table cheap to poll. Leave empty for the whole table. The trigger reads at most 10,000 rows, so a bigger table needs a view.
- **Trigger on · Optional**: When to fire: a new row, a changed row, or either. Options: Row added, Row updated, Row added or updated. Default: Row added.

A later step can use its data, such as `{{trigger._id}}`, `{{trigger._mtime}}`, `{{trigger.change_type}}`. See [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

## Do things in SeaTable

Add a **SeaTable** step, choose a **Resource**, then an **Operation**. Choose a row to see its fields.

- [Row](https://docs.gorunner.io/apps/seatable#fields-f-row): List rows · Get a row · Create a row · Create many rows · Update a row · Update many rows · Delete rows · Lock rows · Unlock rows
- [Table](https://docs.gorunner.io/apps/seatable#fields-f-table): List tables · Create a table · Rename a table · Duplicate a table · Delete a table
- [Column](https://docs.gorunner.io/apps/seatable#fields-f-column): List columns · Add a column · Update a column · Delete a column
- [View](https://docs.gorunner.io/apps/seatable#fields-f-view): List views · Get a view · Create a view · Update a view · Delete a view
- [Link](https://docs.gorunner.io/apps/seatable#fields-f-link): List linked rows · Link rows · Replace links · Unlink rows
- [File](https://docs.gorunner.io/apps/seatable#fields-f-file): Upload a file · Get an upload link · Get a download link · Delete a file
- [Comment](https://docs.gorunner.io/apps/seatable#fields-f-comment): List a row's comments · Get a comment · Delete a comment
- [Notification](https://docs.gorunner.io/apps/seatable#fields-f-notification): List notifications · Show a message to a user
- [Base](https://docs.gorunner.io/apps/seatable#fields-f-base): Run SQL · Get the base's structure · List collaborators

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, SeaTable is `pieceId: "seatable"` with `actionId: "seatable"`, set by `resource` and an `operation_…` field, such as `operation_base`. Its trigger is `seatabletrigger` / `seatable_poll`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

It can change something outside the run (`writes_external`). See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### SeaTable › Row

### List rows

- **Table · Required**: The table to work in.
- **View · Optional**: Only rows visible in this view. Leave empty for the whole table.
- **Start · Optional**: How many rows to skip (0-based offset). Default: 0.
- **Limit · Optional**: How many rows to return (1–1000). Default: 100.
- **Return all rows · Optional**: Page through the whole table (up to 10 000 rows) instead of one page. Off by default.
- **Column names as keys · Optional**: Key each row by its column names (recommended). Turn off for SeaTable's internal column keys. On by default.

### Get a row

- **Table · Required**: The table to work in.
- **Row ID · Required**: The row's _id (such as from a List rows or trigger step).
- **Column names as keys · Optional**: Key each row by its column names (recommended). Turn off for SeaTable's internal column keys. On by default.

### Create a row

- **Table · Required**: The table to work in.
- **Row · Required**: The row's values as a JSON object keyed by column name, such as {"Name": "Ada", "Active": true}. Columns you leave out are untouched.
- **Apply column defaults · Optional**: Fill columns you leave out with their default value. Off by default.

### Create many rows

- **Table · Required**: The table to work in.
- **Rows · Required**: A JSON array of row objects keyed by column name, up to 1000 per call.
- **Apply column defaults · Optional**: Fill columns you leave out with their default value. Off by default.

### Update a row

- **Table · Required**: The table to work in.
- **Row ID · Required**: The row's _id (such as from a List rows or trigger step).
- **Row · Required**: The row's values as a JSON object keyed by column name, such as {"Name": "Ada", "Active": true}. Columns you leave out are untouched.

### Update many rows

- **Table · Required**: The table to work in.
- **Updates · Required**: A JSON array of {"row_id": "…", "row": {"Column": value}} objects, up to 1000 per call.

### Delete rows, Lock rows and Unlock rows

- **Table · Required**: The table to work in.
- **Row IDs · Required**: One or more row _ids, comma-separated, or an expression that resolves to a list.

### SeaTable › Table

### List tables

Nothing to fill in.

### Create a table

- **Name · Required**: The table's (new) name.
- **Columns · Optional**: Optional column definitions, such as [{"column_name": "Name", "column_type": "text"}]. Leave empty for SeaTable's default columns.

### Rename a table

- **Table · Required**: The table to change.
- **Name · Required**: The table's (new) name.

### Duplicate a table

- **Table · Required**: The table to change.
- **Copy the rows too · Optional**: Duplicate the rows along with the table's structure. Off by default.

### Delete a table

- **Table · Required**: The table to change.

### SeaTable › Column

### List columns

- **Table · Required**: The table whose columns to work with.
- **View · Optional**: Only the columns visible in this view. Leave empty for all.

### Add a column

- **Table · Required**: The table whose columns to work with.
- **Column name · Required**: The new column's name.
- **Type · Optional**: The column's type. Options: Text to Button (23 options). Default: Text.
- **Column settings · Optional**: Type-specific settings as JSON, such as {"options": [{"name": "High", "color": "#FF8000"}]} for a select column or {"format": "YYYY-MM-DD"} for a date. Leave empty for the type's defaults.
- **Insert after · Optional**: Place the new column after this one. Leave empty to append it at the end.

### Update a column

- **Table · Required**: The table whose columns to work with.
- **Column · Required**: The column to change.
- **New name · Optional**: Rename the column. Leave empty to keep its name.
- **Column settings · Optional**: Type-specific settings as JSON, such as {"options": [{"name": "High", "color": "#FF8000"}]} for a select column or {"format": "YYYY-MM-DD"} for a date. Leave empty for the type's defaults.

### Delete a column

- **Table · Required**: The table whose columns to work with.
- **Column · Required**: The column to change.

### SeaTable › View

### List views

- **Table · Required**: The table whose views to work with.

### Get a view and Delete a view

- **Table · Required**: The table whose views to work with.
- **View · Required**: The view.

### Create a view

- **Table · Required**: The table whose views to work with.
- **View name · Required**: The new view's name.
- **Type · Optional**: How the view shows its rows. Options: Table, Gallery, Kanban, Calendar, Timeline, Map. Default: Table.
- **Lock the view · Optional**: Stop people changing the view's filters, sorts and layout in SeaTable. Off by default.

### Update a view

- **Table · Required**: The table whose views to work with.
- **View · Required**: The view.
- **View settings · Required**: The view fields to overwrite, such as {"filters": [{"column_name": "Status", "filter_predicate": "is", "filter_term": "Open"}], "sorts": [{"column_name": "Due", "sort_type": "up"}], "hidden_columns": ["Notes"]}.

### SeaTable › Link

### List linked rows

- **Table · Required**: The table that holds the link column.
- **Link column · Required**: The link column. Its target table and link id are resolved for you.
- **Row IDs · Required**: The rows to read links for: comma-separated ids, or an expression that resolves to a list.

### Link rows, Replace links and Unlink rows

- **Table · Required**: The table that holds the link column.
- **Link column · Required**: The link column. Its target table and link id are resolved for you.
- **Links · Required**: Which rows to link: a JSON object mapping each row id in this table to the ids it links to in the other table, such as {"Qtf7xPmoRaiFyQPO1aENTj": ["Bko1e60YT-egit2SljWSZA"]}.

### SeaTable › File

### Upload a file

- **File · Required**: Upload a file, or switch to an expression to use one from an earlier step (such as {{steps.download.result}}).
- **For · Optional**: Which kind of column the file is for. It decides the folder SeaTable stores it in. Options: A File column, An Image column. Default: A File column.
- **File name · Optional**: Store the file under this name. Leave empty to keep the uploaded file's name.
- **Replace an existing file · Optional**: Overwrite a file with the same name instead of storing a renamed copy. Off by default.

### Get an upload link

- **For · Optional**: Which kind of column the file is for. It decides the folder SeaTable stores it in. Options: A File column, An Image column. Default: A File column.

### Get a download link and Delete a file

- **Path · Required**: The file's path inside the base's assets, such as files/2026-08/report.pdf. It is the part after /asset/\<base uuid>/ in a file column's URL.

### SeaTable › Comment

### List a row's comments

- **Row ID · Required**: The row whose comments to list.

### Get a comment and Delete a comment

- **Comment ID · Required**: The comment's id (from List a row's comments).

### SeaTable › Notification

### List notifications

- **Page · Optional**: Which page of notifications (1-based). Default: 1.
- **Per page · Optional**: How many notifications per page (1–100). Default: 25.

### Show a message to a user

- **To · Required**: The recipient's email address (or SeaTable user id). The message shows only for them, only while they have the base open.
- **Type · Optional**: The message's colour. Options: Success, Info, Warning, Danger. Default: Success.
- **Message · Required**: The text to show.

### SeaTable › Base

### Run SQL

- **SQL · Required**: One SELECT, UPDATE or DELETE statement (INSERT needs big-data storage). Use? placeholders and put the values in Parameters. Table and column names go in backticks; SELECT returns 100 rows unless you add LIMIT (max 10 000).
- **Parameters · Optional**: Values for the? placeholders, in order, as a JSON array, such as ["Open", 5]. A null is sent as NULL (it clears a cell in UPDATE … SET); if SeaTable refuses the statement, the error names each parameter that was null.
- **Column names as keys · Optional**: Key each result row by its column names (recommended). Turn off for SeaTable's internal column keys. On by default.

### Get the base's structure and List collaborators

Nothing to fill in.

Source: https://docs.gorunner.io/apps/seatable
