# Google Sheets

Google Sheets holds the working data behind many reports. One API for Agents calls the Sheets API with read and write access to spreadsheets, so agents can read tabs as rows, append results and create new sheets. Agents open a spreadsheet by its ID or URL; there is no access to the rest of Google Drive.

- Provider id: `gsheets`
- Auth: Sign in with Google (OAuth), Service account
- Google scopes: `https://www.googleapis.com/auth/spreadsheets`
- Raw endpoints: 9. Smart tools: 5.
- Machine-readable schemas: `GET https://api.oneapiforagents.com/v1/providers/gsheets`

## Smart tools

Curated calls with compact output for agents. Over MCP each one is a tool with the same name.

### sheets_read

Read a tab or range as rows of objects keyed by the header row. Capped by `limit`; page with `offset`.

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `spreadsheet` | string | yes | Spreadsheet ID, or its full docs.google.com/spreadsheets/d/<id>/... URL |
| `sheet` | string | no | Tab name. Defaults to the tab in the URL (gid), else the first tab. |
| `range` | string | no | A1 range to read, e.g. "A1:F" or "Leads!A1:F200". Its first row is the header. |
| `header` | boolean | no | Use the first row as keys. Off: keys are column letters. Default `true`. |
| `offset` | integer | no | Data rows to skip, for paging Default `0`. (≥ 0) |
| `limit` | integer | no | Maximum rows to return Default `100`. (1–1000) |
| `formatted` | boolean | no | Return values as displayed ("$1,200.00"). Off: numbers as numbers, dates as text. Default `false`. |

```sh
curl https://api.oneapiforagents.com/v1/call \
  -H "Authorization: Bearer $ONEAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "gsheets",
    "tool": "sheets_read",
    "input": {
      "spreadsheet": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit"
    }
  }'
```

### sheets_list_tabs

The spreadsheet's title, URL and tabs, with each tab's grid size (rows × columns, including empty cells).

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `spreadsheet` | string | yes | Spreadsheet ID, or its full docs.google.com/spreadsheets/d/<id>/... URL |

```sh
curl https://api.oneapiforagents.com/v1/call \
  -H "Authorization: Bearer $ONEAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "gsheets",
    "tool": "sheets_list_tabs",
    "input": {
      "spreadsheet": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit"
    }
  }'
```

### sheets_append_rows

Append rows below a tab's existing data. Pass objects keyed by header name, or arrays in column order.

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `spreadsheet` | string | yes | Spreadsheet ID, or its full docs.google.com/spreadsheets/d/<id>/... URL |
| `sheet` | string | no | Tab name. Defaults to the tab in the URL (gid), else the first tab. |
| `rows` | array<object (free-form) \| array<string \| number \| boolean \| null>> | yes | Objects are matched to the header row by name (an empty tab gets a header from their keys). Arrays are written as-is. |
| `valueInput` | string | no | RAW stores values as given. USER_ENTERED parses them as if typed into Sheets (dates, formulas, 1,000). One of: `RAW`, `USER_ENTERED`. Default `"RAW"`. |

```sh
curl https://api.oneapiforagents.com/v1/call \
  -H "Authorization: Bearer $ONEAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "gsheets",
    "tool": "sheets_append_rows",
    "input": {
      "spreadsheet": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit",
      "rows": [
        {}
      ]
    }
  }'
```

### sheets_update_range

Overwrite cells starting at a range with rows of values.

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `spreadsheet` | string | yes | Spreadsheet ID, or its full docs.google.com/spreadsheets/d/<id>/... URL |
| `range` | string | yes | Top-left cell or full A1 range to overwrite, e.g. "B2" or "Leads!B2:D10" |
| `sheet` | string | no | Tab name. Defaults to the tab in the URL (gid), else the first tab. |
| `values` | array<array<string \| number \| boolean \| null>> | yes | Rows of cells; null leaves a cell unchanged |
| `valueInput` | string | no | RAW stores values as given. USER_ENTERED parses them as if typed into Sheets (dates, formulas, 1,000). One of: `RAW`, `USER_ENTERED`. Default `"RAW"`. |

