> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to Grist

The Grist connector lets your AI agent act in each user's Grist account. Each user connects their own Grist access token once, and Scalekit sends it with every call, so your agent never handles credentials. It comes with 48 tools.

**Authentication:** Bearer Token
**Categories:** Databases, Productivity
**Tools:** 48: 20 read, 24 write, 4 destructive
**Users sign in with:** Access token
**Built by:** Scalekit connector
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=GRIST)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the Grist connection

   In **AgentKit > Connections**, create a Grist connection. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

4. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'grist'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize Grist:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'grist_get_current_user',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "grist"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize Grist:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="grist_get_current_user",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user opens the link once and enters their Grist credentials there. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'grist_compare_docs',
  toolInput: {
    doc_id: '<doc_id>',
    doc_id2: '<doc_id2>',
  },
  connector: 'grist',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="grist_compare_docs",
    tool_input={
        "doc_id": "<doc_id>",
        "doc_id2": "<doc_id2>",
    },
    connection_name="grist",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `grist_compare_docs`

Compare Documents · Read-only

Compare a document with another document, for example a fork against its original.
Returns the left and right states, their common parent, and a summary of changes.
Use fork_doc to create a fork to compare.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `doc_id2` (`string`, required): ID of the second document to compare against.
- `detail` (`boolean`, optional): Set to true to include detailed change information. Leave empty for a summary only.
- `max_rows` (`integer`, optional): Maximum number of row changes to include in the detail. Leave empty for the server default.

Example input: `{"doc_id":"<doc_id>","doc_id2":"<doc_id2>"}`

### `grist_get_attachment_metadata`

Get Attachment Metadata · Read-only

Get the metadata of one attachment.
Returns fileName, fileSize, and timeUploaded.
Use list_attachments to find attachment IDs.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `attachment_id` (`integer`, required): Numeric ID of the attachment.
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"attachment_id":1,"doc_id":"<doc_id>"}`

### `grist_get_current_user`

Get Current User · Read-only

Get the profile of the user the API key belongs to.
Returns the user's id, name, and picture.
Use list_orgs to see what the user can access.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `grist_get_doc`

Get Document · Read-only

Retrieve a document's metadata: name, access level, pinned state, and its workspace.
Returns id, name, access, isPinned, urlId, and the containing workspace and org.
Use list_tables to see the document's contents.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_get_doc_states`

Get Document States · Read-only

