YouTube Transcript Scraper: Captions, Timestamps, Channels
Pricing
$0.01 / 1,000 video transcripts
YouTube Transcript Scraper: Captions, Timestamps, Channels
YouTube transcripts without an account: plain text and timestamped segments for videos, Shorts, playlists and channels. Pick caption languages or fall back to the original. Every video gets a record with a clear reason when it has no captions. Trial: 0.01 USD per 1,000 transcripts until 30 Nov 2026.
Pricing
$0.01 / 1,000 video transcripts
Rating
0.0
(0)
Developer
Cozybit
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 hours ago
Last modified
Categories
Share
YouTube Transcript Scraper: captions as text and timestamped segments
Get the transcript (captions) of YouTube videos as clean text and as timestamped segments, without a YouTube account and without downloading any video:
- Any public video: paste video links, Shorts links or video IDs.
- Whole playlists and channels: paste a playlist or channel link and get the transcripts of its newest videos.
- Your language: choose the caption languages you prefer, or fall back to the video's own language.
- Subtitle files: optionally get SRT or WebVTT subtitles for video editors and players, included in the transcript price.
- Honest results: every video gets a record. When a video has no captions or cannot be read, the record says why, and you do not pay for it.
Prices include all platform costs: you pay per transcript delivered and nothing for proxies or compute.
Input
| Field | What it does | Default |
|---|---|---|
| YouTube URLs or video IDs | Video links (watch?v=, youtu.be, Shorts, live), 11-character video IDs, playlist links (playlist?list=) and channel links (@handle, /channel/UC...) | three example videos |
| Caption languages | Language codes in order of preference, for example en or pt-BR. Human-made captions win over automatic ones in the same language | en |
| Fall back to any language | When none of your languages exists, return the video's own captions instead of an error | on |
| Include timestamped segments | Return the segments list next to the plain text | on |
| Subtitle format | Choose SRT or WebVTT to add a subtitles field with the subtitle file's text, even when segments are off | none |
| Maximum videos per playlist or channel | How many of the newest videos to take from each playlist or channel link | 100 |
| Proxy configuration | Keep the default residential proxy (see Limits) | Apify residential |
Example: three videos, Spanish captions preferred, English otherwise:
{"urls": ["https://www.youtube.com/watch?v=iG9CE55wbtY", "https://youtu.be/arj7oStGLkU", "jNQXAC9IVRw"],"languages": ["es", "en"]}
Example: the 20 newest videos of a channel in German or English, text only:
{"urls": ["https://www.youtube.com/@kurzgesagt"],"maxVideosPerSource": 20,"languages": ["de", "en"],"includeSegments": false}
Output (record format v1)
One record per video:
{"video_id": "jNQXAC9IVRw","url": "https://www.youtube.com/watch?v=jNQXAC9IVRw","source_url": null,"status": "ok", "error_code": null, "error": null,"title": "Me at the zoo", "channel_name": "jawed", "channel_id": "UC4QobU6STFB0P71PMvOGN5A","description": "Microplastics are accumulating in human brains at an alarming rate\nhttps://www.youtube.com/watch?v=0PT5c1z3LL8\n\n“Nanoplastics and Human Health” with Matthew J Campen, PhD, MSPH\nhttps://www.youtube.com/watch?v=RRBN_4L09Mg\n\n00:00 Intro\n00:05 The cool thing\n00:17 End","view_count": 447000000,"thumbnail_url": "https://i.ytimg.com/vi/jNQXAC9IVRw/sddefault.jpg","published_at": "2005-04-23T20:31:52-07:00","duration_seconds": 19,"language": "en", "language_name": "English", "is_auto_generated": false,"available_languages": [{ "code": "en", "name": "English", "is_auto_generated": false },{ "code": "de", "name": "German", "is_auto_generated": false }],"segment_count": 6,"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..." }],"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","subtitles": null,"scraped_at": "2026-10-30T17:23:32.782Z"}
-
segments:startanddurationin seconds.textis all segments joined into one paragraph. -
subtitles: SRT or WebVTT text when requested andstatusisok; otherwisenull. Save the text as a.srtor.vttfile, or read it from the API. SRT example:100:00:01,200 --> 00:00:03,360All right, so here we are, in front of the elephants200:00:05,318 --> 00:00:07,974the cool thing about these guys is that they have really... -
is_auto_generated: truemeans YouTube's automatic speech recognition made the captions; expect missing punctuation and some wrong words. For some videos YouTube also offers automatic captions in another language (for example English for Japanese news); these are marked the same way. -
source_url: the playlist or channel link the video came from, ornullfor videos you entered directly. -
description,view_countandthumbnail_url: the video description, current view count and widest available thumbnail. The example view count is approximate and changes over time. Missing values arenull. -
published_at: YouTube's ISO publication date or timestamp, keeping its timezone offset when supplied. It is optional; a failed date lookup leavesnullwithout losing the transcript or changing its status. -
Field names in format v1 do not change; any future change will be announced here first.
status tells you what happened:
| status | error_code | Meaning | Charged |
|---|---|---|---|
ok | null | Transcript delivered | yes |
no_captions | no_captions | The video has no captions at all | no |
error | language_not_available | Captions exist, but not in your languages, and fallback is off | no |
error | video_unavailable | Private, deleted or non-existent video | no |
error | age_restricted | YouTube shows it only to signed-in adults; this actor never signs in | no |
error | live_stream | A live stream in progress or upcoming; captions appear after it ends | no |
error | unplayable | YouTube refuses playback, for example in members-only videos | no |
error | source_unavailable | A playlist or channel link could not be listed | no |
error | invalid_input | The entry is not a YouTube video, playlist or channel link | no |
error | bot_check, transport, parse | YouTube blocked or failed the request after all retries, or answered in an unexpected format | no |
A run summary (RUN_SUMMARY) is saved in the run's key-value store.
Use it from code
Run the actor and read the transcripts with the official Apify API clients. Get your API token in Apify Console under Settings > API & Integrations.
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("cozybit/youtube-transcript-scraper").call(run_input={"urls": ["https://www.youtube.com/watch?v=iG9CE55wbtY"],"languages": ["en"],})for video in client.dataset(run["defaultDatasetId"]).iterate_items():print(video["status"], video["title"])print(video["text"]) # the whole transcript as one plain-text paragraph
JavaScript (npm install apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });const run = await client.actor('cozybit/youtube-transcript-scraper').call({urls: ['https://www.youtube.com/watch?v=iG9CE55wbtY'],languages: ['en'],});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const video of items) console.log(video.status, video.title, video.text);
HTTP API (runs the actor and returns the records in one call; suited to small batches that finish within 5 minutes):
curl -X POST "https://api.apify.com/v2/acts/cozybit~youtube-transcript-scraper/run-sync-get-dataset-items" \-H "Authorization: Bearer <YOUR_API_TOKEN>" -H "Content-Type: application/json" \-d '{"urls": ["https://www.youtube.com/watch?v=iG9CE55wbtY"], "includeSegments": false}'
For an LLM prompt, use each record's text field (plain text, no timestamps) and skip records whose status is not ok.
Pricing
Trial price until 30 November 2026: 0.01 USD per 1,000 transcripts (the lowest price Apify allows). From 1 December 2026 this scraper costs 2.00 USD per 1,000 transcripts. Apify notifies all users before a price change.
You pay per delivered transcript; platform usage (compute and proxies) is included.
| Event | Price |
|---|---|
Transcript (status: ok) | 2.00 USD per 1,000 (0.002 USD each) |
Videos without captions, unavailable videos, errors and playlist or channel listing are free.
Worked examples:
- 10 videos: 10 x 0.002 = 0.02 USD.
- The 100 newest videos of a channel, 92 of them with captions: 92 x 0.002 = 0.184 USD.
- 5,000 videos: 10 USD.
Long videos cost the same as short ones. To cap spending, set a maximum cost per run in the run options; the actor stops cleanly when it is reached.
Free Apify plan
On the free Apify plan a run returns at most 20 videos. When the limit is reached the run finishes successfully with the status message "Free Apify plan limit reached"; everything collected so far is in the dataset. Any paid Apify plan removes the limit.
Reliability
In 44 test runs on the Apify platform with default settings (videos in six languages, manual and automatic captions, Shorts, podcasts of up to 5 hours, channel links), all 407 videos were answered correctly: 404 transcripts, 2 "no captions" and 1 private video reported as unavailable. None were lost to YouTube blocking. The median run of 10 videos took 15 seconds.
How it stays reliable: the actor reads the same caption data the YouTube app uses and asks only for the few fields it needs. When YouTube asks an IP to prove it is not a bot, the actor switches to a new IP, up to three times per video. Transcripts are fetched live on every run, never from a cache, and regular test runs notice changes on YouTube's side quickly.
Limits
- Only captions that YouTube shows publicly. The actor never signs in, never downloads video or audio and does no speech-to-text of its own; videos without captions return
no_captions. - Age-restricted and members-only videos cannot be read without signing in, so they return an error (not charged).
- Use the default residential proxy. Datacenter proxies and runs without a proxy are blocked by YouTube most of the time.
- Playlists and channels: up to 5,000 videos per link, newest first; channel links list the channel's uploads, including Shorts and past live streams.
- Up to 1,000 entries per run; the same video is processed once even if it appears several times.
- No translation: YouTube refused every automated request for machine-translated captions in our tests, so the actor returns captions only in languages the video has.
- YouTube has no official public transcript API; when YouTube changes its apps the actor may fail until it is updated.
- Transcripts are the creators' content. You are responsible for using them in line with copyright law and YouTube's terms.
Support
Report problems and feature requests on the actor's Issues tab, ideally with the run link.