```sh
curl https://api.oneapiforagents.com/v1/call \
  -H "Authorization: Bearer $ONEAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "gsheets",
    "tool": "sheets_update_range",
    "input": {
      "spreadsheet": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit",
      "range": "example",
      "values": [
        [
          null
        ]
      ]
    }
  }'
```

### sheets_create

Create a spreadsheet in the connected Google account's Drive, optionally with a frozen header row. Returns its ID and URL. Needs a Google sign-in connection (service accounts can't own files).

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `title` | string | yes |  |
| `sheet` | string | no | Name of the first tab Default `"Sheet1"`. |
| `headers` | array<string> | no | Header row to write (and freeze) on the first tab |

```sh
curl https://api.oneapiforagents.com/v1/call \
  -H "Authorization: Bearer $ONEAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "gsheets",
    "tool": "sheets_create",
    "input": {
      "title": "example"
    }
  }'
```

## Raw endpoints

Passthrough to the provider API. `path` fills URL placeholders, `query` the query string and `body` the JSON body. The response is the provider's own body.

### spreadsheets.get

Spreadsheet metadata: title, tabs and their grid sizes. Use `fields` (a field mask) to keep responses small; includeGridData returns cell data and is ignored when `fields` is set.

`GET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}`

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `query.ranges` | array<string> | no |  |
| `query.includeGridData` | boolean | no |  |
| `query.excludeTablesInBandedRanges` | boolean | no |  |
| `query.fields` | string | no |  |

```json
{
  "provider": "gsheets",
  "endpoint": "spreadsheets.get",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
    }
  }
}
```

### values.get

Read one range. Trailing empty rows and columns are omitted.

`GET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}`

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `path.range` | string | yes | A1 notation, e.g. "Sheet1!A1:D50" or "'Q3 data'!A:F" |
| `query.majorDimension` | string | no | One of: `ROWS`, `COLUMNS`. |
| `query.valueRenderOption` | string | no | One of: `FORMATTED_VALUE`, `UNFORMATTED_VALUE`, `FORMULA`. |
| `query.dateTimeRenderOption` | string | no | One of: `SERIAL_NUMBER`, `FORMATTED_STRING`. |

```json
{
  "provider": "gsheets",
  "endpoint": "values.get",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
      "range": "example"
    }
  }
}
```

### values.batchGet

Read several ranges in one request.

`GET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values:batchGet`

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `query.majorDimension` | string | no | One of: `ROWS`, `COLUMNS`. |
| `query.valueRenderOption` | string | no | One of: `FORMATTED_VALUE`, `UNFORMATTED_VALUE`, `FORMULA`. |
| `query.dateTimeRenderOption` | string | no | One of: `SERIAL_NUMBER`, `FORMATTED_STRING`. |
| `query.ranges` | array<string> | yes |  |

```json
{
  "provider": "gsheets",
  "endpoint": "values.batchGet",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
    },
    "query": {
      "ranges": [
        "example"
      ]
    }
  }
}
```

### values.update

Overwrite one range with a ValueRange. valueInputOption is required.

`PUT https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}` (writes; needs read-write access)

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `path.range` | string | yes | A1 notation, e.g. "Sheet1!A1:D50" or "'Q3 data'!A:F" |
| `query.valueInputOption` | string | yes | One of: `RAW`, `USER_ENTERED`. |
| `query.includeValuesInResponse` | boolean | no |  |
| `query.responseValueRenderOption` | string | no | One of: `FORMATTED_VALUE`, `UNFORMATTED_VALUE`, `FORMULA`. |
| `query.responseDateTimeRenderOption` | string | no | One of: `SERIAL_NUMBER`, `FORMATTED_STRING`. |
| `body.range` | string | no |  |
| `body.majorDimension` | string | no | One of: `ROWS`, `COLUMNS`. |
| `body.values` | array<array<string \| number \| boolean \| null>> | yes |  |

