YouTube Transcript Scraper avatar

YouTube Transcript Scraper

Pricing

$5.00 / 1,000 transcripts

Go to Apify Store
YouTube Transcript Scraper

YouTube Transcript Scraper

Transcripts of YouTube videos, playlists and whole channels in the language you ask for, with timestamps, SRT/VTT and video metadata. Every video gets a row that says why when there is no transcript. No login, no browser.

Pricing

$5.00 / 1,000 transcripts

Rating

0.0

(0)

Developer

Steady Scrape

Steady Scrape

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Get the transcript of any YouTube video, playlist or channel: the language you ask for, timestamps, SRT and WebVTT, and the video's metadata. Every video you ask for comes back as a row, and when there is no transcript the row says why (no_captions, age_restricted, unavailable…) instead of leaving you guessing. You pay only for rows that carry a transcript.

No login, no cookies, no browser: it calls the same API the YouTube apps use.

What you get

For each video, one row with:

  • The transcript as plain text, as timed segments (start and duration in seconds), and optionally as srt and vtt files ready to save.
  • Which track was read: language, languageName, isAutoGenerated, and availableLanguages (every caption track the video has, so you can ask again for another one).
  • The video: title, channel name and id, duration, views, likes, publish date, category, description, keywords, thumbnail.
  • status and reason: ok, no_captions, language_missing, unavailable, age_restricted, login_required, or blocked.

Input

fieldwhat it does
urlsVideos (any link shape or bare id), playlists (link or id) and channels (@handle, /channel/UC…, /c/…, /user/…).
languageCaption language code, e.g. en, es, pt-BR. pt matches pt-BR. Empty: the track YouTube shows by default.
whenLanguageMissingdefault-track (read the video's default track; the row tells which) or skip (row with status language_missing and the languages it has).
preferAutoGeneratedRead the auto-generated track even when a manual one exists in that language.
formatsAny of text, segments, srt, vtt. Default: text and segments.
maxVideosPerSourceHow many videos to take from each playlist or channel (newest first for channels). Default 100.
residentialFallbackRetry a video YouTube refused from datacenter IPs through a residential proxy. Default on.
{
"urls": ["https://www.youtube.com/watch?v=Ks-_Mh1QhMc", "https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab", "@TED"],
"language": "en",
"formats": ["text", "segments", "srt"],
"maxVideosPerSource": 50
}

Output example

{
"videoId": "jNQXAC9IVRw",
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"status": "ok",
"reason": null,
"title": "Me at the zoo",
"channelName": "jawed",
"channelId": "UC4QobU6STFB0P71PMvOGN5A",
"durationSeconds": 19,
"viewCount": 432880329,
"likeCount": 19864845,
"publishDate": "2005-04-23T20:31:52-07:00",
"category": "Film & Animation",
"description": "…",
"keywords": ["me at the zoo", "jawed karim", "first youtube video"],
"thumbnailUrl": "https://i.ytimg.com/vi/jNQXAC9IVRw/sddefault.jpg",
"isLive": false,
"requestedLanguage": "en",
"language": "en",
"languageName": "English",
"isAutoGenerated": false,
"availableLanguages": [{ "code": "en", "name": "English", "autoGenerated": false }, { "code": "de", "name": "German", "autoGenerated": false }],
"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 …",
"segments": [{ "start": 1.2, "duration": 2.16, "text": "All right, so here we are, in front of the elephants" }],
"srt": null,
"vtt": null,
"source": { "type": "video", "id": "jNQXAC9IVRw" }
}

A video without a transcript still gets its row:

{ "videoId": "hY7m5jjJ9mM", "status": "no_captions", "reason": "The video has no captions", "title": "CATS will make you LAUGH YOUR HEAD OFF - Funny CAT compilation", "availableLanguages": [], "text": null, "segments": null }

The run's SUMMARY record lists how many videos each playlist or channel gave, the rows per status, and any playlist or channel that could not be read.

Why this one

The complaints on other transcript scrapers are always the same, and each one has an answer here:

  • "Returned nothing" / "no captions found" on a video that has captions. That is usually YouTube's bot check on a datacenter IP being reported as "no captions". This Actor tells the two apart: it retries a refused video on another IP class (direct, datacenter proxy, residential proxy), and only says no_captions when YouTube itself lists no track. If every route is refused the row says blocked, uncharged.
  • "The language parameter is ignored." The requested language is honored, a short code finds the regional track, and the row states which track was actually read and which ones exist. You choose whether a missing language falls back or skips.
  • "Could not extract the video id." Every link shape works: watch?v=, youtu.be, Shorts, live, embed, mobile, music, links with playlist parameters, and bare ids.
  • Charged for failures. Only rows with a transcript are charged.
  • Playlists and channels. One line expands to up to maxVideosPerSource videos; duplicates across your list are scraped once.

Pricing

Pay per transcript delivered. Rows with any other status are free. A run of 100 videos usually takes under a minute.

Limits and notes

  • Auto-translated captions are not available through this API; the transcript comes in the languages the video has.
  • Age-restricted, private and members-only videos need a signed-in account, which this Actor does not use: they get a row with the reason.
  • Live streams in progress have no transcript until YouTube publishes the recording's captions.
  • Transcripts are provided for analysis, research, accessibility and indexing. Respect YouTube's terms and the creators' rights in how you use them.