# Grist

> Read and write the records in your Grist documents, and build the tables and columns that hold them.

App · Databases · 16 actions. Web page: https://docs.lodol.com/docs/integrations/grist

## Actions

### Add a column

Add one column of a particular type to a table.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Column name (`column_name`, text, required): What to call the new column, for example 'Renewal date'.
- Column type (`column_type`, text, required): What the column holds. One of: `text`, `number`, `whole_number` (Whole number), `toggle` (Toggle (yes or no)), `date`, `datetime` (Date & time), `choice` (One choice from a list), `choice_list` (Several choices from a list), `reference` (A link to a record in another table), `reference_list` (Links to records in another table), `attachments`, `any` (Anything (Grist works it out)). Default: `text`.
- Choices (`choices`, list): The values this column allows. Only used when the column holds one or several choices.
- Linked table (`linked_table`, text): The table this column points at. Only used when the column links to another table.
- Time zone (`time_zone`, text): The time zone a date & time column displays in, for example Europe/Paris. Defaults to UTC.

**Outputs**

- `choices` (list): The choices it allows, for a choice column.
- `id` (text): The column ID used in record values.
- `links_to` (text): The table it points at, for a link column.
- `name` (text): The name it was given.
- `table_id` (text): The table it was added to.
- `type` (text): What it holds.

**Example output**

```json
{
  "id": "Renewal_date",
  "name": "Renewal date",
  "table_id": "Deals",
  "type": "Date"
}
```

### Add a record

Add a record to a table. The record comes back as Grist stored it, including its new record ID.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Column values (`fields`, object, required): The value for each column. Leave a column blank to leave it empty. Dates go in as 2026-03-01 (and times as 2026-03-01T09:30:00), and a choice-list or link-list column takes a list of values.

**Outputs**

- `errors` (object): Only present when a formula column failed: the column and the error.
- `fields` (object): The record's column values, keyed by column ID.
- `id` (number): The record's ID, which the other record actions take.

**Example output**

```json
{
  "fields": {
    "Amount": 1250,
    "Customer": "Acme Inc.",
    "Due": "2026-03-01",
    "Status": "Open",
    "Tags": [
      "Priority",
      "Renewal"
    ]
  },
  "id": 3
}
```

### Add or update a record

Find the record whose column holds a given value and update it, or add it when there is no such record. The result says which happened.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Match column (`match_column`, text, required): The column that identifies the record, such as an email address or an order number.
- Match value (`match_value`, text, required): The value that column must hold.
- Column values (`fields`, object, required): The values to set on the record, whether it is found or created. Leave a column blank to leave it alone.

**Outputs**

- `created` (true/false): True when the record was added, false when an existing one was updated.
- `errors` (object): Only present when a formula column failed: the column and the error.
- `fields` (object): The record's column values, keyed by column ID.
- `id` (number): The record's ID, which the other record actions take.

**Example output**

```json
{
  "created": false,
  "fields": {
    "Amount": 1250,
    "Customer": "Acme Inc.",
    "Due": "2026-03-01",
    "Status": "Open",
    "Tags": [
      "Priority",
      "Renewal"
    ]
  },
  "id": 3
}
```

### Create a document

Create an empty document in one of your workspaces.

**Inputs**

- Workspace (`workspace_id`, text, required): The workspace to create the document in.
- Document name (`document_name`, text, required): What to call the new document.

**Outputs**

- `id` (text): The document ID the other actions take.
- `name` (text): The name it was given.
- `team` (text): The team site or personal area.
- `url` (text): A link that opens the document.
- `workspace` (text): The workspace holding it.

**Example output**

```json
{
  "id": "9PJhBDZPyCNoayZxaCwFfS",
  "name": "Q2 campaign",
  "team": "Acme",
  "url": "https://acme.getgrist.com/9PJhBDZPyCNoayZxaCwFfS",
  "workspace": "Marketing"
}
```

### Create a table

