YouTube Transcript Scraper - Bulk & Whole Channels avatar

YouTube Transcript Scraper - Bulk & Whole Channels

Pricing

from $2.00 / 1,000 transcript delivereds

Go to Apify Store
YouTube Transcript Scraper - Bulk & Whole Channels

YouTube Transcript Scraper - Bulk & Whole Channels

Extract transcripts from thousands of YouTube videos in one run. Paste video URLs, a channel, or a playlist. Clean text, timestamped segments, SRT and WebVTT subtitles, or RAG-ready chunks. Any language, human or auto captions, plus video metadata. $2 per 1,000; videos without captions are free.

Pricing

from $2.00 / 1,000 transcript delivereds

Rating

0.0

(0)

Developer

DONGMIN KIM

DONGMIN KIM

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

YouTube Transcript Scraper — Bulk Subtitles to Text, SRT, VTT & RAG Chunks

YouTube Transcript Scraper — Bulk Subtitles to Text, SRT, VTT & RAG Chunks

Extract transcripts from thousands of YouTube videos in one run. Paste video URLs, a channel, or a playlist — get back clean text, timestamped segments, SRT/VTT subtitle files, or pre-chunked passages ready for embeddings. Video metadata is included in every row at no extra cost.

Built for people who hit the wall with other transcript scrapers: one URL at a time, silent failures when YouTube throttles, and no metadata.


What makes this one different

This actorTypical transcript scraper
InputUnlimited URLs + whole channels + playlists in one runOne video URL per run
ThrottlingDatacenter → residential proxy escalation, per-video IP sessionsFails, or silently returns nothing
MetadataTitle, channel, views, duration, publish date, keywords, thumbnail — freeSold separately, or missing
RAG outputMerged chunks with timestamps + configurable overlapRaw 2-second caption cues
LanguagesPriority list, human tracks preferred over auto-generatedFirst track found
FailuresRow with a readable error, and you are never charged for itCharged anyway, or the run dies

Why the throttling part matters

YouTube's caption host (youtube.com/api/timedtext) rate-limits per IP address, and independently of the rest of the API. Once an IP is throttled, every caption format and every header combination keeps returning HTTP 429 — we measured this: 15 request variants, all blocked, for over 40 minutes on the same IP.

Most scrapers treat that as "retry and hope". This one treats a 429 as burn this IP and moves to a fresh proxy session. It also starts on cheap datacenter proxies and only escalates to residential once datacenter is provably blocked — which is exactly why it can be priced below the alternatives.


Input

Paste anything YouTube-shaped into YouTube URLs:

{
"videoUrls": [
"https://www.youtube.com/watch?v=8S0FDjFBj8o", // watch URL
"https://youtu.be/jNQXAC9IVRw", // short link
"https://www.youtube.com/shorts/abcdefghijk", // Shorts
"dQw4w9WgXcQ", // bare video ID
"@veritasium", // whole channel
"https://www.youtube.com/playlist?list=PLZHQ..." // whole playlist
],
"maxVideos": 500,
"languages": ["en", "es"],
"outputFormat": "chunks",
"chunkMaxChars": 1200,
"chunkOverlapChars": 100
}

Channels and playlists are expanded to their videos automatically, up to Max videos.

Key settings

  • Preferred languages — ISO-639-1 codes in priority order. A human-made track always beats an auto-generated one in the same language.
  • Allow auto-generated captions — turn off if you only want reviewed subtitles.
  • Output formattext, chunks, segments, srt, vtt, or all.
  • Chunk size / overlap — only used by chunks. Caption cues are ~2 seconds long and useless for embeddings; this merges them into passages.
  • Concurrency — default 10. Raise for speed.

Every option

The same wording you see in the Apify console, with the JSON key for API and MCP callers.

OptionWhat it doesDefault
YouTube URLsvideoUrls (required)Videos, channels or playlists. Paste any mix of: watch URLs, youtu.be links, /shorts/, /embed/, bare 11-character video IDs, @handles, /channel/UC…, or playlist URLs. Channels and playlists are expanded into their videos automatically.
Max videosmaxVideosHard cap on how many videos this run will process, counting videos pulled out of channels and playlists. Leave empty for no cap.100
Preferred languageslanguagesISO-639-1 codes in priority order, e.g. en, es, ko. The first language the video actually has is used. A human-made track always wins over an auto-generated one in the same language.["en"]
Allow auto-generated captionsallowAutoGeneratedFall back to YouTube's speech-recognition captions when no human-made track exists. Turn this off if you only want reviewed subtitles.true
Fall back to any available languageanyLanguageFallbackIf none of your preferred languages exist, take whatever track the video does have instead of returning nothing.true
Output formatoutputFormattext = one clean paragraph string. chunks = merged passages sized for RAG/embeddings. segments = raw timed cues. srt / vtt = subtitle files. all = every field at once."text"
Chunk size (characters)chunkMaxCharsOnly used by the "chunks" format. Caption cues are ~2 seconds long and useless for embeddings; this merges them into passages of about this length.1200
Chunk overlap (characters)chunkOverlapCharsRepeat this much of the previous chunk at the start of the next one, so a sentence split across a boundary still embeds well.0
Include video metadataincludeMetadataAdd title, channel, view count, duration, publish date, keywords and thumbnail to every row. Free — it arrives in the same request as the transcript.true
Include videos without captionsincludeEmptyResultsEmit a row with an error field for videos that have no usable transcript, instead of skipping them silently. You are never charged for these rows.true
ConcurrencyconcurrencyHow many videos to fetch in parallel. Raise it for speed, lower it if you see throttling on a small proxy pool.10
ProxyproxyConfigurationLeave the default. YouTube throttles caption downloads per IP, so the actor starts on cheap datacenter proxies and only escalates to residential when it actually gets blocked — that escalation is what keeps the price low.{"useApifyProxy":true}

