n8n Google Sheets: Complete Automation Guide 2026

Google Sheets is one of the most versatile data stores in the world — free, collaborative, and accessible from anywhere. When combined with n8n, it becomes a powerful backend for lightweight CRMs, event logs, reporting dashboards, and data pipelines.

In this guide we cover credentials setup (both OAuth2 and Service Account), all node operations, triggers, and four complete real-world workflows you can import and adapt today.

⚡ Generate this workflow instantly

Visit Scriflow, describe your Google Sheets automation in plain English, and get a ready-to-import n8n JSON file — no manual configuration needed.

Setting Up Google Sheets Credentials

You have two ways to authenticate with Google Sheets from n8n:

MethodBest ForSetup Complexity
OAuth2 (Google account)Accessing spreadsheets in your personal or GSuite accountMedium — requires Google Cloud project + OAuth consent screen
Service AccountServer-to-server automation, no user interaction neededMedium — requires sharing spreadsheet with service account email

Option A: OAuth2 Setup

  1. Go to console.cloud.google.com → Create a new project (or select existing).
  2. Enable the Google Sheets API and Google Drive API.
  3. Go to APIs & Services → Credentials → Create OAuth 2.0 Client ID.
  4. Set Application Type to Web Application. Add n8n's callback URL as an authorized redirect URI.
  5. Download the Client ID and Client Secret.
  6. In n8n: Credentials → New → Google Sheets OAuth2 API → enter Client ID and Secret → Connect.

Option B: Service Account Setup

  1. In Google Cloud Console → Credentials → Create Service Account.
  2. Download the JSON key file for the service account.
  3. In n8n: Credentials → New → Google Service Account → paste the JSON key content.
  4. Important: Share your Google Spreadsheet with the service account email (name@project.iam.gserviceaccount.com) with Editor access.
💡 Which to choose?

Use Service Account for automated server workflows (no token expiry, no UI interaction required). Use OAuth2 when you need to act as a specific user or access private spreadsheets you own.

Node Operations Overview

The n8n Google Sheets node covers all CRUD operations plus spreadsheet-level management:

Get Rows
Read operation
Read all rows or filter by column value. Returns each row as an n8n item.
Append Row
Write operation
Add new rows at the bottom of the sheet. Maps JSON fields to column headers automatically.
Update Row
Write operation
Modify existing rows. Identify the row by a key column (e.g. ID or email).
Delete Row
Write operation
Remove rows by row number or by matching a column value.
Clear
Write operation
Erase all values in a range while keeping formatting intact.
Create Spreadsheet
Management
Programmatically create a new spreadsheet and get its ID for downstream nodes.

Reading Rows from a Sheet

To read data, you need the Spreadsheet ID (found in the URL: docs.google.com/spreadsheets/d/[ID]/edit) and the sheet name:

Resource: Sheet Operation: Get Rows Spreadsheet ID: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms Sheet Name: Leads Filters: Column: Status Value: New // optional — filter rows by column value

Each row becomes a separate n8n item. Column headers in row 1 become the JSON field names in the output:

// Sheet columns: Name | Email | Status | Created // Output item: { "Name": "Alice Johnson", "Email": "alice@example.com", "Status": "New", "Created": "2026-03-10", "row_number": 2 // always included for update/delete operations }

Appending Rows

The Append Row operation is the workhorse of Google Sheets automation. It maps incoming JSON fields to column headers automatically:

Resource: Sheet Operation: Append Row Spreadsheet ID: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms Sheet Name: Form Submissions Columns: Name: {{ $json.name }} Email: {{ $json.email }} Message: {{ $json.message }} Submitted At: {{ $now.toISO() }} Source: {{ $json.utm_source ?? 'direct' }}
💡 Column mapping tip

The column names in the node must exactly match the header row in your spreadsheet (case-sensitive). If the sheet has a "First Name" column, use First Name — not firstName or first_name.

Updating Rows

To update a row, you must identify it. The most reliable way is using the row_number returned by a prior Get Rows operation:

Resource: Sheet Operation: Update Row Spreadsheet ID: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms Sheet Name: Leads Row Number: {{ $('Get Lead Row').item.json.row_number }} Columns: Status: Contacted Last Updated: {{ $now.toISO() }} Notes: {{ $json.callNotes }}