Add a table to a document, naming the columns it starts with. Each column takes its type from the first value put in it.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table name (`table_name`, text, required): What to call the new table, for example 'Customer notes'.
- Column names (`column_names`, list, required): One name per column, in the order they should appear.

**Outputs**

- `columns` (list): The columns it was created with.
- `id` (text): The table ID the other actions take.
- `name` (text): The name it was given.

**Example output**

```json
{
  "columns": [
    {
      "id": "Customer",
      "name": "Customer"
    },
    {
      "id": "Note",
      "name": "Note"
    }
  ],
  "id": "Customer_notes",
  "name": "Customer notes"
}
```

### Delete a record

Permanently remove one record from a table.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Record ID (`record_id`, number, required): The record's ID in Grist. 'Find records' returns it as 'id', and adding a record hands it back. At least 1.

**Outputs**

- `deleted` (true/false): Whether the record was removed.
- `id` (number): The ID of the record that was removed.

**Example output**

```json
{
  "deleted": true,
  "id": 3
}
```

### Export a table as CSV

Get a whole table as CSV text, formatted the way Grist shows it, ready to attach to an email or save as a file.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.

**Outputs**

- `columns` (list): The column names in the header row.
- `csv` (text): The table as CSV text, with the column names on the first line.
- `row_count` (number): How many records the file holds.
- `table_id` (text): The table that was exported.

**Example output**

```json
{
  "columns": [
    "Customer",
    "Status",
    "Amount"
  ],
  "csv": "Customer,Status,Amount\nAcme Inc.,Open,1250\n",
  "row_count": 1,
  "table_id": "Deals"
}
```

### Find records

Get records from a table. Match one column against one or more values, or leave the column blank to get everything.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Match column (`column`, text): The column to match on. Leave blank to return every record.
- Match values (`values`, list): A record is returned when the column holds any one of these. Dates go in as 2026-03-01.
- Sort by (`sort_column`, text): The column to order the results by. Leave blank to keep Grist's order.
- Order (`sort_direction`, text): Which way to sort. One of: `ascending` (A → Z, smallest and oldest first), `descending` (Z → A, largest and newest first). Default: `ascending`.
- Maximum records (`limit`, number): The most records to return. Leave blank to return all of them. At least 1.

**Outputs**

- `count` (number): How many records came back.
- `records` (list): The matching records.

**Example output**

```json
{
  "count": 1,
  "records": [
    {
      "fields": {
        "Amount": 1250,
        "Customer": "Acme Inc.",
        "Due": "2026-03-01",
        "Status": "Open",
        "Tags": [
          "Priority",
          "Renewal"
        ]
      },
      "id": 3
    }
  ]
}
```

### Get a document

Get a document's name, where it lives, and a link that opens it.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.

**Outputs**

- `access` (text): Your access to it.
- `id` (text): The document ID.
- `name` (text): The document's name.
- `team` (text): The team site or personal area.
- `updated_at` (text): When the document last changed.
- `url` (text): A link that opens the document.
- `workspace` (text): The workspace holding it.

**Example output**

```json
{
  "access": "owners",
  "id": "9PJhBDZPyCNoayZxaCwFfS",
  "name": "Sales pipeline",
  "team": "Acme",
  "updated_at": "2026-02-14T09:12:44.000Z",
  "url": "https://acme.getgrist.com/9PJhBDZPyCNo",
  "workspace": "Revenue"
}
```

### Get a record

Get one record by its ID.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Record ID (`record_id`, number, required): The record's ID in Grist. 'Find records' returns it as 'id', and adding a record hands it back. At least 1.

**Outputs**

- `errors` (object): Only present when a formula column failed: the column and the error.
- `fields` (object): The record's column values, keyed by column ID.
- `id` (number): The record's ID, which the other record actions take.

**Example output**

```json
{
  "fields": {
    "Amount": 1250,
    "Customer": "Acme Inc.",
    "Due": "2026-03-01",
    "Status": "Open",
    "Tags": [
      "Priority",
      "Renewal"
    ]
  },
  "id": 3
}
```

### List columns

List a table's columns: what each is called, what it holds, and the choices a choice column allows.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.