Get a document's action history as a list of states, most recent first.
Returns a states array with a sequential number n and a hash h for each state.
Use list_doc_snapshots for backups.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_get_org`

Get Org · Read-only

Retrieve one organization (team site or personal area) by ID or subdomain.
Returns the org's id, name, domain, owner, access level, and created and updated timestamps.
Use list_orgs to discover orgs. Use list_workspaces to see what is inside one.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `org_id` (`string`, required): Organization (site) to use: its numeric ID, its subdomain such as acme, or the word current to use the site implied by the connected Grist host. Get IDs from the list orgs tool.

Example input: `{"org_id":"<org_id>"}`

### `grist_get_org_usage`

Get Org Usage · Read-only

Get usage statistics for all non-deleted documents in an organization.
Returns document counts by data limit status and attachment storage totals.
Only available to organization owners.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `org_id` (`string`, required): Organization (site) to use: its numeric ID, its subdomain such as acme, or the word current to use the site implied by the connected Grist host. Get IDs from the list orgs tool.

Example input: `{"org_id":"<org_id>"}`

### `grist_get_table_schema`

Get Table Schema · Read-only

Get a table's schema in the Frictionless Data table-schema format.
Returns a schema object describing each field's name and type.
Use list_columns for Grist-native column metadata instead.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Normalized name of the table, as shown as TABLE ID in Raw Data.
- `header` (`string`, optional): Header format: colId for normalized column IDs or label for human-friendly labels. Leave empty for the server default. One of: `colId`, `label`.

Example input: `{"doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_get_workspace`

Get Workspace · Read-only

Retrieve one workspace and the documents inside it.
Returns the workspace id, name, access level, and a docs array with each document's id, name, pinned state, and access.
Use list_workspaces to browse all workspaces in an org.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"workspace_id":1}`

### `grist_list_attachments`

List Attachments · Read-only

List the metadata of attachments stored in a document.
Returns a records array; each has an id and fields with fileName, fileSize, and timeUploaded.
Use get_attachment_metadata for one attachment.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `filter` (`string`, optional): JSON object, as a string, mapping column names to arrays of allowed values. Example: {"pet": ["cat", "dog"]} returns only rows whose pet is cat or dog. Leave empty for no filtering.
- `limit` (`integer`, optional): Maximum number of rows to return. 0 means no limit. Leave empty for no limit.
- `sort` (`string`, optional): Comma-separated column names giving the sort order. Prefix a column with - for descending order, for example pet,-age. Leave empty for the default order.

Example input: `{"doc_id":"<doc_id>"}`

### `grist_list_columns`

List Columns · Read-only

List the columns of a table.
Returns a columns array; each column has an id and a fields object with type, label, formula, isFormula, widgetOptions, and related settings.
Use this before add_records or update_records to learn valid column IDs and types.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.
- `hidden` (`boolean`, optional): Set to true to include hidden columns such as manualSort. Leave empty to exclude them.

Example input: `{"doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_list_doc_access`

List Document Access · Read-only

List the users who have access to a document.
Returns maxInheritedRole and a users array with id, name, email, and access level.
Use update_doc_access to change who has access.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_list_doc_snapshots`

List Document Snapshots · Read-only

List automatic snapshots (backups) of a document, most recent first.
Returns a snapshots array with snapshotId, lastModified, and docId.
Use get_doc_states for fine-grained action history.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `raw` (`boolean`, optional): Set to true to include snapshots that are not in the snapshot inventory. Leave empty for the normal list.

Example input: `{"doc_id":"<doc_id>"}`

### `grist_list_org_access`

List Org Access · Read-only

List the users who have access to an organization.
Returns a users array with id, name, email, and access level.
Use list_doc_access or list_workspace_access for narrower scopes.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `org_id` (`string`, required): Organization (site) to use: its numeric ID, its subdomain such as acme, or the word current to use the site implied by the connected Grist host. Get IDs from the list orgs tool.

Example input: `{"org_id":"<org_id>"}`

### `grist_list_orgs`

List Orgs · Read-only

List the organizations (team sites and personal areas) the connected user can access.
Returns an array of orgs with id, name, domain, owner, access level, and created and updated timestamps.
Use this first to find an org ID, then list_workspaces to browse its documents. Use get_org for one org.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `grist_list_records`

List Records · Read-only

Fetch records (rows) from a table, optionally filtered, sorted, and limited.
Returns a records array; each record has an id and a fields object mapping column names to cell values.
Use run_sql_query for joins or aggregates. Use list_columns to see the column names first.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.
- `cell_format` (`string`, optional): Cell value format: normal (default) or typed, which returns self-describing typed values such as dates as ["d", timestamp]. Leave empty for normal. One of: `normal`, `typed`.
- `filter` (`string`, optional): JSON object, as a string, mapping column names to arrays of allowed values. Example: {"pet": ["cat", "dog"]} returns only rows whose pet is cat or dog. Leave empty for no filtering.
- `hidden` (`boolean`, optional): Set to true to include hidden columns such as manualSort. Leave empty to exclude them.
- `limit` (`integer`, optional): Maximum number of rows to return. 0 means no limit. Leave empty for no limit.
- `sort` (`string`, optional): Comma-separated column names giving the sort order. Prefix a column with - for descending order, for example pet,-age. Leave empty for the default order.

Example input: `{"doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_list_tables`

List Tables · Read-only

List the tables in a document.
Returns a tables array with each table's id and fields; with expand set to column, each table also includes its column metadata.
Use list_columns for a single table's columns. Use list_records to read rows.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `expand` (`string`, optional): Set to column to include column metadata for each table. Leave empty to omit it. One of: `column`.

Example input: `{"doc_id":"<doc_id>"}`

### `grist_list_workspace_access`

List Workspace Access · Read-only

List the users who have access to a workspace.
Returns maxInheritedRole and a users array with id, name, email, and access level.
Use update_workspace_access to change who has access.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"workspace_id":1}`

### `grist_list_workspaces`

List Workspaces · Read-only

List the workspaces in an organization, including the documents inside each workspace.
Returns an array of workspaces, each with id, name, access level, and a docs array of document id, name, pinned state, and access.
Use this to find document IDs for the table and record tools. Use get_workspace for a single workspace.
Requires an org ID from list_orgs, or the value current.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `org_id` (`string`, required): Organization (site) to use: its numeric ID, its subdomain such as acme, or the word current to use the site implied by the connected Grist host. Get IDs from the list orgs tool.

Example input: `{"org_id":"<org_id>"}`

### `grist_run_sql_query`

Run SQL Query · Read-only

Run a read-only SQL SELECT query against a document's SQLite database.
Returns the statement and a records array; each record has a fields object of column values.
Use list_records for simple reads. Use this for joins, aggregates, and WITH clauses. Table names are the table IDs from list_tables.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `sql` (`string`, required): A single SELECT statement with no trailing semicolon. WITH clauses are allowed; statements that modify data are not. Use ? placeholders together with args for values. Example: SELECT Name, Age FROM People WHERE Age > ?.
- `args` (`array`, optional): Values for the ? placeholders in sql, in order. Each is a number or string. Example: [30]. Leave empty if the query has no placeholders.
- `timeout` (`number`, optional): Query timeout in milliseconds. Defaults to the server setting (1000) and can only be lowered, not raised. Leave empty for the default.

Example input: `{"doc_id":"<doc_id>","sql":"<sql>"}`

### `grist_add_columns`

Add Columns · Write

Add one or more columns to an existing table.
Returns a columns array with the id of each column created.
Use update_columns to change existing columns. Use create_tables to make a whole new table.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `columns` (`array`, required): Columns to add. Each item is an object with an id (the column name) and an optional fields object such as type (Any, Text, Numeric, Int, Bool, Date, DateTime:<timezone>, Choice, ChoiceList, Ref:<tableId>, RefList:<tableId>, Attachments), label, formula, isFormula, and widgetOptions (a JSON string). Example: [{"id": "Email", "fields": {"type": "Text", "label": "Email"}}].
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.

Example input: `{"columns":[{"id":"Email","fields":{"type":"Text","label":"Email"}}],"doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_add_records`

Add Records · Write

Add one or more records (rows) to a table.
Returns a records array with the id of each new record, in the order given.
Use update_records to change existing rows. Use upsert_records to add or update by matching values.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `records` (`array`, required): Records to add. Each item is an object with a fields object mapping column names to values. Example: [{"fields": {"Name": "Ada", "Age": 36}}].
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.
- `noparse` (`boolean`, optional): Set to true to store string values exactly as given instead of parsing them according to the column type (for example dates will not be converted). Leave empty to use Grist's default parsing.

Example input: `{"doc_id":"<doc_id>","records":[{"fields":{"Name":"Ada","Age":36}}],"table_id":"<table_id>"}`

### `grist_apply_user_actions`

Apply User Actions · Write

Apply a batch of low-level Grist user actions to a document in one transaction.
Returns actionNum (the action number assigned) and retValues (return values such as new row IDs).
Use this only for operations the other tools cannot express, such as BulkAddRecord, AddTable, or RenameColumn. Prefer add_records, update_records, and delete_records for row changes.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `actions` (`array`, required): List of user actions. Each action is an array whose first item is the action name, for example ["AddRecord", "Table1", null, {"Name": "Ada"}], ["UpdateRecord", "Table1", 3, {"Name": "Ada L"}], or ["RemoveRecord", "Table1", 3].
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `noparse` (`boolean`, optional): Set to true to store string values exactly as given instead of parsing them according to the column type. Leave empty for default parsing.

Example input: `{"actions":[],"doc_id":"<doc_id>"}`

### `grist_copy_doc`

Copy Document · Write

Copy a document into a workspace.
Returns the string ID of the new document.
Set as_template to copy only the structure without data or history. Use fork_doc for a personal fork that tracks the original.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `document_name` (`string`, required): Name for the copied document.
- `workspace_id` (`integer`, required): Numeric ID of the workspace to place the copy in.
- `as_template` (`boolean`, optional): Set to true to remove all data and history and keep only the structure. Leave empty for a full copy.

Example input: `{"doc_id":"<doc_id>","document_name":"<document_name>","workspace_id":1}`

### `grist_create_doc`

Create Document · Write

Create an empty document in a workspace.
Returns the string ID of the new document.
Use copy_doc to duplicate an existing document instead. Use create_tables afterwards to add tables.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.
- `is_pinned` (`boolean`, optional): Set to true to pin the document so it appears prominently in the workspace. Leave empty to leave it unpinned.
- `name` (`string`, optional): Name for the new document.

Example input: `{"workspace_id":1}`

### `grist_create_tables`

Create Tables · Write

Add one or more tables, with their columns, to a document.
Returns a tables array with the id of each table created.
Use add_columns to add columns to an existing table. Use add_records to fill a table with rows.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `tables` (`array`, required): Tables to create. Each item is an object with an optional id (the table name) and a columns array; each column has an id and an optional fields object (for example type, label, formula). Example: [{"id": "People", "columns": [{"id": "Name", "fields": {"type": "Text"}}, {"id": "Age", "fields": {"type": "Int"}}]}].

Example input: `{"doc_id":"<doc_id>","tables":[{"id":"Table1","fields":{"tableId":"Customers"}}]}`

### `grist_create_workspace`

Create Workspace · Write

Create an empty workspace in an organization.
Returns the numeric ID of the new workspace.
Use create_doc afterwards to add documents to it.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): Name for the new workspace.
- `org_id` (`string`, required): Organization (site) to use: its numeric ID, its subdomain such as acme, or the word current to use the site implied by the connected Grist host. Get IDs from the list orgs tool.

Example input: `{"name":"<name>","org_id":"<org_id>"}`

### `grist_fork_doc`

Fork Document · Write

Create a personal fork of a document that tracks its relationship to the original.
Returns forkId, docId, and urlId of the new fork.
Use compare_docs to see the fork's changes against the original. Use copy_doc for an independent copy.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_move_doc`

Move Document · Write

Move a document to another workspace.
Returns an empty success response.
Use list_workspaces to find the target workspace ID.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `workspace_id` (`integer`, required): Numeric ID of the workspace to move the document into.

Example input: `{"doc_id":"<doc_id>","workspace_id":1}`

### `grist_pin_doc`

Pin Document · Write

Pin a document so it appears at the top of its workspace listing.
Returns an empty success response.
Use unpin_doc to undo.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_restore_doc`

Restore Document · Write

Restore a document that was moved to the trash.
Returns an empty success response.
Only works while the document is still in the trash.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_restore_workspace`

Restore Workspace · Write

Restore a workspace that was moved to the trash.
Returns an empty success response.
Only works while the workspace is still in the trash.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"workspace_id":1}`

### `grist_trash_doc`

Move Document to Trash · Write

Move a document to the trash so it can be restored later.
Returns an empty success response.
Use restore_doc to undo. Use delete_doc for permanent deletion.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_trash_workspace`

