YouTube Transcript Scraper avatar

YouTube Transcript Scraper

Pricing

from $6.50 / 1,000 transcript scrapeds

Go to Apify Store
YouTube Transcript Scraper

YouTube Transcript Scraper

Extract YouTube transcripts with millisecond timestamps. Give it a video, a channel, a playlist or a search keyword and get raw caption segments plus merged paragraphs, ready for RAG, search and analysis. Incremental mode skips videos you already have, so a scheduled run does not bill you twice.

Pricing

from $6.50 / 1,000 transcript scrapeds

Rating

0.0

(0)

Developer

Mehmet

Mehmet

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

Give this Actor a YouTube video, Shorts, channel or playlist link — or just a search keyword — and it returns the spoken content as structured, timestamped text: the raw caption lines exactly as YouTube serves them, plus merged paragraphs ready for embedding. No browser automation, no cookies, no yt-dlp binary to maintain.

This Actor is an independent, third-party tool. It is not affiliated with, endorsed by, or sponsored by YouTube or Google LLC. YouTube and the YouTube logo are trademarks of Google LLC.

What makes this different

Most transcript scrapers charge you again for every video, every run. This one remembers what it already fetched.

Incremental mode is on by default. A video that was scraped in an earlier run is skipped and not charged. If you track channels on a schedule, this is where the actual bill is decided:

Tracking 20 channels daily, 30 videos eachTranscripts billed per month
A scraper without deduplication18,000
This Actor, incremental mode on660

That is 27× fewer billed units for the same coverage, assuming each channel publishes around three new videos a month. The ratio is the point: it holds whatever the two unit prices happen to be.

This applies to recurring runs. For a single one-off bulk scrape where every video is new, a cheaper per-unit actor will cost you less. Pick the tool that matches your job.

Three more things you get here:

  • Paragraphs, not just caption fragments. Raw captions arrive as 2-second snippets. chunkSeconds merges them into timestamped paragraphs that are ready to embed. Set chunkBy to chapter and the split follows the video's own chapters when it has them.
  • Human-written captions preferred. preferManual picks the human transcript over the auto-generated one when both exist. Auto captions have no punctuation and need cleaning before they are useful.
  • Translate the transcript. Set translateTo to a language code and the transcript comes back in that language, using YouTube's own translation — no extra request, no extra charge. Every video supports a different set of translation languages; if yours doesn't offer the one you asked for, you still get the original transcript plus a warning listing what it does support, and translatedTo on the record tells you at a glance whether the translation actually happened.

Check the cost before you spend it

Turn on Preview only and the actor lists every video it would scrape, how many were already fetched in an earlier run, and how many would actually be charged — without fetching a single transcript.

Preview makes no transcript charges. The Apify actor start event is still billed, because the platform charges it before this actor runs. There is no way for any actor to suppress it.

Judging transcript quality in bulk

Every record carries a transcriptQuality block so you can filter before you ingest:

FieldUse it to
coverageRatioDrop videos where captions cover only part of the video
wordCount, wordsPerMinuteSpot near-empty or broken transcripts
hasPunctuationDecide which transcripts need cleaning first
isAutoGeneratedPrefer human-written text when you have a choice

Output formats

outputFormat adds a ready-to-use string to each record: text, srt or vtt. Segments, paragraphs and metadata are always included as well — you never have to choose between a subtitle file and structured data.

Chapters

When a video's description contains a proper chapter list, chapters is filled in and chunkBy: chapter splits paragraphs on those boundaries. Many videos do not have one; in our sample only about a quarter did. When there is no chapter list the actor falls back to fixed-length paragraphs.

What does YouTube Transcript Scraper do?

Paste any mix of links into YouTube URLs and get back one dataset record per video: title, channel, and thumbnail, plus duration, view count, publish date, and the transcript when Include transcript is on. Video and Shorts links are scraped directly; channel and playlist links (@handle, /channel/UC..., or list=...) are expanded into their videos automatically, up to a configurable cap. No link handy? Use Search keywords instead and the Actor searches YouTube for you — no URL needed. Every record carries inputUrl, so you always know which source produced it, even when several sources are mixed in one run.

Transcripts come in two forms. segments are the caption lines exactly as YouTube's track returns them. chunks merge those lines into paragraph-length blocks, split at sentence boundaries for human-written captions and at pause gaps for auto-generated ones. Every chunk and segment carries a millisecond startMs.

Click Start to see it run against two known-good example videos — no setup required.

Sample output

Most of this record is copied from a real run of this Actor (Run mG13RBc8ty3X2ltoN, dataset k4Jj0ETl2bDe7h5cw). To respect copyright, most segments and all chunks text are collapsed below. Six fields — inputUrl, description, keywords, chapters, transcriptQuality and translatedTo — were added to the schema after that run and are shown here with illustrative example values rather than that run's actual data; transcriptFormatted is genuinely null below because outputFormat defaults to json, and translatedTo is genuinely null because no translation was requested.

