YouTube Transcript Scraper: Captions, Timestamps, Channels avatar

YouTube Transcript Scraper: Captions, Timestamps, Channels

Pricing

$0.01 / 1,000 video transcripts

Go to Apify Store
YouTube Transcript Scraper: Captions, Timestamps, Channels

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

Cozybit

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

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

FieldWhat it doesDefault
YouTube URLs or video IDsVideo 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 languagesLanguage codes in order of preference, for example en or pt-BR. Human-made captions win over automatic ones in the same languageen
Fall back to any languageWhen none of your languages exists, return the video's own captions instead of an erroron
Include timestamped segmentsReturn the segments list next to the plain texton
Subtitle formatChoose SRT or WebVTT to add a subtitles field with the subtitle file's text, even when segments are offnone
Maximum videos per playlist or channelHow many of the newest videos to take from each playlist or channel link100
Proxy configurationKeep 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: start and duration in seconds. text is all segments joined into one paragraph.

  • subtitles: SRT or WebVTT text when requested and status is ok; otherwise null. Save the text as a .srt or .vtt file, or read it from the API. SRT example:

    1
    00:00:01,200 --> 00:00:03,360
    All right, so here we are, in front of the elephants
    2
    00:00:05,318 --> 00:00:07,974
    the cool thing about these guys is that they have really...
  • is_auto_generated: true means 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, or null for videos you entered directly.

  • description, view_count and thumbnail_url: the video description, current view count and widest available thumbnail. The example view count is approximate and changes over time. Missing values are null.

  • published_at: YouTube's ISO publication date or timestamp, keeping its timezone offset when supplied. It is optional; a failed date lookup leaves null without 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:

statuserror_codeMeaningCharged
oknullTranscript deliveredyes
no_captionsno_captionsThe video has no captions at allno
errorlanguage_not_availableCaptions exist, but not in your languages, and fallback is offno
errorvideo_unavailablePrivate, deleted or non-existent videono
errorage_restrictedYouTube shows it only to signed-in adults; this actor never signs inno
errorlive_streamA live stream in progress or upcoming; captions appear after it endsno
errorunplayableYouTube refuses playback, for example in members-only videosno
errorsource_unavailableA playlist or channel link could not be listedno
errorinvalid_inputThe entry is not a YouTube video, playlist or channel linkno
errorbot_check, transport, parseYouTube blocked or failed the request after all retries, or answered in an unexpected formatno

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 ApifyClient
client = 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.

EventPrice
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.