YouTube Transcript Scraper - Subtitles & Captions avatar

YouTube Transcript Scraper - Subtitles & Captions

Pricing

from $1.95 / 1,000 transcript results

Go to Apify Store
YouTube Transcript Scraper - Subtitles & Captions

YouTube Transcript Scraper - Subtitles & Captions

Get YouTube transcripts (captions/subtitles) in bulk for videos, Shorts, channels, playlists or search results. Plain text, timestamped segments, SRT, VTT or RAG-ready chunks, with language fallback and video metadata. No browser, no API key. Pay only for transcripts found.

Pricing

from $1.95 / 1,000 transcript results

Rating

0.0

(0)

Developer

Adyanth Ganesh

Adyanth Ganesh

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

YouTube Transcript Scraper & API for AI Agents

Get YouTube transcripts (captions / subtitles) fast and in bulk: single videos, Shorts, whole channels, playlists or search results. Each row has the full transcript as plain text, timestamped segments, SRT, WebVTT or RAG-ready chunks, plus video metadata: title, channel, publish date, duration, views, language and whether the captions are auto-generated.

It's built for AI agents, LLM pipelines, RAG / embeddings, content research and SEO. It doesn't use a browser, needs no YouTube API key, and you pay only for videos that return a transcript.

  • ⚡ Fast: about 1-2 seconds per video, many videos in parallel. In our cloud stress tests, about 130-140 videos from 15-16 channels, playlists and searches finished in 40-120 seconds per run.
  • ✅ Reliable: 0 failed videos out of 536 in 4 cloud stress runs (20+ languages, Shorts, 3+ hour podcasts, live replays). Every video got either a transcript or a clear "no transcript" reason. If YouTube shows a "confirm you're not a bot" check, the request is retried on a fresh IP and switches to residential proxy when needed.
  • 🌍 Any language: you set a list of preferred languages with fallbacks. If none is available, you get the original spoken language. Videos with AI-dubbed audio tracks are handled correctly.
  • 🤖 Agent-friendly output: clean JSON, a word count, chapters, and RAG chunks with start/end times and deep links (&t=123s) for citations.
  • 💸 Pay only for transcripts: videos without captions, private, age-restricted or unavailable videos return a free row that says why.

What data do you get?

Field groupFields
VideovideoId, url, title, channelName, channelId, channelUrl, publishDate, durationSeconds, duration, viewCount, category, isLive, isUnlisted, description, chapters
Transcripttext (plain), segments (start, end, text in seconds), timestampedText ([m:ss] lines), srt, vtt, chunks (index, text, start, end, url, chars), wordCount, segmentCount
Languagelanguage, languageName, isAutoGenerated, originalLanguage, languageMatch (preferred / original), availableLanguages (all caption tracks), isTranslated, translationError
Statusstatus (ok, no_transcript, error), noTranscriptReason, error, source, sourceType, scrapedAt

How to use

  1. Paste YouTube URLs, video IDs or @handles into one list. The Actor detects the type for each one:
    • Videos: watch?v=, youtu.be/, /shorts/, /live/, /embed/, or a bare 11-character ID.
    • Channels: @handle, /@handle, /channel/UC…, /c/…, /user/…. Add /shorts or /streams to the URL for that tab.
    • Playlists: playlist?list=…
  2. Optionally add search queries. You get the top results for each one.
  3. Set Max videos per channel / playlist / search.
  4. Choose your preferred languages (e.g. en, es) and the output formats you need.
  5. Click Start. You can download the results as JSON, CSV or Excel, or call the Actor through the API / MCP.

Input example

{
"urls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/jNQXAC9IVRw",
"https://www.youtube.com/@veritasium",
"https://www.youtube.com/@mkbhd/shorts",
"https://www.youtube.com/playlist?list=PLUl4u3cNGP63WbdFxL8giv4yhgdMGaZNA"
],
"searchQueries": ["how transformers work"],
"maxVideos": 20,
"languages": ["en", "es"],
"fallbackToAnyLanguage": true,
"outputFormats": ["text", "segments", "chunks"],
"chunkSize": 2000,
"chunkOverlap": 200
}

Output example

