YouTube Transcript Scraper - Bulk Subtitles to Text, No Browser avatar

YouTube Transcript Scraper - Bulk Subtitles to Text, No Browser

Pricing

$5.00 / 1,000 transcript delivereds

Go to Apify Store
YouTube Transcript Scraper - Bulk Subtitles to Text, No Browser

YouTube Transcript Scraper - Bulk Subtitles to Text, No Browser

Clean transcript text with timestamped segments, language, auto-generated flag, title and channel for any list of YouTube videos, Shorts or bare IDs. No headless browser; proxy configuration for rate-limited IPs. Charged only for videos that return a transcript.

Pricing

$5.00 / 1,000 transcript delivereds

Rating

0.0

(0)

Developer

Lee Kung

Lee Kung

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

21 days ago

Last modified

Categories

Share

YouTube Transcript Scraper - subtitles to text with timestamps, from Python or the API

Paste a list of YouTube videos and get one row per video back: the full transcript as clean text, the timestamped caption lines, the language you got, whether it was auto-generated, and the video's title and channel, from watch URLs, Shorts, youtu.be links or bare video IDs. Call it from Python, JavaScript, cURL or an AI agent, or export a CSV. No YouTube Data API key and no headless browser.

  • Charged per transcript, nothing else. Captions disabled, a private or removed video, or a request YouTube keeps blocking: you get a row with a status, and it costs nothing.
  • Language fallback that makes sense. Your languages in your order, manually created captions before auto-generated ones, and optional translation through YouTube's own translation.
  • Bounded retries. YouTube blocks datacenter IPs, so the Actor rotates residential proxy sessions up to maxRetries times, then reports the video as blocked.
  • Reliability, measured on our own runs. 128 of 128 runs in the last 30 days succeeded (our account's run history, read 2026-10-02). These are our own test and monitoring runs, not customer runs.

What data you get

  • video_id, url - the video
  • status - ok, no_transcript, captions_disabled, unavailable, blocked or error
  • text - the whole transcript as one string
  • segments[] - every caption line with start, duration (seconds) and text (optional)
  • language, source_language, is_generated - what you got and where it came from
  • available_languages[] - every transcript YouTube offers for the video (language, code, generated)
  • word_count, segment_count, duration_seconds - size of the transcript
  • title, channel, channel_url, thumbnail - public video metadata (optional)
  • error - the reason on rows that are not ok; translation_note if translation was not possible

Use cases

  • Feed videos to an LLM or RAG pipeline - clean text for summaries, embeddings or question answering.
  • Notes from lectures, talks and podcasts - search a long video instead of rewatching it.
  • Quote finding with timestamps - segments give the second each line was said.
  • Topic and keyword research - what a set of videos talks about, in their own words.
  • Translation work - the original captions or YouTube's translation as a starting text.

How to use it (quick start)

  1. Open the Actor in Apify Console (you need an Apify account).
  2. Paste your video URLs or IDs into Video URLs or IDs, one per line, and set your preferred languages.
  3. Click Start. When the run finishes, open the Dataset tab and export as JSON, CSV or Excel.

To call it from your own code, skip to Use it from code.

Input

FieldWhat it doesDefault
videoUrlsWatch, Shorts, youtu.be, embed or live URLs, or 11-character IDs (required)one example video
languagesLanguage codes in order of preference, e.g. en, en-US, de, es["en"]
allowAutoGeneratedFall back to automatic captions, then to any available transcripttrue
translateToTranslate with YouTube's translation; empty keeps the original""
includeSegmentsAdd the timestamped segments arraytrue
includeMetadataAdd title, channel, channel URL and thumbnailtrue
concurrencyVideos processed in parallel (1-20)5
maxRetriesFresh proxy sessions to try per video when blocked (1-10)4
proxyConfigurationProxy; YouTube blocks datacenter IPsApify residential

One video, English:

{ "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"] }

Any URL form, German first, then English (all three are the same video, so this returns one row):

{
"videoUrls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"https://youtu.be/dQw4w9WgXcQ",
"dQw4w9WgXcQ"
],
"languages": ["de", "en"]
}

Only human-made captions, translated to Spanish:

{
"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"languages": ["en"],
"allowAutoGenerated": false,
"translateTo": "es"
}

Output

A real row from a run with the default input (run S8SrhkA8w19WyC7gj, 2026-10-02 UTC; text and segments shortened, available_languages trimmed from 6 entries to 2):

{
"video_id": "dQw4w9WgXcQ",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"available_languages": [
{ "language": "English", "code": "en", "generated": false },
{ "language": "English (auto-generated)", "code": "en", "generated": true }
],
"status": "ok",
"language": "en",
"source_language": "en",
"is_generated": false,
"segment_count": 61,
"duration_seconds": 211.3,
"word_count": 487,
"text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ ...",
"segments": [
{ "start": 1.36, "duration": 1.68, "text": "[♪♪♪]" },
{ "start": 18.64, "duration": 3.24, "text": "♪ We're no strangers to love ♪" }
],
"title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
"channel": "Rick Astley",
"channel_url": "https://www.youtube.com/@RickAstleyYT",
"thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg"
}
FieldMeaning
statusok means a transcript was returned; any other value says why not
textall caption lines joined with spaces
language / source_languagelanguage returned / language of the source track (differ after translation)
duration_secondsend of the last caption line, which can be shorter than the video