Move Workspace to Trash · Write

Move a workspace to the trash so it can be restored later.
Returns an empty success response.
Use restore_workspace to undo. Use delete_workspace for permanent deletion.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"workspace_id":1}`

### `grist_unpin_doc`

Unpin Document · Write

Unpin a previously pinned document.
Returns an empty success response.
Use pin_doc to pin it again.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_update_columns`

Update Columns · Write

Modify existing columns of a table, such as their type, label, or formula.
Returns an empty success response.
Use upsert_columns to add or update in one call. Use add_columns to add only.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `columns` (`array`, required): Columns to change. Each item is an object with id (the column's current id) and fields, an object with the properties to set such as type, label, formula, isFormula, or widgetOptions. Example: [{"id": "Email", "fields": {"label": "Work Email"}}].
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.

Example input: `{"columns":[{"id":"Email","fields":{"label":"Work Email"}}],"doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_update_doc`

Update Document · Write

Rename a document or change its pinned state, without changing its contents.
Returns an empty success response.
Use pin_doc or unpin_doc when only the pinned state changes.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `is_pinned` (`boolean`, optional): Set to true to pin the document or false to unpin it. Leave empty to keep the current state.
- `name` (`string`, optional): New name for the document. Leave empty to keep the current name.

Example input: `{"doc_id":"<doc_id>"}`

### `grist_update_doc_access`

Update Document Access · Write

Change who has access to a document and at what level.
Returns an empty success response.
Use list_doc_access to see current access first.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `delta` (`object`, required): Changes to make to a document's access, as an object with optional keys maxInheritedRole (one of owners, editors, viewers) and users (an object mapping a user email address to a role: owners, editors, viewers, or members; use null to remove that user's access). Example: {"users": {"ann@example.com": "editors", "bob@example.com": null}}.
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"delta":{},"doc_id":"<doc_id>"}`

### `grist_update_records`

Update Records · Write

Update existing records (rows) of a table by record id.
Returns an empty success response.
Use list_records to find record ids. Use upsert_records to match rows by column values instead of id.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `records` (`array`, required): Records to change. Each item is an object with id (the numeric record id) and fields (an object mapping column names to new values). Only the listed columns change. Example: [{"id": 1, "fields": {"Age": 37}}].
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.
- `noparse` (`boolean`, optional): Set to true to store string values exactly as given instead of parsing them according to the column type (for example dates will not be converted). Leave empty to use Grist's default parsing.

Example input: `{"doc_id":"<doc_id>","records":[{"id":1,"fields":{"Age":37}}],"table_id":"<table_id>"}`

### `grist_update_tables`

Update Tables · Write

Rename tables or change their on-demand loading setting.
Returns an empty success response.
Use update_columns to change columns instead.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `tables` (`array`, required): Tables to change. Each item is an object with id (the table's current id) and fields, an object with tableId (a new name to rename the table) and or onDemand (boolean). Example: [{"id": "Table1", "fields": {"tableId": "Customers"}}].

Example input: `{"doc_id":"<doc_id>","tables":[{"id":"Table1","fields":{"tableId":"Customers"}}]}`

### `grist_update_workspace`

Update Workspace · Write

Rename a workspace.
Returns an empty success response.
Use get_workspace to confirm the change.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `name` (`string`, required): New name for the workspace.
- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"name":"<name>","workspace_id":1}`

