Blog / Tutorials / Send YouTube Transcripts to Google Sheets Automatically
Tutorials 8 min read â€ĸ November 13, 2026

Send YouTube Transcripts to Google Sheets Automatically

Founder

Getting a new row in Google Sheets every time Scriptube finishes a transcript takes one webhook and one of two receivers: a Make scenario, or a small Google Apps Script web app. Both listen for the same event and payload; pick whichever fits your stack.

What you're wiring together

Scriptube fires batch.completed (and transcript.ready per item) to a URL you register. That URL needs to end up writing a row to a sheet. There's no native Scriptube-to-Sheets connector — see zapier-make-youtube-transcripts-webhooks for why — so both options below go through the raw webhook.

Option A: Make scenario

  1. Add a Webhooks > Custom webhook module, create a new hook, copy its URL.
  2. Register it with Scriptube:
curl -X POST https://scriptube.me/api/webhooks/register \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hook.make.com/XXXXXXXXXXXXX",
    "events": ["batch.completed"],
    "secret": "a-dedicated-random-string-16-to-256-chars"
  }'
  1. Add a function/code step that computes the HMAC-SHA256 signature over {timestamp}.{raw body} with your secret and compares it to the X-Scriptube-Signature header — the same check covered in zapier-make-youtube-transcripts-webhooks. Route on a match with a Filter immediately after.
  2. Add a Google Sheets > Add a Row module. Map columns from the payload: data.batch_id, data.status, data.item_count, data.completed_count, data.failed_count, and the top-level timestamp.

That's the whole scenario — one trigger, one verification step, one Sheets write. Test it by submitting a batch with a matching external_id you can look for in the new row; if you set external_id at submit time, it's echoed back inside data on every webhook, which makes matching a sheet row to the request that created it trivial.

Option B: Apps Script web app (no third platform at all)

If you don't want to run this through Make, Google Apps Script can be the webhook receiver directly, bound to the sheet itself.

In the target Sheet, open Extensions > Apps Script and paste:

function doPost(e) {
  const secret = 'a-dedicated-random-string-16-to-256-chars';
  const timestamp = e.parameter.ts || e.parameters['X-Scriptube-Timestamp'];
  // Apps Script doesn't expose request headers on doPost(e) directly;
  // verify using the raw POST body and the header value your proxy/
  // relay forwards as a query param or a wrapped field, per your setup.
  const rawBody = e.postData.contents;

  const payload = JSON.parse(rawBody);
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Transcripts');
  sheet.appendRow([
    new Date(),
    payload.event,
    payload.data.batch_id,
    payload.data.status,
    payload.data.item_count,
    payload.data.completed_count,
    payload.data.failed_count,
  ]);

  return ContentService.createTextOutput(JSON.stringify({ ok: true }))
    .setMimeType(ContentService.MimeType.JSON);
}

Deploy it as a web app (Deploy > New deployment > Web app, execute as yourself, access "Anyone") and copy the deployment URL. Register that URL with Scriptube exactly as in Option A.

Important limitation: Apps Script's doPost(e) does not give you direct access to inbound request headers, which is where X-Scriptube-Signature and X-Scriptube-Timestamp arrive. Without header access, you cannot verify the HMAC signature inside Apps Script alone, which means anyone who learns your deployment URL could append fake rows. For anything beyond a personal/low-stakes sheet, put a small relay in front of it — a Cloudflare Worker or similar — that verifies the signature and only forwards the body to Apps Script on success, or use the Make route in Option A instead, where the verification step is straightforward.

Which one to use

Make scenarioApps Script only
Signature verificationYes, in a function stepNot without a relay in front
Extra service neededA Make accountNone
Best forAnything that should be verified, or that also needs branching/other actionsA quick personal log where the URL stays private

Avoiding duplicate rows

A webhook can be delivered more than once in genuinely rare cases — a slow receiver that times out just as it finishes writing, for instance, can cause Scriptube's retry logic to attempt a redelivery before it hears back. Guard against a duplicate row by checking the batch_id before appending: in Make, add a Google Sheets > Search Rows module filtering on the batch id column, and only run Add a Row when nothing matches. In Apps Script, scan the sheet's batch id column with a short loop before calling appendRow. It's a few extra lines either way, and it's the difference between a sheet that's safe to leave unattended and one you have to periodically de-duplicate by hand.

Getting more than the summary into the sheet

The webhook payload for batch.completed carries counts, not transcript text. If you want the actual transcript in the sheet (or a linked Drive file), add a second step that calls the export endpoint once the webhook confirms the batch finished:

GET https://scriptube.me/api/v1/transcripts/{batch_id}/export?format=csv
Header: X-API-Key: YOUR_API_KEY

CSV exports paste cleanly into Sheets' own CSV import, or you can pull it as JSON and map fields into columns yourself — see youtube-transcript-to-excel-google-sheets for column-by-column guidance on the export schema, and how-to-export-youtube-transcripts-to-srt-vtt-txt if you need a different output format instead.

Keeping the sheet from growing forever

A webhook-driven sheet only ever appends — nothing deletes an old row automatically. If you're tracking a high-volume workflow (a batch per hour, say), plan for periodic archiving: move rows older than a set window to a separate "archive" tab on a schedule, rather than letting one tab grow until Sheets itself starts slowing down. This is a Sheets limitation, not a Scriptube one — the webhook delivery itself doesn't care how big the destination sheet gets.

Start with an API key: /ui/signup.

Try Scriptube Free

Extract YouTube transcripts instantly. No credit card required.

Get Started

Related Articles

Tutorials

Your YouTube Transcript Library: Find Everything You've Already Processed

Every video you've ever submitted to Scriptube stays in your library — browsable by channel and playlist, searchable when you need to find something you...

Tutorials

How to Retry Failed YouTube Transcripts Without Resubmitting the Batch

A batch of 50 videos rarely comes back 50 for 50 — a couple of videos might have no captions, one might hit a rate limit, another might just need a second...

Tutorials

YouTube Transcript API: The Complete Guide

The Scriptube API lets you submit YouTube video, playlist, or channel URLs and get back transcripts and metadata as JSON, CSV, or JSONL, plus timed segments...