Use it with AI agents (MCP)

Apify's hosted MCP server exposes this Actor as a tool to an MCP client. Add it with the URL below and the header Authorization: Bearer <YOUR_APIFY_TOKEN>:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=actors,docs,leekung125/youtube-transcript-scraper",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Clients that support it can also sign in through the browser instead of pasting a token. Example prompt:

Get the English transcript of https://www.youtube.com/watch?v=dQw4w9WgXcQ and summarize it in five bullet points.

Use it from code (Python, JavaScript, cURL)

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("leekung125/youtube-transcript-scraper").call(
run_input={
"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"languages": ["en"],
}
)
for row in client.dataset(run.default_dataset_id).list_items().items:
print(row["status"], row.get("title"))

JavaScript (npm i apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('leekung125/youtube-transcript-scraper').call({
videoUrls: ['https://www.youtube.com/watch?v=dQw4w9WgXcQ'],
languages: ['en'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

cURL (runs the Actor and returns the rows in one request):

curl -X POST "https://api.apify.com/v2/acts/leekung125~youtube-transcript-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"], "languages": ["en"]}'

Schedules, webhooks and integrations (Make, Zapier, n8n, Google Sheets) work with this Actor as with any Apify Actor.

Pricing

$0.005 per transcript delivered - that is $5.00 per 1,000 transcripts. The event is charged once per video whose row has status: "ok". You pay only this event price; there is no separate charge to you for compute or other platform usage on this Actor.

Transcripts deliveredCost
1,0001,000 x $0.005 = $5.00
10,00010,000 x $0.005 = $50.00
100,000100,000 x $0.005 = $500.00

Never charged: rows with no_transcript, captions_disabled, unavailable, blocked or error, and retries. A video listed twice is fetched once. If the run reaches its maximum charge limit, the Actor stops starting new videos.

Limits and honesty notes

  • Transcripts are what YouTube provides: manually uploaded captions when they exist, otherwise automatic captions, whose accuracy depends on the audio. is_generated tells you which you got.
  • Output is JSON rows (exportable to CSV or Excel), not SRT or VTT files.
  • Live streams without captions, members-only and age-restricted videos may have no transcript.
  • With allowAutoGenerated: true and none of your languages available, you get the first transcript YouTube lists, in its own language; check language. Set it to false for human-made captions in your languages only.
  • If a caption track cannot be translated, you get the original language and a translation_note.
  • Title and channel come from YouTube's public oEmbed endpoint, best effort; if that call fails the row lacks them. blocked rows carry no metadata.
  • A video YouTube blocks on every retry comes back blocked, uncharged. Run it later or raise maxRetries (max 10).
  • Entries that are not a YouTube URL or 11-character ID are skipped. If no entry is valid, the run fails with a message saying so.
  • Public data only. No login; it reads captions and public oEmbed metadata.

FAQ

Do I need a YouTube API key? No YouTube API key. You need an Apify account, and an Apify token to call it from code.

Is it legal to scrape YouTube transcripts? It reads only public captions and metadata, with no login. You are responsible for lawful use and for following YouTube's terms, including copyright in the transcripts. Do not resell personal data.

Can I get SRT or VTT subtitle files? Not directly. segments holds start, duration and text for every caption line, which is all an SRT or VTT file needs if you write one yourself.

Can I export to CSV or Excel? Yes, from the run's Dataset tab (CSV, Excel, JSON and more), or through the API.

Can I run it on a schedule? Yes, with Apify Schedules, like any Actor.

Can I use it from an AI agent or MCP? Yes, through Apify's hosted MCP server. See Use it with AI agents (MCP).

Why did I get fewer rows than I asked for? Duplicate links to the same video are merged into one row, entries that are not a YouTube URL or ID are skipped, and if the run reaches its maximum charge limit the Actor stops starting new videos.

What happens when a video has no transcript or YouTube blocks the request? You still get a row (no_transcript, captions_disabled, unavailable, or blocked after maxRetries proxy sessions) with the reason in error. None of these are charged.

What is charged? Only rows with status: "ok", at $0.005 each. See Pricing.

ActorWhat it does
YouTube Channel TranscriptsEvery video of a channel or playlist, each with its transcript
YouTube Search ScraperA keyword in, ranked YouTube video rows out
Google Play Reviews ScraperReviews of Android apps from Google Play
App Store Reviews ScraperReviews of apps from the Apple App Store, by app and country
Google Trends ScraperGoogle Trends interest over time, by region, related queries and topics

Support

Open an issue on the Issues tab with the run ID and your input; we read every issue.