{
"videoId": "jNQXAC9IVRw",
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"status": "ok",
"title": "Me at the zoo",
"channelName": "jawed",
"channelId": "UC4QobU6STFB0P71PMvOGN5A",
"publishDate": "2005-04-23T20:31:52-07:00",
"durationSeconds": 19,
"duration": "0:19",
"viewCount": 441560186,
"category": "Film & Animation",
"language": "en",
"languageName": "English",
"isAutoGenerated": false,
"originalLanguage": "en",
"languageMatch": "preferred",
"text": "All right, so here we are, in front of the elephants the cool thing about these guys is that they have really... really really long trunks and that's cool (baaaaaaaaaaahhh!!) and that's pretty much all there is to say",
"wordCount": 39,
"segments": [
{"start": 1.2, "end": 3.36, "text": "All right, so here we are, in front of the elephants"},
{"start": 5.318, "end": 7.974, "text": "the cool thing about these guys is that they have really..."}
],
"chunks": [
{"index": 0, "text": "All right, so here we are, ...", "start": 1.2, "end": 18.881, "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw&t=1s", "chars": 217}
],
"availableLanguages": [
{"code": "en", "name": "English", "isAutoGenerated": false},
{"code": "de", "name": "German", "isAutoGenerated": false}
]
}

A video without a transcript returns a free row:

{"videoId": "UiPcEW_d9Io", "status": "no_transcript", "noTranscriptReason": "no_captions", "error": "This video has no captions or auto-generated transcript.", "title": "...", "transcriptAvailable": false}

Language selection

  • Preferred languages are tried in order. For each language, creator-made captions come before auto-generated ones (unless you turn this off). en also matches en-US, en-GB, etc.
  • Fallback: if none of your languages exists, you get the original spoken language (languageMatch: "original"). If you turn the fallback off, you get a free no_transcript row with reason language_not_available and the list of available languages.
  • Only human-made captions: ignore auto-generated (ASR) captions completely.
  • Auto-translate (best effort): asks YouTube to machine-translate the original transcript into your first preferred language. YouTube currently rate-limits these translation requests heavily, so most of them fail. When that happens you get the original-language transcript with translationError set. If you need a translation, we recommend translating the text field with your own LLM.

Output formats

FormatFieldUse it for
Plain texttextLLM prompts, summaries, search
Timestamped segmentssegmentsHighlights, quotes, video editing
Timestamped texttimestampedTextLLM prompts that cite times ([12:34] ...)
SRT / WebVTTsrt, vttSubtitle files for players and editors
RAG chunkschunksEmbeddings / vector DBs. Chunks follow caption boundaries and have start, end and a deep link to the exact moment

All formats cost the same. Turn off formats you don't need to keep the dataset small.

Pricing

This Actor uses pay-per-event pricing. You pay for transcript-result: one video that returned a transcript. Proxy and compute costs are included. Rows for videos without a transcript, unavailable videos and errors are free. Check the Pricing tab for the current price.

You can cap your spending with the run's maximum cost (or maximum paid results). The Actor stops cleanly when it reaches the limit.

Reliability - how it works

  • The Actor calls the same public endpoints the YouTube mobile apps use. It doesn't load watch pages or run a browser, so each video costs only a few kilobytes of traffic and finishes in about a second.
  • Requests go through Apify datacenter proxy first. If YouTube answers "Sign in to confirm you're not a bot" or HTTP 429, the request is retried on a fresh IP with backoff. When the datacenter IPs keep getting blocked, the Actor switches to residential IPs for the rest of the run.
  • Each video is processed on its own. One failed video never stops the run, and the run summary (key-value store SUMMARY) shows the success rate and proxy statistics.

Content research: what people search for, what creators say, and what channels post.

All of these are maintained by the same developer and export flat JSON, CSV or Excel, so you can feed one tool's dataset into the next.

FAQ

Do I need a YouTube API key or account? No. The Actor uses no login, no cookies and no API key.

Which videos have no transcript? Videos whose creator turned off captions and that YouTube didn't auto-caption (often music, live news streams and very short clips). Also private, members-only, age-restricted and removed videos, and live streams that haven't started. These return a free row with noTranscriptReason.

Does it work for Shorts and live streams? Yes. Use Shorts URLs, a channel's /shorts tab, or set Channel tab to Shorts. Finished live streams (replays) work when YouTube has captions for them.

How many videos can I get from a channel? As many as the channel has. Set Max videos per channel (up to 5,000 per source). Channels are listed newest first.

Can I use it from an AI agent / MCP / n8n / Make / Zapier? Yes. Call the Actor through the Apify API, MCP server or any Apify integration with a single video URL, and read text from the first dataset item. Rows are small, flat JSON.

Is it legal to scrape YouTube transcripts? This Actor collects publicly available captions and metadata only, and no personal data beyond public channel names. Transcripts are the creators' copyrighted content. Make sure your use (e.g. research, analysis, summarization) complies with YouTube's Terms of Service and copyright law in your country. If you are unsure, consult a lawyer.

Something didn't work? Open an issue on the Issues tab with the run ID and the video URL. We usually fix things within a day.