```json
{
  "provider": "gsheets",
  "endpoint": "values.update",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
      "range": "example"
    },
    "query": {
      "valueInputOption": "RAW"
    },
    "body": {
      "values": [
        [
          null
        ]
      ]
    }
  }
}
```

### values.append

Append rows after the table found in `range`. valueInputOption is required.

`POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:append` (writes; needs read-write access)

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `path.range` | string | yes | A1 notation, e.g. "Sheet1!A1:D50" or "'Q3 data'!A:F" |
| `query.valueInputOption` | string | yes | One of: `RAW`, `USER_ENTERED`. |
| `query.includeValuesInResponse` | boolean | no |  |
| `query.responseValueRenderOption` | string | no | One of: `FORMATTED_VALUE`, `UNFORMATTED_VALUE`, `FORMULA`. |
| `query.responseDateTimeRenderOption` | string | no | One of: `SERIAL_NUMBER`, `FORMATTED_STRING`. |
| `query.insertDataOption` | string | no | One of: `OVERWRITE`, `INSERT_ROWS`. |
| `body.range` | string | no |  |
| `body.majorDimension` | string | no | One of: `ROWS`, `COLUMNS`. |
| `body.values` | array<array<string \| number \| boolean \| null>> | yes |  |

```json
{
  "provider": "gsheets",
  "endpoint": "values.append",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
      "range": "example"
    },
    "query": {
      "valueInputOption": "RAW"
    },
    "body": {
      "values": [
        [
          null
        ]
      ]
    }
  }
}
```

### values.batchUpdate

Overwrite several ranges in one request.

`POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values:batchUpdate` (writes; needs read-write access)

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `body.valueInputOption` | string | yes | One of: `RAW`, `USER_ENTERED`. |
| `body.data` | array<object> | yes |  |
| `body.includeValuesInResponse` | boolean | no |  |
| `body.responseValueRenderOption` | string | no | One of: `FORMATTED_VALUE`, `UNFORMATTED_VALUE`, `FORMULA`. |
| `body.responseDateTimeRenderOption` | string | no | One of: `SERIAL_NUMBER`, `FORMATTED_STRING`. |

```json
{
  "provider": "gsheets",
  "endpoint": "values.batchUpdate",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
    },
    "body": {
      "valueInputOption": "RAW",
      "data": [
        {
          "range": "example",
          "values": [
            [
              null
            ]
          ]
        }
      ]
    }
  }
}
```

### values.clear

Clear the values in a range. Formatting and validation are kept.

`POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:clear` (writes; needs read-write access)

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `path.range` | string | yes | A1 notation, e.g. "Sheet1!A1:D50" or "'Q3 data'!A:F" |

```json
{
  "provider": "gsheets",
  "endpoint": "values.clear",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
      "range": "example"
    }
  }
}
```

### spreadsheets.create

Create a spreadsheet from a Spreadsheet resource. Needs a Google sign-in connection: service accounts have no Drive storage to own files.

`POST https://sheets.googleapis.com/v4/spreadsheets` (writes; needs read-write access)

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `body` | object (free-form) | yes | Request body, passed through to the provider API as-is |

```json
{
  "provider": "gsheets",
  "endpoint": "spreadsheets.create",
  "input": {
    "body": {}
  }
}
```

### spreadsheets.batchUpdate

Structural changes (add, rename or delete tabs, formatting, sorting, …) as a list of requests, applied atomically.

`POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate` (writes; needs read-write access)

| Name | Type | Required | Notes |
| --- | --- | --- | --- |
| `path.spreadsheetId` | string | yes |  |
| `body.requests` | array<object (free-form)> | yes |  |
| `body.includeSpreadsheetInResponse` | boolean | no |  |
| `body.responseRanges` | array<string> | no |  |
| `body.responseIncludeGridData` | boolean | no |  |

```json
{
  "provider": "gsheets",
  "endpoint": "spreadsheets.batchUpdate",
  "input": {
    "path": {
      "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
    },
    "body": {
      "requests": [
        {}
      ]
    }
  }
}
```