{
"videoId": "arj7oStGLkU",
"url": "https://www.youtube.com/watch?v=arj7oStGLkU",
"inputUrl": "https://www.youtube.com/watch?v=arj7oStGLkU",
"title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED",
"channelName": "TED",
"channelUrl": "https://www.youtube.com/@TED",
"thumbnailUrl": "https://i.ytimg.com/vi/arj7oStGLkU/hqdefault.jpg",
"durationSeconds": 844,
"viewCount": 61678070,
"publishedAt": "2016-04-06T16:59:35.000Z",
"description": "/* the video's own description text, truncated */",
"keywords": ["TED", "TEDTalk", "..." /* illustrative, truncated */],
"language": "en",
"isAutoGenerated": false,
"availableLanguages": ["ar", "hy", "bg", "..." /* 49 total, truncated */],
"segments": [
{ "startMs": 12645, "durationMs": 1370, "text": "So in college," }
// 314 more segments — truncated for this README
],
"chunks": [
{ "startMs": 12645, "endMs": 50900, "text": "/* 608-char merged paragraph, truncated */", "language": "en", "isAutoGenerated": false }
// 21 more chunks — truncated for this README
],
"nonSpeechEvents": [],
"chapters": [],
"transcriptAvailable": true,
"transcriptQuality": {
"coverageRatio": 0.97,
"wordCount": 2180,
"wordsPerMinute": 155,
"hasPunctuation": true
},
"transcriptFormatted": null,
"scrapedAt": "2026-08-10T19:15:12.912Z",
"translatedTo": null,
"contentHash": "ba594315dc2da412ed55e0ae1e6610be77895fa6e08e6c1bf63c966d924d5de1"
}

The real record has 315 segments and 22 chunks for this 14-minute talk. nonSpeechEvents is empty here; on a music video it holds entries like [Music], kept separate from spoken text. chapters is empty above because this video has none — see the Chapters section above.

How to use YouTube Transcript Scraper

  1. Click Start to run it with the two example videos, or replace YouTube URLs with your own — video links, Shorts links, youtu.be short links, bare video IDs, channel links (@handle or /channel/UC...), or playlist links all work in the same field.
  2. No link on hand? Add terms to Search keywords instead and the Actor finds and scrapes the top results for you.
  3. Pulling a channel or playlist? Set Max videos per source to cap how many it expands to.
  4. Not sure what a run will cost? Turn on Preview only first — see "Check the cost before you spend it" above.
  5. Leave Incremental mode on and schedule the run — each later run skips videos already fetched, so a daily schedule only pays for what's new.
  6. Read results from the dataset, the API, or push them into Google Sheets, Slack, Zapier, Make or n8n through the standard Apify integrations.

Input configuration

FieldWhat it doesDefault
YouTube URLsAny mix of video, Shorts, channel or playlist links. Channel and playlist links are expanded into their videos automatically2 example videos
Search keywordsSearch YouTube for each keyword and scrape transcripts from the top results — no URL neededEmpty
Preview only (no transcript charges)List what would be scraped and how many videos would be charged, without fetching a single transcriptOff
Preferred languagesLanguage codes in priority order (en, de, tr, ...). If none match, the first available track is returned rather than skipped — check language on the record["en"]
Prefer human-written captionsChoose manual captions over auto-generated when both existOn
Translate transcript toLanguage code to translate the transcript into (es, de, ...), using YouTube's own translation at no extra charge. Falls back to the original transcript with a warning if the video doesn't offer that language — check translatedTo on the recordOff (no translation)
Include transcriptOff skips duration, view count and publish date; title, channel and thumbnail return, at the lower priceOn
Transcript formatAdds a ready-to-use text, srt or vtt string to each record. Segments and paragraphs are always included as wellJSON only
Paragraph length (seconds)Target length of each merged chunk; raw segments always kept too40 (5–600)
Paragraph boundariesSplit paragraphs on the video's own chapters when it has them, otherwise fixed lengthFixed length
Include ShortsWhen expanding a channel, also include Shorts. Shorts links given directly are always scrapedOff
Max videos per sourceUpper bound on videos pulled per channel, playlist or search30 (1–200)
Max pages per sourceHow many result pages to fetch per channel, playlist or search10 (1–20)
Incremental modeSkip videos already fetched in a previous runOn

Video URLs, Channel URLs and Max videos per channel are deprecated but still accepted, so existing runs keep working — new runs should use YouTube URLs and Max videos per source instead.

Pricing

This Actor uses Apify's Pay-Per-Event model. Two events fire independently:

EventFires when
video-metadataA video record is delivered — even with no captions
transcript-scrapedA transcript was actually extracted and included

A video with no captions, a deleted video, or one that stays blocked after retries never triggers transcript-scraped. A caption-less video still returns a metadata-only record, charged at the metadata rate only. A deleted, private, or permanently blocked video returns no record at all and is not charged for either event — you only pay the transcript rate for transcripts you actually receive. Turn Include transcript off to fetch metadata only, at the lower single-event rate. Exact per-event prices are on this Actor's Pricing tab in Apify Console.

Limits, stated plainly

Not every video has a transcript, and we do not invent one.

  • No captions at all — the video still returns a metadata record, charged at the metadata rate only. transcript-scraped does not fire.
  • Deleted, private, or permanently blocked — no record at all, and no charge for either event.
  • Auto-generated captions carry YouTube's own errors. Proper nouns, technical terms and overlapping speech are where they break down. The record tells you whether the track was auto-generated or human-written, so you can filter on it.
  • Translation is YouTube's, not ours. If the video does not offer the language you asked for, you get the original transcript plus a warning — check translatedTo on the record rather than assuming the translation happened.
  • Shorts and long videos behave the same way, but a video that stays rate-limited after retries is reported as such instead of being silently dropped.

Output & integrations

Every record follows one schema: videoId, url, inputUrl, title, channelName, channelUrl, thumbnailUrl, durationSeconds, viewCount, publishedAt, description, keywords, language, isAutoGenerated, availableLanguages, segments, chunks, nonSpeechEvents, chapters, transcriptAvailable, transcriptQuality, transcriptFormatted, scrapedAt, translatedTo, contentHash.

segments and chunks exist side by side on purpose. segments are the unmodified caption lines, for your own paragraphing or subtitle format. chunks are pre-merged into paragraphs sized by Paragraph length, ready for search-index or RAG pipelines without extra work. Both carry millisecond timestamps, so any chunk or segment links back to url plus its startMs to jump into the video.

inputUrl records which entry in YouTube URLs or Search keywords produced this video — useful when one run mixes several sources. chapters holds the video's own chapter list when it has one (see "Chapters" above) and is empty otherwise. transcriptQuality is the quality block described in "Judging transcript quality in bulk" above. transcriptFormatted holds the ready-to-use string requested via Transcript format, and is null when that setting is left at its json default.

isAutoGenerated tells you whether captions came from YouTube's speech model or a human — useful for quality filtering, since auto captions are noisier on accented or technical speech. translatedTo holds the language code the transcript was actually translated into when Translate transcript to succeeded, and is null when no translation was requested or the video didn't offer the one you asked for — language always keeps carrying the source track's language, so the two fields together answer "was this translated, and from what." contentHash fingerprints every field except scrapedAt (the fetch timestamp), inputUrl (provenance, not content) and transcriptFormatted (derived from segments, not independent content) — useful for detecting changes between your own runs without diffing every field. A translated transcript is genuinely different content, so translatedTo is included in the hash: translating a previously-scraped video produces a new contentHash. inputUrl and transcriptFormatted were excluded after earlier versions of this Actor already shipped, so records produced before this version will hash differently even when nothing about the video changed — expect one full sweep of "changed" records the first time you run this version.

Incremental mode works by video ID, and only for runs where Include transcript is on: once a video has produced a transcript record, it's skipped — and not re-charged — on a later run. Metadata-only runs (Include transcript off) are never recorded this way, so the same videos are billed again on every run.

Export as JSON, CSV, Excel or XML, or read the dataset through the Apify API. Works with the standard Apify integrations: Google Sheets, Slack, Zapier, Make, n8n, and webhooks.

Frequently asked questions

Is this Actor affiliated with YouTube? No. This is an independent, unofficial tool, not affiliated with, endorsed by, or connected to YouTube or Google LLC. All product names and trademarks belong to their respective owners.

Why do some videos return no transcript? Two outcomes return no transcript: no captions in any language (metadata rate only), or a deleted, private, or blocked video after three retries (nothing charged). Captions that don't match your Preferred languages aren't skipped — the Actor falls back to the first available track, charged at the transcript rate.

Are auto-generated captions accurate? It varies — auto captions handle clear speech well but struggle with fast talkers, technical terms, or heavy accents. Check isAutoGenerated on the record to filter or clean up as needed. This Actor prefers human-written captions by default, via Prefer human-written captions.

Can I get a whole channel? Yes. Paste the channel's @handle or /channel/UC... URL into YouTube URLs and set Max videos per source (up to 200). The Actor pages through the upload list and processes every video the same way as a single one — same metadata, transcript logic, and incremental skip. Playlists and search results work the same way. If a source has more videos than your cap, the run finishes normally and its RUN-SUMMARY output notes the truncation.