Google Sheets

The Google Sheets node reads, writes, and manages data in Google Sheets spreadsheets via OAuth2.

The Google Sheets node reads, writes, and manages data in Google Sheets spreadsheets via OAuth2. Use it to automate spreadsheet workflows — reading reports, logging results, updating trackers, and more.

Overview

PropertyValue
Inputs1
Outputs1
CredentialGoogle Sheets (OAuth2)
Output$nodeLabel.values, $nodeLabel.updatedRange, $nodeLabel.sheets, $nodeLabel.success

Parameters

ParameterTypeDescription
credentialIdUUIDGoogle Sheets credential from Credentials
gsOperationstringOperation: readRange, appendRows, updateRange, clearRange, getSheetInfo
gsSpreadsheetIdexpressionSpreadsheet ID or full Google Sheets URL
gsSheetNameexpressionSheet tab name (e.g. Sheet1). Not required for getSheetInfo.
gsStartRowexpressionFor readRange: 1-based first data row (with gsHasHeader, row 1 is the header).
gsMaxRowsexpressionFor readRange: max rows of data (0 = all).
gsHasHeaderbooleanFor readRange: treat row 1 as column names when true.
gsUpdateRowexpressionFor updateRange only: 1-based sheet row number to update (columns A–Z); if unset, gsStartRow is used. Not batchUpdate — one values API PUT.
gsRangeexpressionA1 notation range (e.g. A1:D100). Legacy examples; the editor uses row fields for read/update.
gsKeepHeaderbooleanFor clearRange only: when true, row 1 is kept and data rows below are cleared (columns A–Z).
gsAppendPlacementappend | prependFor appendRows only: Bottom adds after the last row with data; Top inserts new rows directly under row 1 (shifts data down).
gsValuesInputModeraw | selectiveFor appendRows / updateRange: Raw = full JSON array; Selective = one sheet row, column fields only (no A1 labels).
gsValuesSelectiveColsstringSelective mode: number of columns (A–Z).
gsValuesexpressionJSON 2D array of values (e.g. [["Name","Age"],["Alice",30]]). Required for appendRows, updateRange.

Spreadsheet ID

The gsSpreadsheetId field accepts either the bare ID (the long alphanumeric string between /d/ and /edit in a Google Sheets URL) or the full URL — Heym extracts the ID automatically.

Credential Setup

Google Sheets uses an OAuth2 "Bring Your Own App" model. You provide your own Google Cloud OAuth2 credentials.

Backend configuration: Set FRONTEND_URL on the Heym backend to the public URL of the app (the address users type in the browser), e.g. https://your-heym-domain. The OAuth redirect URI is always {FRONTEND_URL}/api/credentials/google-sheets/oauth/callback — it is derived only from this setting, not from request headers.

  1. Go to Google Cloud ConsoleAPIs & ServicesEnable APIs → enable Google Sheets API.
  2. Go to CredentialsCreate CredentialsOAuth client ID → select Web application.
  3. Under Authorized redirect URIs, add exactly: {your FRONTEND_URL}/api/credentials/google-sheets/oauth/callback (for example https://your-heym-domain/api/credentials/google-sheets/oauth/callback).
  4. Copy the Client ID and Client Secret.
  5. In Heym Dashboard → CredentialsNew → select Google Sheets (OAuth2).
  6. Enter the Client ID, Client Secret, and a name, then click Connect to complete the OAuth2 consent in a browser popup.

Tokens refresh automatically in the background — no manual token management required.

Operations

OperationRequired FieldsDescription
readRangegsSpreadsheetId, gsSheetName, gsStartRow, gsMaxRows, gsHasHeaderRead cell values (A–Z); optional gsRange in legacy flows
appendRowsgsSpreadsheetId, gsSheetName, gsValuesAdd rows at the bottom (gsAppendPlacement append) or under row 1 (prepend)
updateRangegsSpreadsheetId, gsSheetName, gsUpdateRow, gsValuesOverwrite row(s) starting at gsUpdateRow (A–Z); multi-row JSON writes consecutive rows
clearRangegsSpreadsheetId, gsSheetNameClear all values in columns A–Z for the tab; optional gsKeepHeader keeps the first row
getSheetInfogsSpreadsheetIdGet spreadsheet title and list of sheet tabs

Output Reference

OperationOutput fieldTypeDescription
readRange.rowsarrayRow objects: column keys (header names or A, B, …) plus rowIndex (1-based sheet row)
readRange.totalnumberNumber of data rows returned
appendRows.updatedRangestringRange written
appendRows.updatesnumberNumber of rows appended
updateRange.updatedRangestringRange written
updateRange.updatedCellsnumberNumber of cells updated
clearRange.clearedRangestringRange that was cleared
getSheetInfo.titlestringSpreadsheet title
getSheetInfo.sheetsarrayList of {sheetId, title} objects

All operations include success: true and operation: "<name>" in the output.

Example – Read a Range

{
  "type": "googleSheets",
  "data": {
    "label": "readReport",
    "credentialId": "google-sheets-credential-uuid",
    "gsOperation": "readRange",
    "gsSpreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
    "gsSheetName": "Sheet1",
    "gsRange": "A1:D100"
  }
}

Access output: $readReport.rows[0] (first data row object), $readReport.rows[0].Name (column by header), $readReport.rows[0].rowIndex (1-based sheet row).

Example – Append a Row from Input

{
  "type": "googleSheets",
  "data": {
    "label": "logEntry",
    "credentialId": "google-sheets-credential-uuid",
    "gsOperation": "appendRows",
    "gsSpreadsheetId": "$input.spreadsheetUrl",
    "gsSheetName": "Log",
    "gsValues": "[[\"$input.name\", \"$input.email\", \"$input.timestamp\"]]"
  }
}