YouTube Transcript Scraper: Captions & Subtitles to Text
Pricing
$4.00 / 1,000 transcript returneds
YouTube Transcript Scraper: Captions & Subtitles to Text
Get the transcript of any YouTube video, Short, channel or playlist as timestamped caption lines and plain text, with title, channel, views and date. $4 per 1,000 transcripts, proxy included; videos without captions are free.
Pricing
$4.00 / 1,000 transcript returneds
Rating
0.0
(0)
Developer
Changefeeds Tools
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
1
Monthly active users
20 days ago
Last modified
Features
Share
- What you get: the full transcript of each YouTube video, as timestamped caption lines and as one plain-text string, with title, channel, duration, views and publish date.
- Works on: video, Shorts, channel and playlist links; manual and auto-generated captions in any language the video has. No login, no API key.
- Price: $4 per 1,000 transcripts, proxy included. Videos with no captions are free.
Sample output
The prefilled input (two videos), run on 2026-10-23:
| video_id | title | channel_name | duration_seconds | language | is_generated | segment_count | word_count |
|---|---|---|---|---|---|---|---|
| dQw4w9WgXcQ | Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster) | Rick Astley | 213 | en | false | 61 | 366 |
| jNQXAC9IVRw | Me at the zoo | jawed | 19 | en | false | 6 | 39 |
One row in full, with segments cut to three entries:
{"type": "transcript","video_id": "jNQXAC9IVRw","url": "https://www.youtube.com/watch?v=jNQXAC9IVRw","title": "Me at the zoo","channel_name": "jawed","channel_id": "UC4QobU6STFB0P71PMvOGN5A","duration_seconds": 19,"view_count": 445947210,"published_at": "2005-04-23T20:31:52-07:00","language": "en","language_name": "English","is_generated": false,"requested_language_matched": true,"available_languages": [{ "language": "en", "name": "English", "is_generated": false },{ "language": "de", "name": "German", "is_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","segments": [{ "start": 1.2, "duration": 2.16, "text": "All right, so here we are, in front of the elephants" },{ "start": 5.318, "duration": 2.656, "text": "the cool thing about these guys is that they have really..." },{ "start": 7.974, "duration": 4.642, "text": "really really long trunks" }],"word_count": 39,"segment_count": 6,"thumbnail": "https://i.ytimg.com/vi/jNQXAC9IVRw/hqdefault.jpg","fetched_at": "2026-10-23T03:49:32.053Z"}
How to run in 30 seconds
- Click Try for free. The input already holds two video links.
- Click Start. Our test run of that input took 16 seconds and cost $0.008 (two transcripts).
- Open the Output tab, or export the dataset as JSON, CSV or Excel.
For your own videos, replace the links in Videos. You can paste watch URLs,
youtu.be links, Shorts, bare video ids, a channel URL (https://www.youtube.com/@name)
or a playlist URL. Set Preferred language if you want a track other than English.
Pricing
- $0.004 per transcript ($4 per 1,000), Apify residential proxy included.
- Free: status rows for videos with no captions, or that are private, age-restricted, removed, blocked or not YouTube links.
- The run stops cleanly at the maximum total charge you set and never fetches a
video it could not bill within that limit. If a run delivers nothing, it
leaves one free
run_inforow explaining why.
FAQ
Can I feed the transcript to ChatGPT, Claude or another LLM?
Yes, that is the main use. Take transcript_text (one clean paragraph), or turn
on Timestamps in plain text if you want the model to cite times.
Does it work for Shorts and live streams?
Shorts, yes, when they have captions. Live streams usually get captions only
after they end; until then they return no_captions.
Can I get SRT or VTT subtitle files?
Not directly. The segments array has everything an SRT needs (start,
duration, text) and converts in a few lines of code.
Does it download the video or audio? No. It reads only the caption text and the video's public metadata.
How fast is it? Three videos run in parallel. In our tests a transcript took 1 to 2 seconds of run time, including a 3.5-hour video with 5,700+ caption lines; ten mixed videos took about 8 seconds. Add the platform start-up: the 2-video prefill run took 16 seconds end to end, 8 of them inside the actor.
Is this allowed? It reads publicly available captions the way YouTube's own apps do, without signing in. You are responsible for how you use the transcripts (copyright and YouTube's terms apply to the content).
Limits
- Only videos that have captions. There is no speech-to-text: a video with
neither manual nor auto-generated captions gets a free
no_captionsrow. - YouTube can block some requests, especially at high volume. Blocked
videos come back as free
blockedrows, never as empty transcripts. They are retried through two fresh residential proxy IPs first. - Channel and playlist URLs cover the first page YouTube lists: up to 30 of a channel's latest regular uploads (not Shorts or live streams) or a playlist's first videos. For more, list the video URLs directly.
- Age-restricted and private videos need a signed-in account and are not supported. The actor does not machine-translate.
- YouTube can change its caption endpoints without notice. If that happens, affected videos fail as free rows until the actor is updated.
Input reference
| Field | Default | Notes |
|---|---|---|
videos | required | Watch URLs, youtu.be links, /shorts/, /live/, /embed/ URLs or bare 11-character ids. A channel URL (/@name, /channel/UC…) adds its latest uploads; a playlist URL (/playlist?list=…) adds its first videos. Duplicates are fetched once. |
language | en | Preferred caption language (en, es, de, pt-BR, ja…). See "Which caption track?" below. |
outputFormat | both | segments (timestamped lines), text (one string), or both. |
includeTimestampsInText | false | Write the text as [hh:mm:ss] line rows instead of one paragraph. |
includeDescription | false | Add the video description to each row. |
maxVideos | 1000 | Cap on videos per run (after expanding channels and playlists). |
maxVideosPerChannel | 10 | For channel and playlist URLs: how many videos to take, up to 30. |
proxyConfiguration | Apify residential | YouTube bot-checks cloud IPs, so requests go through residential proxy by default. Included in the price. |
Spanish transcripts with timestamps, from a video and the first two videos of a playlist:
{"videos": ["https://www.youtube.com/watch?v=kJQP7kiw5Fk","https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab"],"language": "es","maxVideosPerChannel": 2,"outputFormat": "text","includeTimestampsInText": true}
With includeTimestampsInText: true the text looks like this:
[00:00:10] El elemento fundamental y raíz de todo el álgebra lineal es el vector.
Output reference
startanddurationare seconds (millisecond precision). Auto-generated captions often overlap the next line; the values are YouTube's own.is_generated: truemeans YouTube's automatic speech recognition: no punctuation or capitals, and occasional wrong words.published_atis best effort; it isnullon the rare video where YouTube does not report it.- Rows are written as each video finishes, so their order can differ from the
input order. A run summary (counts per status, HTTP requests) is saved as
OUTPUTin the key-value store.
Videos without a transcript get a free video row instead:
{"type": "video","input": "https://www.youtube.com/watch?v=EColTNIbOko","video_id": "EColTNIbOko","url": "https://www.youtube.com/watch?v=EColTNIbOko","status": "no_captions","error": "This video has no captions (manual or auto-generated).","title": "Forests from Above (No Sound) — 10 Hours Screensaver of 4K UHD Drone Aerials","available_languages": [],"fetched_at": "2026-09-30T04:34:22.976Z"}
status | Meaning |
|---|---|
no_captions | The video has no manual or auto-generated captions (common for music-only, silent and live videos). |
unavailable | Removed, never existed, members-only, region-blocked, or a premiere that has not started. |
private | The video is private. |
age_restricted | YouTube requires a signed-in adult account; this actor does not sign in. |
blocked | YouTube refused the request (bot check or rate limit) even after fresh proxy IPs. Try again later. |
invalid | The input is not a YouTube video, channel or playlist link. |
error | Anything else; the error field has the details. |
Which caption track?
For language: "en" the actor takes, in order: a manual English track (exact
code first, so en before en-GB), then the auto-generated English track. If
the video has no English track at all, it returns the first manual track in
another language (or the first track) and sets
requested_language_matched: falseavailable_languages.
Troubleshooting: youtube-transcript-api RequestBlocked / IpBlocked
If you run the open-source youtube-transcript-api
on a cloud server and it works on your laptop but throws RequestBlocked or
IpBlocked in production, the cause is YouTube's IP-based bot detection, not
your code.
Why it happens
YouTube treats requests from AWS, GCP, Azure, Railway, Heroku and other
datacenter ranges far more aggressively than residential ISP ranges. The
library's own README says: "YouTube has started blocking most IPs that are
known to belong to cloud providers (like AWS, Google Cloud Platform, Azure,
etc.), which means you will most likely run into RequestBlocked or
IpBlocked exceptions when deploying your code to any cloud solutions."
Free fixes
- Add retries and backoff, and cache results so you never re-fetch a transcript you already have.
- Route through rotating residential proxies. The library ships proxy support
via
youtube_transcript_api.proxies:
from youtube_transcript_api import YouTubeTranscriptApifrom youtube_transcript_api.proxies import GenericProxyConfigytt_api = YouTubeTranscriptApi(proxy_config=GenericProxyConfig(http_url="http://user:pass@your-proxy.org:port",https_url="https://user:pass@your-proxy.org:port",))
- Space out requests to one video or channel, and re-test whenever YouTube adjusts its detection.
What this actor does about it
It uses residential proxy by default, rotates IPs on any block and retries through fresh proxies. Blocked, private and caption-less videos are not charged.