Portal Community

When to Use

Configuration

FieldRequiredDescription
CredentialIdRequiredInteger ID referencing a stored Google credential in the BizFirst Credentials Manager. The created spreadsheet will be owned by this Google account (service account or OAuth user).
TitleRequiredThe name of the new spreadsheet as it will appear in Google Drive and the Sheets UI. Supports dynamic expressions: {{ $json.clientName }} — Report {{ $now | date('YYYY') }}. Maximum 255 characters.
SheetsOptionalList of SpreadsheetSheetDefinition objects to provision as initial tabs. Each definition has: Title (string, tab name) and Hidden (boolean, default false). When omitted, the spreadsheet is created with a single default tab named "Sheet1". Providing this list is more efficient than creating tabs individually with sheet/create after the fact.
LocaleOptionalBCP 47 locale string, e.g. "en_US", "de_DE", "fr_FR". Controls the spreadsheet's number formatting, date formatting, and currency symbol defaults. When omitted, the Google account's default locale is used.
RecalculationIntervalOptionalString. Controls how often volatile functions (e.g. NOW(), RAND()) recalculate. Options: "ON_CHANGE" (default — recalculates when the spreadsheet changes), "MINUTE" (recalculates every minute), "HOUR" (recalculates every hour). Use "HOUR" or "ON_CHANGE" for performance — "MINUTE" generates frequent recalculation load.
Service account file visibility: When a spreadsheet is created by a service account, it is placed in the service account's Google Drive — not in any human user's Drive. To make it accessible to human users, you must share the spreadsheet after creation. Use an HttpRequest node to call the Google Drive API's /permissions endpoint to add the target user's email as an editor or viewer. Alternatively, create the spreadsheet in a Shared Drive where the service account has access.

Validation Errors

Error CodeCause
VAL_MISSING_TITLETitle is empty or whitespace.
VAL_TITLE_TOO_LONGTitle exceeds 255 characters.
VAL_INVALID_LOCALELocale is not a recognized BCP 47 locale string.
VAL_DUPLICATE_SHEET_TITLEThe Sheets list contains two entries with the same Title — tab names must be unique within a spreadsheet.
VAL_INVALID_CREDENTIALCredentialId does not resolve to a valid Google credential.
QUOTA_EXCEEDEDThe Google Drive storage quota for the account is exceeded. A new spreadsheet file cannot be created.

Output Fields

FieldTypeDescription
spreadsheetIdstringThe unique ID of the newly created spreadsheet. Use this in all subsequent sheet operations targeting this file.
spreadsheetUrlstringThe full Google Sheets URL for the new spreadsheet, e.g. https://docs.google.com/spreadsheets/d/{id}/edit. Suitable for sharing in emails or Slack notifications.
titlestringThe title of the created spreadsheet — echoed from the request.
sheetsCreatedintegerNumber of sheet tabs created. Equal to the length of the Sheets list, or 1 if no Sheets were specified (the default "Sheet1" tab).
statusstring"success".
resourcestringAlways "spreadsheet".
operationstringAlways "create".

Sample Configuration

{
  "resource": "spreadsheet",
  "operation": "create",
  "CredentialId": 12,
  "Title": "{{ $json.clientName }} — Analytics {{ $now | date('YYYY') }}",
  "Sheets": [
    { "Title": "Dashboard",   "Hidden": false },
    { "Title": "Monthly KPIs","Hidden": false },
    { "Title": "Raw Data",    "Hidden": false },
    { "Title": "Config",      "Hidden": true  }
  ],
  "Locale": "en_US",
  "RecalculationInterval": "ON_CHANGE"
}

Sample Output

{
  "spreadsheetId": "1Xt4QzpNnFMdKvBdBZjgmRk9VE2upms7qptlbs74OgVE",
  "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/1Xt4QzpNnFMdKvBdBZjgmRk9VE2upms7qptlbs74OgVE/edit",
  "title": "Acme Corp — Analytics 2026",
  "sheetsCreated": 4,
  "status": "success",
  "resource": "spreadsheet",
  "operation": "create"
}

Expression Reference

Assuming this node is named createClientWorkbook in the workflow:

ExpressionReturnsDescription
{{ $output.createClientWorkbook.spreadsheetId }}stringNew spreadsheet ID — pass to all subsequent sheet operations.
{{ $output.createClientWorkbook.spreadsheetUrl }}stringFull URL — embed in email notifications or Slack messages.
{{ $output.createClientWorkbook.title }}stringSpreadsheet title — confirm the created name in audit log.
{{ $output.createClientWorkbook.sheetsCreated }}integerNumber of tabs created in the new spreadsheet.
{{ $output.createClientWorkbook.status }}string"success" on success port.

Node Policies & GuardRails

Workflow Examples

Example 1 — New Client Onboarding — Full Workbook Provisioning

// Trigger: Webhook — new client signed contract in CRM
// Node 1 — spreadsheet/create (createWorkbook)
{
  "resource": "spreadsheet", "operation": "create",
  "CredentialId": 12,
  "Title": "{{ $json.clientName }} — BizFirst Analytics {{ $now | date('YYYY') }}",
  "Sheets": [
    { "Title": "Dashboard" },
    { "Title": "Monthly KPIs" },
    { "Title": "Weekly Data" },
    { "Title": "Config", "Hidden": true }
  ],
  "Locale": "{{ $json.locale }}"
}

// Node 2 — HttpRequest: share with client's admin email
// POST https://www.googleapis.com/drive/v3/files/{{ $output.createWorkbook.spreadsheetId }}/permissions
// Body: { "role": "writer", "type": "user", "emailAddress": "{{ $json.clientAdminEmail }}" }

// Node 3 — HttpRequest (CRM): update client record with spreadsheetId and spreadsheetUrl
// Node 4 — Email to client: "Your analytics workbook is ready: {{ $output.createWorkbook.spreadsheetUrl }}"

Example 2 — Annual Fiscal Year Report Setup

// Trigger: Scheduled — January 1st at 1 AM
{
  "resource": "spreadsheet", "operation": "create",
  "CredentialId": 14,
  "Title": "BizFirst Annual Report {{ $now | date('YYYY') }}",
  "Sheets": [
    { "Title": "Jan {{ $now | date('YYYY') }}" },
    { "Title": "Feb {{ $now | date('YYYY') }}" },
    { "Title": "Mar {{ $now | date('YYYY') }}" },
    { "Title": "Apr {{ $now | date('YYYY') }}" },
    { "Title": "May {{ $now | date('YYYY') }}" },
    { "Title": "Jun {{ $now | date('YYYY') }}" },
    { "Title": "Jul {{ $now | date('YYYY') }}" },
    { "Title": "Aug {{ $now | date('YYYY') }}" },
    { "Title": "Sep {{ $now | date('YYYY') }}" },
    { "Title": "Oct {{ $now | date('YYYY') }}" },
    { "Title": "Nov {{ $now | date('YYYY') }}" },
    { "Title": "Dec {{ $now | date('YYYY') }}" },
    { "Title": "Full Year Summary" }
  ],
  "Locale": "en_US"
}
// Store spreadsheetId in database for use by all monthly reporting workflows