Google Sheets Triggers

The Google Sheets Trigger node polls your spreadsheet for changes and fires your workflow when data is added or updated. This enables reactive automation without a third-party webhook service.

Trigger Event: Row Added // or "Row Updated" Spreadsheet ID: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms Sheet Name: Orders Poll Time: Every minute // minimum polling interval
📌 Polling note

Google Sheets doesn't natively support webhooks. The trigger node polls the sheet every minute (or your configured interval). For near-real-time reactions, combine a Google Forms submission webhook with the Sheets node for writes.

Real Workflow Examples

Workflow 1: Form Submissions → Google Sheets CRM

Automatically capture website form submissions into a Google Sheets CRM:

  1. Webhook Trigger — receives form submission from your site.
  2. Set Node — normalizes and enriches the data (adds timestamp, default status).
  3. Google Sheets → Append Row — adds the lead to the "Leads" sheet.
  4. Gmail/SendGrid — sends a welcome email to the new lead.
  5. Slack — notifies the sales team in #new-leads.

Workflow 2: Spreadsheet to Email Reports

Every Monday morning, pull last week's sales data and email a formatted report:

  1. Schedule Trigger — Monday at 8 AM.
  2. Google Sheets → Get Rows — reads all rows from "Sales" sheet where Date is last 7 days.
  3. Code Node — aggregates totals (sum revenue, count deals, calculate conversion rate).
  4. Gmail → Send Email — sends an HTML-formatted report to the team.
// Code node: aggregate sales data const items = $input.all(); const total = items.reduce((sum, item) => sum + item.json.Revenue, 0); const deals = items.length; const avgDeal = total / deals; return [{ json: { total_revenue: total.toFixed(2), deal_count: deals, avg_deal_size: avgDeal.toFixed(2), week_start: items[0].json.Date, week_end: items[items.length - 1].json.Date } }];

Workflow 3: Sync Database → Google Sheets

Keep a Google Sheet in sync with a PostgreSQL or MySQL database for stakeholder visibility:

  1. Schedule Trigger — runs every hour.
  2. Postgres Node — queries the latest records.
  3. Google Sheets → Clear — clears the data range (not headers) to avoid duplicates.
  4. Google Sheets → Append Row — writes all fresh data rows in bulk.

Workflow 4: Typeform → Sheets → Slack Notification

  1. Typeform Trigger — fires on every survey response.
  2. Google Sheets → Append Row — logs the response with timestamp and score.
  3. IF Node — checks if NPS score is ≤ 6 (detractor).
  4. Slack (true branch) — alerts the customer success team to follow up.

Tips for Large Datasets

  • Use filters on read: Always filter on the Sheets node level rather than reading all rows and filtering in n8n. This reduces API quota usage.
  • Batch appends: The Append Row operation can process multiple items in a single API call. n8n handles this automatically when upstream nodes produce multiple items.
  • Archive old data: Google Sheets performs poorly beyond ~50k rows. Use a Delete Row operation or move old rows to an archive sheet periodically.
  • Use named ranges: Define named ranges in Google Sheets (e.g. "SalesData") and reference them by name instead of hardcoded cell ranges like A:Z.
  • Monitor API quota: Google Sheets API has a limit of 300 write requests per minute. Add Wait nodes if you're writing many rows in rapid succession.

Frequently Asked Questions

Can n8n create a new sheet (tab) within an existing spreadsheet?
Not directly with the Google Sheets node. Use the HTTP Request node to call the Google Sheets API's batchUpdate endpoint with an addSheet request. This gives you full control over tab creation, naming, and positioning.
How do I look up a row by email and update it?
Use Get Rows with a filter on the Email column to find the matching row. The result includes row_number. Pass this to the Update Row operation's Row Number field to modify only that specific row.
What happens if I append to a sheet and the headers don't match?
Non-matching fields are silently ignored. If you provide a field name that doesn't exist as a column header, n8n skips it. The sheet's header row is always used as the source of truth for column mapping.
Can I generate a Google Sheets n8n workflow automatically?
Yes. Go to Scriflow, describe what you want (e.g. "When a new row is added to my Google Sheet, send a Slack notification and add the contact to HubSpot"), and get a complete n8n JSON in seconds.