YouTube
YouTube Transcript Scraper: Download Transcripts in Bulk
Download YouTube transcripts in bulk, even from videos with no captions, using AI fallback, speaker labels and translation. Input, output, API and RAG tips.
YouTube
Download YouTube transcripts in bulk, even from videos with no captions, using AI fallback, speaker labels and translation. Input, output, API and RAG tips.
Getting the transcript of one YouTube video is easy: click “Show transcript” and copy. Getting transcripts for 300 lectures, a podcast’s full back catalogue, or every earnings call a competitor posted is a different job. Many of those videos have no caption track at all, which is where most transcript tools return an error.
The YouTube Transcript Scraper handles both cases. It pulls YouTube’s own captions when they exist, and when they don’t, it downloads the audio and transcribes it with AI speech-to-text. It can also label speakers (diarization) and translate the transcript, so you get usable text from any public video instead of a list of failures.
Each video goes through up to three stages:
You control this with transcriptionMode:
transcriptionMode |
Behaviour |
|---|---|
auto (default) |
Captions first, AI fallback if none exist |
captions_only |
Only existing captions; videos without them return source: "none" |
ai_only |
Always transcribe with AI, even when captions exist |
No YouTube Data API key, OAuth or quota is involved.
urlList. Watch URLs, youtu.be, Shorts, embed and /live/ URLs all work.transcriptionMode.diarization and/or translationEnabled.{
"urlList": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw",
"https://youtu.be/dQw4w9WgXcQ",
"https://www.youtube.com/shorts/VIDEO_ID"
],
"transcriptionMode": "auto"
}
For multi-speaker content you want to localise, turn on diarization and add target languages:
{
"urlList": [
"https://www.youtube.com/watch?v=VIDEO_ID_1",
"https://www.youtube.com/watch?v=VIDEO_ID_2"
],
"transcriptionMode": "ai_only",
"diarization": true,
"translationEnabled": true,
"translationLanguages": ["es", "de", "fr"]
}
ai_only here makes every episode go through the same engine, so speaker labels and timestamps are consistent across the whole set.
Every record has a url and a source that tells you how the text was obtained: captions, ai_transcription, none or error.
A captions result is compact:
{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"source": "captions",
"transcript": "We're no strangers to love\nYou know the rules and so do I\nA full commitment's what I'm thinking of"
}
An AI transcription result adds structure (trimmed; word-level timings removed):
{
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"source": "ai_transcription",
"transcription": {
"full_transcript": "All right, so here we are in front of the elephants. Cool thing about these guys is that they have really, really, really long trunks...",
"utterances": [
{ "text": "All right,", "start": 1.297, "end": 1.517, "speaker": 0 },
{ "text": "so here we are in front of the elephants.", "start": 1.518, "end": 3.379, "speaker": 0 }
],
"languages": ["en"]
}
}
Each utterance also carries a confidence score and a words array with per-word timings. When translation is enabled, the translated transcripts come back in the same record, keyed by language. Failed videos (private, deleted, geo-blocked) get source: "error" and a readable error message rather than silently disappearing, and each URL produces exactly one record.
Keep your Apify token in APIFY_TOKEN.
cURL:
curl -X POST \
"https://api.apify.com/v2/acts/epicscrapers~youtube-transcript-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urlList": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"], "transcriptionMode": "auto"}'
Python (pip install apify-client), normalising both sources into one text field:
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("epicscrapers/youtube-transcript-scraper").call(run_input={
"urlList": [
"https://www.youtube.com/watch?v=VIDEO_ID_1",
"https://www.youtube.com/watch?v=VIDEO_ID_2",
],
"transcriptionMode": "auto",
})
docs = []
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item["source"] == "captions":
text = item["transcript"]
elif item["source"] == "ai_transcription":
text = item["transcription"]["full_transcript"]
else:
continue
docs.append({"url": item["url"], "text": text})
Transcripts are one of the best sources of domain knowledge for AI applications: conference talks, tutorials, expert interviews and product demos that never got written down. A few patterns that work well:
RAG over a channel. Chunk each transcript (500 to 1,000 tokens), embed the chunks, and store them with the video url. For AI-transcribed videos, chunk along utterances instead and keep the start time of each chunk. Your chatbot can then cite https://www.youtube.com/watch?v=ID&t=123s and send users to the exact moment.
Summaries and show notes. Feed full_transcript to an LLM for a summary, chapter list or blog draft. With diarization on, include speaker labels in the prompt so the model can attribute quotes (“Speaker 1 argues…”) instead of blending voices.
Structured extraction. Ask a model to pull product mentions, pricing statements or guidance from earnings calls and keynotes into JSON, then track them across quarters.
Training and evaluation data. The auto mode gives you text for videos that other tools skip, which is useful for building speech, dialogue or domain-specific corpora.
Transcripts tell you what was said; comments tell you how people reacted. The YouTube Comments Scraper takes the same video URLs in startUrls and returns each comment’s text, like_count, author, timestamp and parent (for reply threads), with sortCommentsBy set to top or new and a maxCommentsPerUrl limit (0 for all).
{
"startUrls": ["https://www.youtube.com/watch?v=VIDEO_ID_1"],
"sortCommentsBy": "top",
"maxCommentsPerUrl": 500
}
Join both datasets on the video URL and you can ask an LLM which claims in a video drew the most pushback, or which questions viewers keep asking.
If you track topics across media, pair this with the Google News scraper guide to cover written coverage too.
The YouTube Data API can list caption tracks, but downloading caption content generally requires OAuth and permission from the video owner, and it doesn’t help when a video has no captions. This actor works on any public video without an API key and falls back to AI transcription.
Yes. In auto or ai_only mode the audio is transcribed with AI. Only captions_only returns none for such videos.
Shorts and finished live streams (VODs) work. Streams that are live right now are not supported.
Captions in any language YouTube provides. AI transcription supports 100+ languages, and translation accepts language codes such as es, fr, de or ja.
The actor only accesses publicly available videos. Transcripts are still the creator’s content, so respect YouTube’s terms and copyright: analysing, summarising and internal research are common uses, while republishing transcripts wholesale is riskier. This is not legal advice.
Paste ten video URLs, leave the mode on auto and run it. You’ll have a dataset of full transcripts in minutes, including the videos with no captions. Open the YouTube Transcript Scraper on Apify or see the actor page.