### `grist_update_workspace_access`

Update Workspace Access · Write

Change who has access to a workspace and at what level.
Returns an empty success response.
Use list_workspace_access to see current access first.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `delta` (`object`, required): Changes to make to a workspace's access, as an object with optional keys maxInheritedRole (one of owners, editors, viewers) and users (an object mapping a user email address to a role: owners, editors, viewers, or members; use null to remove that user's access). Example: {"users": {"ann@example.com": "editors", "bob@example.com": null}}.
- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"delta":{},"workspace_id":1}`

### `grist_upsert_columns`

Add or Update Columns · Write

Add columns that do not exist and update those that do, matching on column id.
Returns an empty success response. Columns not listed are left unchanged.
Use add_columns or update_columns when you only need one of the two behaviors.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `columns` (`array`, required): Columns to add or update. Each item is an object with id (the column id) and fields (properties such as type, label, formula). A column whose id already exists is updated, otherwise it is created. Example: [{"id": "Score", "fields": {"type": "Numeric"}}].
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.
- `noadd` (`boolean`, optional): Set to true to prevent adding new columns, so only existing columns are updated. Leave empty to allow adding.
- `noupdate` (`boolean`, optional): Set to true to prevent updating existing columns, so only new columns are added. Leave empty to allow updating.

Example input: `{"columns":[{"id":"Score","fields":{"type":"Numeric"}}],"doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_upsert_records`

Add or Update Records · Write

Add or update records by matching on column values, instead of by record id.
Returns an empty success response.
For each item, a row matching require is updated with fields; if none matches, a new row is created. Use add_records or update_records when you know you only need one of the two.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `records` (`array`, required): Records to add or update. Each item is an object with require (an object of column values used to find an existing row, or used to create a new one) and an optional fields object (values to set). Example: [{"require": {"Email": "ada@example.com"}, "fields": {"Age": 37}}].
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.
- `allow_empty_require` (`boolean`, optional): Set to true to allow an empty require object, which matches and updates every row in the table. Leave empty to reject empty require.
- `noadd` (`boolean`, optional): Set to true to prevent adding new rows, so only matching rows are updated. Leave empty to allow adding.
- `noparse` (`boolean`, optional): Set to true to store string values exactly as given instead of parsing them according to the column type (for example dates will not be converted). Leave empty to use Grist's default parsing.
- `noupdate` (`boolean`, optional): Set to true to prevent updating rows, so only new rows are added. Leave empty to allow updating.
- `onmany` (`string`, optional): What to do when several rows match require: first updates only the first match, none updates nothing, all updates every match. Leave empty for first. One of: `first`, `none`, `all`.

Example input: `{"doc_id":"<doc_id>","records":[{"require":{"Email":"ada@example.com"},"fields":{"Age":37}}],"table_id":"<table_id>"}`

### `grist_delete_column`

Delete Column · Destructive

Delete a column from a table. This permanently removes the column and its data.
Returns an empty success response.
Use list_columns first to confirm the column id.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `col_id` (`string`, required): Column identifier, without the leading $, as shown in the column configuration panel.
- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.

Example input: `{"col_id":"<col_id>","doc_id":"<doc_id>","table_id":"<table_id>"}`

### `grist_delete_doc`

Delete Document · Destructive

Delete a document permanently.
Returns an empty success response.
Use trash_doc instead for a recoverable removal.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).

