---
title: "YouTube to Sheets Scraper — n8n YouTube Data API scraper | Harshith Nayaka L"
description: "n8n workflow pulling YouTube videos, playlists and channels into Google Sheets through the official Data API: one row per video, no duplicates on re-runs."
canonical: "https://harshith-nayaka-l-portfolio.vercel.app/work/youtube-scraper-google-sheets"
last-updated: "2026-10-04T17:07:29Z"
published: "2026-10-04T16:45:37Z"
author: "Harshith Nayaka L"
author-role: "AI Engineer - Full Stack"
author-title: "AI Engineer - Full Stack"
author-location: "Bengaluru, India"
author-availability: "Available for freelance work"
author-email: "harshith28124@gmail.com"
content-type: "text/markdown"
html-version: "https://harshith-nayaka-l-portfolio.vercel.app/work/youtube-scraper-google-sheets"
---
# YouTube to Sheets Scraper — 24-node n8n workflow

> Turns search terms, videos, playlists and channels listed in a Google Sheet into one clean, de-duplicated row per video, using the official YouTube Data API instead of scraping pages that break.

Case study by Harshith Nayaka L, AI Engineer - Full Stack, Bengaluru, India.
Canonical page: https://harshith-nayaka-l-portfolio.vercel.app/work/youtube-scraper-google-sheets

- **Type:** n8n workflow automation
- **Flow:** YouTube Data API v3 → Google Sheets
- **Role:** Solo build
- **Status:** Live run on n8n 2.8.4

## The problem

Tracking YouTube videos in a spreadsheet usually means one of two bad options: copying details by hand, or an HTML scraper that breaks whenever YouTube changes its page and sits outside its terms of service.

A sheet that is written to on a schedule has failure modes of its own: duplicate rows on every run, one broken input stopping all the others, and video titles a spreadsheet will happily treat as formulas.

## What I built

A 24-node n8n workflow on the official YouTube Data API v3. What to scrape is managed from an Inputs tab: column A takes search words, a video URL (watch, youtu.be, Shorts or live), a playlist URL or a channel (@handle, /channel/ or /user/ URL); column B sets the most videos for that row, from 1 to 50; column C pauses a row. Every run writes back the last run time, a status with its reason, and the number of videos found.

Each input is classified, channel handles are resolved to the channel's uploads playlist, searches and playlists are listed, and video details are fetched 50 IDs per call. Results land in a Videos tab, one row per video: title, channel, description, publish date, view, like and comment counts, duration, tags, thumbnail, IDs and URL, plus the input it came from and first-seen and last-updated dates.

Re-runs update existing rows in place, keyed by video ID, so nothing is duplicated even when inputs overlap, and the original first-seen date is kept. The first run creates both tabs with headers and two example inputs, then scrapes them.

## Pipeline

- **Trigger:** Daily 6:00 AM (Or Run Scraper, by hand)
- **Prepare:** Open the sheet (Create tabs if missing)
- **Plan:** Classify inputs (Search, video, playlist, channel)
- **Fetch:** Resolve channels (@handle → uploads playlist) → Video details (50 IDs per API call)
- **Write:** Batch write (Update in place, append new) → Per-row status (✅ / ⚠️ / ❌ with the reason)

## The judgment calls

**One bad input never stops the others**

A private playlist, a deleted video, an unknown handle or a legacy /c/ URL gets a ❌ and the reason in its own row of the Inputs tab, and every other row is still scraped. Exhausted quota, an invalid key, a disabled API or a sheet that isn't shared each produce a message that names the fix.

**Writes can't smuggle in a formula**

Values are written with the RAW input option, so a video titled =HYPERLINK(…) stays text instead of becoming a live formula. Control characters are stripped and cell lengths are capped before anything reaches the sheet.

**It won't overwrite a tab it didn't create**

If the Videos tab already holds data this workflow didn't write, the run stops and asks for an empty tab or a different tab name rather than writing over someone else's work.

**Quota is guarded, not hoped for**

The free tier allows 10,000 units a day, a search costs 100 and most lookups cost 1. Video details are fetched 50 at a time, and a per-run cap on searches (20 by default) makes it impossible to spend the whole day's quota in one run.

## What it changed

**Live run:** On n8n 2.8.4 with real accounts: 10 videos written to the sheet, and both inputs marked ✅.

**Tested:** Validated inside a real n8n instance against strict mocks of the YouTube and Sheets APIs: a first run on an empty sheet, eleven mixed input types, in-place updates, max-results clamping, formula injection, deleted videos, exhausted quota, a tab the workflow didn't create, empty inputs and a wrong sheet ID.

## Questions this answers

**How do you scrape YouTube video data into Google Sheets reliably?**

Use the official YouTube Data API v3 rather than scraping the page, which breaks when YouTube changes its layout. Harshith Nayaka L's n8n workflow reads search terms, video, playlist and channel URLs from an Inputs tab, fetches video details 50 at a time, and writes one row per video to Google Sheets, updating existing rows in place so re-runs never duplicate. Values are written as raw text so a title can't inject a formula, and each input row gets its own status and reason.

## Built with

n8n, YouTube Data API v3, Google Sheets API, JavaScript (Code nodes)

## Links

- [View on GitHub](https://github.com/HarshithNayakaL/youtube-scraper-google-sheets-n8n)