Output

One row per video:

{
"videoId": "8S0FDjFBj8o",
"url": "https://www.youtube.com/watch?v=8S0FDjFBj8o",
"title": "The Danger of Silence",
"description": "Clint Smith is a teacher, poet and doctoral candidate...",
"channelName": "TEDx Talks",
"channelId": "UCsT0YIqwnpJCM-mx7-gSA4Q",
"channelUrl": "https://www.youtube.com/channel/UCsT0YIqwnpJCM-mx7-gSA4Q",
"durationSeconds": 356,
"viewCount": 15641909,
"publishedAt": "2014-03-07",
"category": "Nonprofits & Activism",
"keywords": ["poetry", "education"],
"isLive": false,
"thumbnailUrl": "https://i.ytimg.com/vi/8S0FDjFBj8o/maxresdefault.jpg",
"language": "en",
"languageName": "English",
"isAutoGenerated": false,
"segmentCount": 128,
"wordCount": 1043,
"transcript": "Hear that? That is the sound of ..."
}

With outputFormat: "chunks" you also get:

"chunks": [
{ "start": 0.0, "end": 58.4, "text": "Hear that? ..." },
{ "start": 55.1, "end": 121.7, "text": "...continues here" }
]

Videos with no captions come back as a row with transcript: null and a readable errorand are never billed.

Every field

You are billed per transcript delivered, so here is everything a row can contain. Which fields appear depends on outputFormat and includeMetadata; a metadata field is also absent when YouTube did not publish it for that video.

FieldWhenWhat it is
videoIdalwaysThe 11-character id.
urlalwayswatch?v= URL.
languagealwaysCaption language code of the track that was used, e.g. "en".
languageNamealwaysIts display name, e.g. "English (auto-generated)".
isAutoGeneratedalwaystrue when the track is YouTube speech recognition rather than human-made.
segmentCountalwaysHow many timed cues the track had.
wordCountalwaysWords in the transcript.
transcripttext / allOne clean paragraph string. null on a row that carries an error.
chunkschunks / allPassages merged to your character cap, each with start, end, text. Sized for embeddings.
segmentssegments / allThe raw cues: start, duration, text.
srtsrt / allA complete SRT subtitle file as a string.
vttvtt / allA complete WebVTT file as a string.
titlemetadataVideo title.
descriptionmetadataThe full video description.
channelNamemetadataUploading channel's display name.
channelIdmetadataIts UC… id.
channelUrlmetadataIts canonical /channel/UC… URL.
durationSecondsmetadataLength in seconds.
viewCountmetadataViews at the time of the run.
publishedAtmetadataUpload date. Costs one extra request per video, which is why it follows includeMetadata.
categorymetadataYouTube's own category label.
keywordsmetadataThe uploader's tags.
isLivemetadatatrue for a live or previously-live stream.
thumbnailUrlmetadataLargest available thumbnail.
publishedTextchannel/playlist inputThe listing page's relative date, e.g. "3 weeks ago", kept from the expansion step.
isShortchannel/playlist inputtrue when the video was listed as a Short.
tabchannel inputWhich channel tab it came from: "videos", "shorts" or "live".
errorempty rowsWhy this video produced no transcript. Only written when Include videos with no captions is on.
availableLanguagesempty rowsCaption languages the video does have, so you can widen your language list and re-run.

Pricing

Pay per event. Beyond $0.00002 for starting a run — the platform's $0.00001 minimum, charged once per GB of memory, on 2 GB — you are only charged for a transcript that is actually delivered. Videos without captions, throttled requests, and failed rows cost you nothing.

Run it on a channel of 500 videos and you pay for the transcripts you get back, not for the attempts.


Who this is for

  • AI and RAG engineers — the chunks format drops straight into a vector store, so a channel becomes a corpus with no transcription bill.
  • Content marketers with a back catalogue — a year of video becomes the raw material for posts, newsletters and show notes in one run.
  • Market and competitor researchers — transcribe a rival's whole channel and search what they actually say, not what they tagged.
  • Localisation teams — bulk SRT and VTT export for re-uploading or translating.

Common uses

  • RAG / AI knowledge baseschunks format drops straight into a vector store.
  • Content repurposing — turn a back catalogue into blog posts, newsletters, show notes.
  • Competitor & market research — transcribe a competitor's whole channel and search it.
  • SEO — extract the language your audience actually uses, at scale.
  • Subtitle files — bulk SRT/VTT export for re-uploading or translating.
  • Datasets — build training or analysis corpora with metadata attached.