Example input: `{"doc_id":"<doc_id>"}`

### `grist_delete_records`

Delete Records · Destructive

Delete records (rows) from a table by record id. This permanently removes the rows.
Returns an empty success response.
Use list_records first to find the record ids to delete.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `doc_id` (`string`, required): ID of the Grist document (a UUID-style string, also shown as the document's id in its URL or from Grist list workspaces results).
- `row_ids` (`array`, required): Numeric IDs of the records to delete. Example: [1, 2, 3].
- `table_id` (`string`, required): Table identifier: the normalized table name shown as TABLE ID in the document's Raw Data page (for example Table1), or its numeric row ID in _grist_Tables.

Example input: `{"doc_id":"<doc_id>","row_ids":[1,2,3],"table_id":"<table_id>"}`

### `grist_delete_workspace`

Delete Workspace · Destructive

Delete a workspace and all documents in it.
Returns an empty success response.
Use trash_workspace instead for a recoverable removal.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `workspace_id` (`integer`, required): Numeric ID of the workspace. Get it from the list workspaces tool.

Example input: `{"workspace_id":1}`

## Related

Other Databases connectors ([all 22](/agentkit/connectors/?category=databases)):

- [Snowflake](/agentkit/connectors/snowflake/): Scalekit connector, OAuth, 42 tools
- [AWS Redshift](/agentkit/connectors/redshift/): Scalekit connector, Trusted identity provider, 10 tools
- [Google BigQuery](/agentkit/connectors/bigquery/): Scalekit connector, OAuth, 47 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
