YouTube Transcript Scraper - YouTube Captions API. Returns YouTube video transcripts as text, timed segments and AI chunks, from videos, channels, playlists or searches. Price, example input and output, and FAQ: YouTube Transcript Scraper on the Aurelix tools site. Run it on the Apify Store: apify.com/aurelix/youtube-transcript-scraper.
A small, runnable example for YouTube Transcript Scraper, an Apify Actor by Aurelix.
YouTube Transcript Scraper turns YouTube videos into clean transcripts: give video links, channels (latest videos), playlists or search terms, and get one row per video with the full transcript as plain text, timestamped caption segments, ready-made chunks for RAG and embeddings, chapters, the caption language and whether it is auto-generated, plus the title, channel, publish date, duration and views. Choose your languages in order of preference with an automatic fallback. AI agents can call it through Apify's MCP server. The $0.20 residential retry is off by default.
- One video in seconds: plain HTTP, no browser to start.
- Channels, playlists and search terms in the same run as single videos.
- AI-ready chunks with start and end times and a timestamped link for citations.
- AI developers loading a channel's videos into a vector database for RAG
- Researchers and analysts mining talks, lectures and interviews as text
- Marketers and SEO writers turning videos into articles, summaries and quotes
- AI agents that need a video's transcript through MCP
This is the youtube-channel-latest-transcripts input used in main.py:
{
"channels": [
"https://www.youtube.com/@veritasium"
],
"maxVideosPerSource": 20,
"languages": [
"en"
]
}Every input field is documented on the Store page.
- Get an Apify API token from Apify Console (Settings, API & Integrations).
- Install and run:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export APIFY_TOKEN=your_token_here
python main.pyThe script starts a run of aurelix/youtube-transcript-scraper, prints a few fields from the first results and writes every result to results.csv. Lists and nested objects are stored in the CSV as JSON text. Each run is billed to your Apify account (see Pricing below).
One record as returned by a real run (long text is shortened):
{
"video_id": "jNQXAC9IVRw",
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"title": "Me at the zoo",
"channel_name": "jawed",
"channel_id": "UC4QobU6STFB0P71PMvOGN5A",
"channel_url": "https://www.youtube.com/channel/UC4QobU6STFB0P71PMvOGN5A",
"published_at": "2005-04-24T03:31:52Z",
"duration_seconds": 19,
"view_count": 447765657,
"category": "Film & Animation",
"is_live_content": false,
"language": "en",
"language_name": "English",
"is_auto_generated": false,
"language_fallback": false,
"available_languages": [
{
"language": "en",
"is_auto_generated": false
},
{
"language": "de",
"is_auto_generated": false
}
],
"transcript_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",
"word_count": 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..."
},
{
"start": 7.974,
"end": 12.616,
"text": "really really long trunks"
},
"... [3 more]"
],
"chapters": [
{
"title": "Intro",
"start": 0,
"end": 5
},
{
"title": "The cool thing",
"start": 5,
"end": 17
},
{
"title": "End",
"start": 17,
"end": 19
}
],
"chunks": [
{
"index": 0,
"start": 1.2,
"end": 18.881,
"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",
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw&t=1s"
}
],
"source_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"scraped_at": "2026-11-04T19:33:36Z"
}main.py writes results.csv with the csv module. You can also download any run's results directly:
https://api.apify.com/v2/datasets/<datasetId>/items?format=csv&clean=true
Send your token in an Authorization: Bearer <token> header (or ?token=) if the dataset is not readable without one. Other formats: format=json, format=xlsx.
- Simplest: use Apify's Google Sheets integration on the Actor or a saved task, so each run's results land in a sheet with no token in the sheet itself.
- Quick pull of one run:
=IMPORTDATA("https://api.apify.com/v2/datasets/<datasetId>/items?format=csv&clean=true"). This only works without a token if your account lets anyone with the dataset ID read it. Do not paste an API token into a sheet formula: anyone who can view or copy the sheet can read it and use your account.
- Apify node: choose "Run an Actor", enter
aurelix/youtube-transcript-scraper, paste the input above, then read the run's dataset items. - HTTP Request node:
POST https://api.apify.com/v2/acts/aurelix~youtube-transcript-scraper/run-sync-get-dataset-itemswith headerAuthorization: Bearer <token>(stored as an n8n credential) and the input as the JSON body. The response is the list of results. This endpoint waits for the run to finish, so for large runs start the run asynchronously and fetch the dataset when it ends.
- Only videos that have captions can be returned; there is no speech-to-text for videos without them.
- Private, removed, age-restricted, members-only, live and upcoming videos are skipped (they need a login or have no final captions).
- No translation: captions come in the languages the video has.
- Channels are read from their Videos tab (newest first); Shorts and live tabs are not included unless you give those videos directly.
- Search returns YouTube's video results for the term in relevance order, without Shorts, channels or playlists.
- A real browser is needed, so a run starts in about 10 to 20 seconds and reads a video every few seconds.
- Chapters come from description timestamps only, not YouTube's auto-generated chapters.
- YouTube can block cloud IPs; the run retries on fresh datacenter sessions, and if its first 3 page loads (or its first 60 seconds) are all blocked or time out it stops at once with a BLOCKED status (only the start fee is charged). Turn on 'residentialFallback' to continue on one residential session for up to 20 more videos.
At the time of writing:
Pay per event: you pay only for what the run returns, plus a small start fee.
| Event | Free plan | Paid plans (Bronze, Silver, Gold) |
|---|---|---|
transcript-result |
$2.50 per 1,000 videos | $2.25 per 1,000 videos |
residential-retry |
$0.20 per run (only with residentialFallback on, when YouTube blocks the datacenter IP) | $0.20 per run (only with residentialFallback on, when YouTube blocks the datacenter IP) |
apify-actor-start |
$0.02 per GB of run memory ($0.04 per run at the 2 GB default) | $0.02 per GB of run memory ($0.04 per run at the 2 GB default) |
$2.50 per 1,000 videos ($2.25 on paid Apify plans); the start fee is $0.04 per run at the default 2 GB of memory (Apify charges $0.02 per GB); the $0.20 residential retry is off by default. Videos skipped for missing captions or because they are private, removed, age-restricted, members-only or live are never charged. The residential-retry fee applies only if you turn on 'residentialFallback': at most once per run, and only when YouTube blocked every datacenter session, the run switched to a residential IP and that IP returned at least one transcript.
Check the Store page for current prices.
- Actor: https://apify.com/aurelix/youtube-transcript-scraper
- Questions, bugs and feature requests: the Issues tab on the Store page.
The example code in this repository is released under the MIT licence (see LICENSE). The Actor itself runs on Apify and is billed through your Apify account.