Other Actors in this family

Same engines, same billing, no account or API key on any of them.

YouTube & video

Search demand

E-commerce

Hiring

Run it from code

Nothing here needs a login to the source, only your Apify token.

HTTP — start a run and wait for the rows:

curl -X POST "https://api.apify.com/v2/acts/gganbukim~youtube-transcript-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "content-type: application/json" \
-d @input.json

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('gganbukim/youtube-transcript-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python

from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("gganbukim/youtube-transcript-scraper").call(run_input=input)
items = client.dataset(run["defaultDatasetId"]).list_items().items

Scheduled or event-driven — attach a schedule to run it on a cron, or a webhook to push each finished run into your own endpoint. It also connects through Apify's Zapier, Make, n8n and LangChain integrations, and is reachable from an MCP server if you are driving it from an agent.

Standby / API mode — the run above is synchronous: one call in, rows out, no polling. That is the shape to use if you are calling this per request rather than in a batch.

Errors, limits and what you are charged for

  • You pay for delivered rows only. A row your filters removed, a page that failed, a retry — none of it is billed. Starting a run costs $0.00001: the platform minimum, charged once per gigabyte, and this Actor runs on 512 MB.
  • A run that delivers nothing still costs the start fee and nothing else. If the input resolved to zero items, the run fails loudly with the reason rather than finishing green on an empty dataset.
  • Blocking is handled by changing address, not by waiting. The Actor starts on cheap datacenter proxies and moves up only after a tier has actually been refused several times in a row, then drops back down once the cheap tier answers cleanly again. You are not paying for residential bandwidth that was never needed.
  • Rate limits belong to the source, not to this Actor. Very large inputs are worked through in batches; the run reports how many items succeeded, were filtered, and failed, so a partial result is never presented as a complete one.
  • Dataset retention follows your Apify plan. Export what you need, or push it out with a webhook, if you want it past that window.

This Actor reads pages and public endpoints that anyone can open in a browser without an account. It does not log in, does not defeat a paywall, and does not touch anything behind authentication.

Scraping public data is broadly lawful in the US and the EU, and courts have repeatedly said so — but "public" is not the same as "unrestricted", and what you may then do with the data is a separate question from whether you may collect it. Personal data pulls in the GDPR and similar regimes whatever the source, so if your rows contain people, you need a lawful basis for keeping them.

Apify publishes a fuller treatment in Is web scraping legal? and an ethical scraping guide. None of this is legal advice; if the use is commercial and the data is personal, ask someone qualified.

Something wrong, or missing?

Open an issue on the Actor's Issues tab — it goes straight to the developer and is the fastest route. Include the run ID; it carries the input and the log, which is usually enough to reproduce the problem without another round trip.

Sources change without warning, and a field that quietly goes null is worth reporting even if the run succeeded. A broken parser looks exactly like a quiet day in the data until someone says so.

FAQ

Will I get blocked, or my account banned? There is no account to ban — this Actor never signs in and sends no cookies. It reads the same caption endpoints the player uses, on cheap datacenter proxies, escalating to residential only once datacenter is provably blocked. YouTube signals throttling with an HTTP 200 and an error body rather than an error code, which is the trap that silently halves most scrapers' results; this one detects it by reason and rotates.

Does this need a YouTube API key? No. The official Data API will not return captions for videos you do not own; this does not use it.

What if a video has no captions? You get a row with error explaining why, plus availableLanguages when there were tracks in other languages. You are not charged.

Can I get auto-translated captions? Not currently. YouTube removed the tlang translation parameter from the caption endpoint. Pull the original language and translate downstream.

How fast is it? Concurrency 10 by default. A 500-video channel typically finishes in a few minutes.

Can I run it on a schedule? Yes — use Apify Schedules, or call it from the API. It is also available over MCP for AI agents.

Is scraping YouTube transcripts legal? This reads publicly available caption data, the same data the YouTube web player requests. You are responsible for how you use the output, including copyright in the underlying content.


How much does 1,000 transcripts cost? $2.00, plus $0.00002 for the run itself. Videos with no captions are not billed at all, so a list padded with them costs less than you budgeted rather than more.

Can I export the results to Excel or Google Sheets? Yes. Every run's dataset downloads as CSV, Excel, JSON, XML or RSS from the Storage tab, or straight from the API if you want a live link a spreadsheet can pull.

Can I connect it to Zapier, Make or n8n? Yes — Apify publishes integrations for all three, plus webhooks that fire when a run finishes. A common setup is a schedule here and a webhook into your own database or Slack.

Do I need to write code? No. Fill the form in the console and press Start. If you do want code, the Apify client libraries for Python and JavaScript call this the same way, and it is available over MCP so an AI agent can call it directly.

Integrations

Works with Apify's standard integrations: webhooks, Zapier, Make, n8n, Google Sheets, Airtable, LangChain, and the Apify MCP server for AI agents. Every run's dataset is available as JSON, CSV, Excel or XML via the API.