**Outputs**

- `columns` (list): The table's columns, in the order Grist shows them.
- `count` (number): How many columns there are.

**Example output**

```json
{
  "columns": [
    {
      "id": "Customer",
      "is_formula": false,
      "name": "Customer",
      "type": "Text"
    },
    {
      "choices": [
        "Open",
        "Won",
        "Lost"
      ],
      "id": "Status",
      "is_formula": false,
      "name": "Status",
      "type": "Choice"
    },
    {
      "id": "Due",
      "is_formula": false,
      "name": "Due",
      "type": "Date"
    }
  ],
  "count": 3
}
```

### List documents

List every Grist document this connection can open, across your personal area and any team sites.

**Inputs**: None.

**Outputs**

- `count` (number): How many documents there are.
- `documents` (list): The documents, newest workspace first.

**Example output**

```json
{
  "count": 1,
  "documents": [
    {
      "access": "owners",
      "id": "9PJhBDZPyCNoayZxaCwFfS",
      "name": "Sales pipeline",
      "team": "Acme",
      "url": "https://acme.getgrist.com/9PJhBDZPyCNo",
      "workspace": "Revenue"
    }
  ]
}
```

### List tables

List the tables in a document, with the ID each one is known by. The summary tables Grist derives for charts and totals are left out.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.

**Outputs**

- `count` (number): How many tables there are.
- `tables` (list): The document's tables.

**Example output**

```json
{
  "count": 2,
  "tables": [
    {
      "id": "Deals",
      "name": "Deals"
    },
    {
      "id": "Customer_Notes",
      "name": "Customer Notes"
    }
  ]
}
```

### List workspaces

List the workspaces documents are kept in, across your personal area and any team sites. This is where 'Create a document' gets the workspace to put a new document in.

**Inputs**: None.

**Outputs**

- `count` (number): How many workspaces there are.
- `workspaces` (list): The workspaces, personal area first.

**Example output**

```json
{
  "count": 1,
  "workspaces": [
    {
      "access": "owners",
      "document_count": 4,
      "id": 7,
      "name": "Home",
      "team": "Personal"
    }
  ]
}
```

### Run a SQL query

Run a read-only SELECT across a document's tables: totals, date ranges, and joins that the record actions cannot express. Nothing in the document can be changed by it.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Query (`query`, text, required): A single SELECT statement, using table and column IDs, for example: select Customer, Amount from Deals where Status = ?
- Values for ? (`values`, list): One value for each ? in the query, in order. Use these rather than pasting values into the query itself.

**Outputs**

- `count` (number): How many rows came back.
- `query` (text): The statement that was run.
- `rows` (list): The rows the query selected. Values come straight from storage, so a toggle reads 0 or 1 and a date reads as seconds since 1970.

**Example output**

```json
{
  "count": 1,
  "query": "select Status, sum(Amount) as total from Deals group by Status",
  "rows": [
    {
      "Status": "Open",
      "total": 4300
    }
  ]
}
```

### Update a record

Change some columns of one record. Columns left blank keep the values they already have.

**Inputs**

- Document (`doc_id`, text, required): The Grist document to work in.
- Table (`table_id`, text, required): The table to work in.
- Record ID (`record_id`, number, required): The record's ID in Grist. 'Find records' returns it as 'id', and adding a record hands it back. At least 1.
- Column values (`fields`, object, required): The columns to change and their new values. Leave a column blank to keep the value it already has. Dates go in as 2026-03-01 (and times as 2026-03-01T09:30:00), and a choice-list or link-list column takes a list of values.

**Outputs**

- `errors` (object): Only present when a formula column failed: the column and the error.
- `fields` (object): The record's column values, keyed by column ID.
- `id` (number): The record's ID, which the other record actions take.

**Example output**

```json
{
  "fields": {
    "Amount": 1250,
    "Customer": "Acme Inc.",
    "Due": "2026-03-01",
    "Status": "Open",
    "Tags": [
      "Priority",
      "Renewal"
    ]
  },
  "id": 3
}
```
