YouTube Transcript Scraper
Pricing
Pay per event
YouTube Transcript Scraper
Extract YouTube transcripts from videos, playlists, channels or search queries. Works when other transcript scrapers return nothing. Five output formats, 100+ languages, YouTube translation.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Muhammad Ahmed
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 days ago
Last modified
Share
Extract transcripts from any YouTube video, playlist, channel, or search query — in bulk, in five formats, across 100+ languages.
Built for people who need transcripts reliably: RAG pipelines, content research, competitor monitoring, subtitle workflows, and LLM training data.
What makes it different
- It works when others return nothing. YouTube gates the public web player: caption URLs scraped from the watch page now return HTTP 200 with an empty body. This Actor drives YouTube's mobile app API instead and falls back across three clients, so it keeps returning transcripts where watch-page scrapers quietly fail.
- Bulk input, not one video at a time. Paste a channel URL, a playlist, an
@handle, orsearch:your queryand it expands to every video, with paging. - Translation built in. Pull a transcript in one language and have YouTube translate it to another in the same run.
- Five output formats. Plain text, timed JSON segments, SRT, WebVTT, or timestamped Markdown (ideal for chunking into a vector store).
- You are never charged for a video that fails. Charging happens only after a transcript is actually in hand.
Input
| Field | Type | Description |
|---|---|---|
urls | array | Video URLs/IDs, playlist URLs, channel URLs or @handles, and search:<query> terms |
languages | array | Preferred caption languages, best first (default ["en"]) |
fallbackToAnyLanguage | boolean | Use any available track when no preferred language matches (default true) |
preferManualCaptions | boolean | Prefer human-written captions over auto-generated (default true) |
translateTo | string | Translate captions to this language code via YouTube's translator |
outputFormat | string | text, segments, srt, vtt, or markdown |
maxVideos | integer | Hard cap on videos processed — protects you from an accidental whole-channel run |
aiEnrichments | array | Optional AI summary/key points/chapters — see AI enrichment below |
concurrency | integer | Parallel video fetches (default 5) |
proxyConfiguration | object | Recommended for large runs — YouTube rate-limits datacenter IPs |
Example
{"urls": ["https://www.youtube.com/watch?v=aircAruvnKk","https://www.youtube.com/@3blue1brown","search:retrieval augmented generation"],"languages": ["en"],"outputFormat": "markdown","maxVideos": 50}
Output
One dataset item per video:
{"videoId": "aircAruvnKk","title": "But what is a neural network? | Deep learning chapter 1","author": "3Blue1Brown","channelId": "UCYO_jab_esuFRV4b17AJtAw","url": "https://www.youtube.com/watch?v=aircAruvnKk","lengthSeconds": 1120,"viewCount": 23914996,"thumbnail": "https://i.ytimg.com/vi/aircAruvnKk/sddefault.jpg","language": "en","isAutoGenerated": false,"availableLanguages": ["ar", "en", "es", "..."],"segmentCount": 286,"characterCount": 18145,"transcript": "This is a 3. It's sloppily written and rendered at an extremely low resolution...","scrapedAt": "2026-08-16T16:52:20.630Z"}
Videos that cannot be processed produce an item with videoId, url, and error — so a failed video is visible in your results instead of silently missing.
Notes and limits
- Videos with captions disabled cannot be transcribed. There is no caption track to fetch. The Actor reports this per video rather than failing the run.
- Private, deleted, and age-restricted videos are reported as errors with YouTube's reason.
- Residential proxy is required, and it is the default. YouTube blocks datacenter IP ranges outright with "Sign in to confirm you're not a bot" — measured on Apify's own servers, 4 of 5 videos failed without one and 4 of 4 succeeded with one. Leave
proxyConfigurationon its residential default unless you are running from an IP you know YouTube trusts.
AI enrichment (optional, off by default)
The Actor can also generate a summary, key points and timestamped chapters from each transcript. This requires the Actor operator to configure an LLM credential; if none is set, runs return transcripts only and log a warning — they never fail, and you are never charged for an enrichment that did not happen.
Leave aiEnrichments empty unless the listing states AI is enabled.
Configuration (Actor operator)
AI enrichment reaches a model one of two ways. Whichever credential is present wins, preferring OpenRouter because it needs no provider account.
| Variable | Purpose |
|---|---|
APIFY_TOKEN | Default route. Goes through Apify's OpenRouter Actor — no second account, tokens billed as Apify platform usage. Set automatically in every run, but needs a paid Apify plan (Free returns HTTP 429). |
OPENROUTER_API_KEY | Optional override — calls openrouter.ai directly, billed to an OpenRouter balance. Takes precedence if set. |
ANTHROPIC_API_KEY | Optional override — calls the Anthropic API with your own key. |
LLM_PROVIDER | Force openrouter or anthropic instead of auto-detecting. |
LLM_MODEL | Model id. Defaults to deepseek/deepseek-v4-flash (OpenRouter) or claude-haiku-4-5 (Anthropic). |
LLM_TIMEOUT_MS | Request timeout, default 180000. |
Credential precedence is OPENROUTER_API_KEY → APIFY_TOKEN → ANTHROPIC_API_KEY. With none
of them available the Actor logs a warning and returns transcripts only — it never fails a run.
See PRICING.md for model costs and the per-character charging model.
Local development
npm installnpm run buildnode dist/main.js # reads storage/key_value_stores/default/INPUT.json