YouTube Transcript Scraper — Subtitles & Captions API
Pricing
from $1.20 / 1,000 transcripts
YouTube Transcript Scraper — Subtitles & Captions API
Scrape YouTube transcripts, subtitles and captions from videos, Shorts, channels, playlists and search. Any language with fallback; text, timestamps, SRT, VTT or chunks for AI, plus title, views, likes, date and channel. Works with MCP, n8n and Make. No captions, no charge.
Pricing
from $1.20 / 1,000 transcripts
Rating
0.0
(0)
Developer
Anuar Bakty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
Scrape the transcript of any YouTube video, Short, channel, playlist or search, with the video's details in the same row. Paste links in any form, pick your languages, and get clean text, timestamped segments, paragraphs, chunks for AI, SRT, VTT or XML. You pay only for transcripts delivered: videos without captions, private or removed videos and blocked requests are free rows, and there is no start fee.
What does YouTube Transcript Scraper do?
- Takes every kind of YouTube link. Videos (
watch?v=,youtu.be,/live/,/embed/, mobile and music links, bare ids), Shorts, channels (@handle,/channel/UC…,/c/,/user/), channel tabs (/shorts,/streams), playlists, search pages and plain search words — all in one list. - Gets the captions you ask for. Author captions or YouTube's auto-generated ones, in your languages in order of preference, with a fallback to the language spoken in the video. Each row says which language and kind it got and why.
- Returns the formats you need. Timestamped segments, one plain text string, readable paragraphs, chunks for AI with a link to their second of the video,
[1:23]-style timestamped text, SRT, VTT and XML, with[Music]-style labels removed and'turned back into characters. Word-level timestamps for auto-generated captions. Optional.srt,.vttand.txtfiles with download links. - Adds the video details. Title, channel, @handle, channel avatar, subscribers, exact publish time, duration, views, likes, comment count, category, tags, description, thumbnail, Shorts and live flags.
- Reads 8 videos at a time and moves on to a fresh address by itself whenever YouTube refuses one.
- Explains every video it could not transcribe in a free row with a code (
NO_CAPTIONS,LANGUAGE_NOT_FOUND,PRIVATE,AGE_RESTRICTED…), a plain-English message, the languages the video does have, and whether running it again may help. - Runs inputs made for other transcript Actors. Field names of the most used ones (
youtube_url,videoUrls,startUrls,channel_url,max_videos,transcript_type,output_formats,language…) are read as they are, so a saved input or an n8n flow keeps working.
What YouTube data can you extract?
| Group | Fields |
|---|---|
| Transcript | transcript (lines with start, duration, end, text, optional words), text, paragraphs, chunks, timestampedText, srt, vtt, xml, fileUrls, segmentCount |
| Language | language, languageName, captionType (manual / auto), isAutoGenerated, languageMatch (requested / fallback / original / all), availableLanguages, requestedLanguages |
| Video | videoId, url, title, description, keywords, category, thumbnailUrl, durationSeconds, duration, publishedAt, publishDate, isShort, isLive, wasLive, isUnlisted, isFamilySafe |
| Engagement | viewCount, likeCount, commentCount |
| Channel | channelName, channelId, channelUrl, channelHandle, channelThumbnailUrl, subscriberCount |
| Run | status, errorCode, message, retryable, inputType, input, position, scrapedAt, runTag |
What can you use YouTube transcripts for?
- AI and RAG. Feed lectures, interviews and product videos to ChatGPT, Claude or a vector database; the timestamps let an answer link to the exact second.
- Content research. Read what a channel says across its last 50 videos without watching them: health channels, clinics, physical therapists, software tutorials, conference talks.
- Subtitles for editing. SRT and VTT files ready for Premiere, DaVinci Resolve, CapCut or a web player.
- SEO and repurposing. Turn videos into articles, show notes, summaries and quotes.
- Monitoring. Schedule a run on a channel with "published after: 1 day" to get each new video's transcript.
- Accessibility and translation work. See which languages a channel already offers, for free, before ordering captions.
How to scrape YouTube video transcripts
- Paste one or more links or video ids into YouTube links or video ids, or type Search words.
- Set Languages (default
en; the original language is taken when none of yours exists). - Choose Transcript formats and, for channels and searches, Videos per channel tab, playlist or search.
- Click Start. Each video becomes one row; download it as JSON, CSV, Excel or HTML, or read it through the API.
One video
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"] }
Many videos at once, with SRT
{"urls": ["https://youtu.be/arj7oStGLkU", "https://www.youtube.com/shorts/eW5Oi91m4SY", "jNQXAC9IVRw"],"outputFormats": ["segments", "text", "srt"]}
Spanish first, then English, author captions only
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "languages": ["es", "en"], "captionType": "manualOnly" }
The last 30 days of a channel, videos and Shorts
{ "urls": ["https://www.youtube.com/@TED"], "channelTabs": ["videos", "shorts"], "publishedAfter": "30 days", "maxVideosPerSource": 0 }
A playlist
{ "urls": ["https://www.youtube.com/playlist?list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo"], "maxVideosPerSource": 100 }
A search, this week only
{ "searchTerms": ["physical therapy after knee replacement"], "publishedAfter": "7 days", "maxVideosPerSource": 20 }
Chunks for ChatGPT, Claude or a vector database
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "outputFormats": ["chunks"], "chunkWords": 200 }
Each chunk comes with start, end, wordCount and a url that opens the video at that second, so an AI answer can cite the moment it came from.
SRT, VTT and TXT subtitle files to download
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "saveFiles": true }
The row gets fileUrls with links to the .srt, .vtt and .txt files.
Which languages does a video have? (free)
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "listLanguagesOnly": true }
Every language of a video
{ "urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "allLanguages": true, "outputFormats": ["text"] }
How much does it cost to scrape YouTube transcripts?
You pay per transcript delivered; see the Pricing tab for the price on your plan.
- No start fee. One video per run costs the same as one video in a batch, which matters for n8n, Make and API calls made video by video.
- Free rows. Videos without captions, without your language, private, removed, age-restricted, members-only, upcoming, or blocked after every retry cost nothing.
- Video details are included in the transcript price: date, likes, comment count and subscribers are not extra.
- Free language lists.
listLanguagesOnlyreturns the details and languages of any number of videos without charge. - Spending limits that hold.
maxItemsstops the run after that many transcripts, and the run's cost limit in Apify is respected to the cent.
Input
| Field | What it does | Default |
|---|---|---|
urls | Videos, Shorts, channels, channel tabs, playlists, search pages, video ids, @handles | — |
searchTerms | Search words, one search per line | — |
languages | Language codes or names in order of preference; en matches en-US and en-GB | ["en"] |
fallbackToAnyLanguage | Take the video's original language when none of yours exists | true |
captionType | manualFirst, autoFirst, manualOnly, autoOnly | manualFirst |
allLanguages | One row per caption language of the video | false |
listLanguagesOnly | Only details and languages, no transcript, free | false |
outputFormats | Any of segments, text, paragraphs, chunks, timestampedText, srt, vtt, xml | ["segments", "text"] |
chunkWords | Words per chunk in the chunks format | 150 |
saveFiles | Also save .srt, .vtt, .txt files and put their links in fileUrls | false |
removeNonSpeech | Remove [Music], [Applause], music notes and [ __ ] | true |
wordTimestamps | Start and end of every word (auto-generated captions) | false |
includeDetails | Exact publish time, likes, category, Shorts flag, @handle | true |
includeEngagement | Comment count and channel subscribers | true |
maxVideosPerSource | Videos per channel tab, playlist or search; 0 = all | 50 |
channelTabs | videos, shorts, streams | ["videos"] |
publishedAfter, publishedBefore | 2026-09-01, or 30 days, 2 weeks, 6 months | — |
maxItems | Most transcripts in the whole run; 0 = no limit | 0 |
includeErrorRows | Free rows for videos without a transcript | true |
deduplicate | Each video once per run | true |
failIfAllInputsFail | End the run as failed when no transcript came, for alerts | false |
strictInput | Stop before the first request on an unknown field name | true |
runTag | Text copied into every row | — |
proxyConfiguration | Leave as it is; the Actor picks addresses itself | Apify Proxy |
Output
One row per transcript (and one free row per video without one). A shortened example:
{"status": "ok","videoId": "arj7oStGLkU","url": "https://www.youtube.com/watch?v=arj7oStGLkU","title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED","channelName": "TED","channelId": "UCAuUUnT6oDeKwE6v1NGQxug","channelUrl": "https://www.youtube.com/channel/UCAuUUnT6oDeKwE6v1NGQxug","channelHandle": "@TED","channelThumbnailUrl": "https://yt3.ggpht.com/ytc/AIdro_koIFcCOrvh0KThLNOiazAIDu6hcs…","subscriberCount": 27900000,"publishedAt": "2016-04-06T16:59:35.000Z","publishDate": "2016-04-06","durationSeconds": 844,"duration": "14:04","viewCount": 62071153,"likeCount": 2055271,"commentCount": 79000,"category": "People & Blogs","keywords": ["TED Talk", "TED Talks", "Tim Urban", "procrastination"],"description": "Tim Urban knows that procrastination doesn't make sense, but he's never been able to shake his habit of waiting until th…","thumbnailUrl": "https://i.ytimg.com/vi/arj7oStGLkU/sddefault.jpg","isShort": false,"isLive": false,"wasLive": false,"isUnlisted": false,"isFamilySafe": true,"language": "en","languageName": "English","captionType": "manual","isAutoGenerated": false,"languageMatch": "requested","availableLanguages": [{ "code": "ar", "name": "Arabic", "type": "manual", "isDefault": false },{ "code": "en", "name": "English", "type": "manual", "isDefault": true },{ "code": "en", "name": "English (auto-generated)", "type": "auto", "isDefault": false }],"segmentCount": 286,"transcript": [{ "start": 12.645, "duration": 1.37, "end": 14.015, "text": "So in college," },{ "start": 15.349, "duration": 1.564, "end": 16.913, "text": "I was a government major," },{ "start": 16.937, "duration": 2.462, "end": 19.399, "text": "which means I had to write a lot of papers." }],"text": "So in college, I was a government major, which means I had to write a lot of papers. Now, when a normal student writes a paper…","paragraphs": null,"chunks": null,"timestampedText": null,"srt": null,"vtt": null,"xml": null,"fileUrls": null,"requestedLanguages": ["en"],"errorCode": null,"message": null,"retryable": null,"inputType": "video","input": "https://www.youtube.com/watch?v=arj7oStGLkU","position": null,"scrapedAt": "2026-10-17T20:10:00.000Z","runTag": null}
Every row has the same fields in the same order, so a spreadsheet or an n8n flow reads transcripts and free rows alike. A run summary by input is saved in the key-value store as SUMMARY.
Status and error codes
status | errorCode | Meaning | Charged |
|---|---|---|---|
ok | — | A transcript | yes |
listed | — | Details and languages only (listLanguagesOnly) | no |
no_transcript | NO_CAPTIONS | The video has no captions at all | no |
no_transcript | LANGUAGE_NOT_FOUND | None of your languages; availableLanguages lists what exists | no |
no_transcript | NO_MANUAL_CAPTIONS, NO_AUTO_CAPTIONS | Not the kind of captions asked for | no |
no_transcript | EMPTY_TRANSCRIPT | The track holds only sound labels | no |
failed | PRIVATE, REMOVED, UNAVAILABLE, AGE_RESTRICTED, MEMBERS_ONLY, LOGIN_REQUIRED | YouTube does not show the video to visitors | no |
failed | UPCOMING, LIVE_NOW, LIVE_RECORDING_UNAVAILABLE | Live and scheduled videos | no |
failed | BLOCKED, REGION_BLOCKED, FETCH_FAILED | YouTube refused every address tried; retryable: true | no |
failed | CHANNEL_NOT_FOUND, PLAYLIST_NOT_FOUND, NO_VIDEOS, INVALID_INPUT | The input line points at nothing | no |
YouTube transcript API and integrations
- n8n and Make: use the Apify node or module, Actor
anuarbakty/youtube-transcript-scraper, input{ "urls": ["{{ video link }}"] }, then readtextortranscriptfrom the dataset items. One video per call costs no more than one video in a batch. - Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("anuarbakty/youtube-transcript-scraper").call(run_input={"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"]})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["status"], row["language"], row["text"][:200] if row["text"] else row["message"])
- JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });const run = await client.actor('anuarbakty/youtube-transcript-scraper').call({ urls: ['https://www.youtube.com/watch?v=arj7oStGLkU'] });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0].text);
- AI agents (MCP): connect Apify's MCP server (
https://mcp.apify.com) to Claude, Cursor, VS Code or ChatGPT and ask "get the transcript of this YouTube video"; the agent calls this Actor and reads the rows.
Apify's two-minute step-by-step video shows how to configure the MCP server:
Run it on a schedule
In Apify Console, open Schedules, click Create new, choose how often, and add this Actor with one of the inputs below, or a task you saved. Set Published on or after to the schedule's interval, as in each row.
| How often | Input | What you get |
|---|---|---|
| Every day | Channel links, "channelTabs": ["videos", "shorts"], "publishedAfter": "1 day", "maxVideosPerSource": 0 | Transcripts of the new videos and Shorts of the channels you follow, such as clinics and health channels, in your n8n or Make flow |
| Every week | "searchTerms": ["physical therapy after knee replacement"], "publishedAfter": "7 days", "maxVideosPerSource": 20 | What this week's videos say about a topic; n8n can send the text to ChatGPT or Claude for a digest |
| Every week | A podcast or lecture channel, "outputFormats": ["chunks"], "publishedAfter": "7 days", "maxVideosPerSource": 0 | New chunks with links to the exact second, for your Python or JavaScript code to add to a vector database |
| Every month | Channel links, "listLanguagesOnly": true, "publishedAfter": "30 days", "maxVideosPerSource": 0 | Free rows with the caption languages of the month's videos, as Excel or CSV, for accessibility and translation work |
Is it legal to scrape YouTube transcripts?
The Actor reads only what YouTube shows any visitor who is not signed in: public captions and public video details. It does not sign in, does not download video or audio, and does not touch private or members-only content. How you use the transcripts is up to you; check YouTube's terms and the copyright of the channels you work with, and ask a lawyer when in doubt.
More from this developer
- Instagram Reels Transcript Generator: Instagram reels to text by link, account or hashtag: transcript, SRT and VTT subtitles, hooks, no login.
- Facebook Ads Library Scraper: ads from the Meta Ad Library by keyword, brand, page or Instagram account, with creatives, days running and EU reach.
- Threads Scraper: posts, all replies and profiles from Threads without login, keyword search and only-new monitoring.
- 2GIS Places Scraper: businesses from 2GIS (Russia, Kazakhstan, Central Asia, UAE) with phones, WhatsApp, Telegram, emails and websites.
- 2GIS Reviews Scraper: 2GIS reviews with star, topic and date filters and only-new monitoring.
- Google Ads Library Scraper: Google ads of any brand or website from the Google Ads Transparency Center: ad text read even from pictures, variations, countries, EU reach and targeting, no login.
- Pinterest Search Scraper: Pinterest pins, boards and profiles without login, with real pin links, saves, repins and comments, plus Pinterest Trends and search suggestions.
FAQ
How do I get a transcript of a YouTube video? Paste the video's link, or just its 11-character id, into YouTube links or video ids and click Start. The row holds the full transcript (the video's script) in text and the timed lines in transcript; copy it or download it as JSON, CSV or Excel. For more videos, paste one link per line, or give a channel, a playlist or search words.
Is there an official YouTube transcript API? Why use this scraper instead? YouTube Data API v3 has a captions resource: captions.list lists a video's caption tracks without their text, and captions.download returns one track as SRT, VTT, SBV, SCC or TTML. Both need OAuth authorization, the download works only for a user with permission to edit the video, and each download costs 200 units of the default 10,000-unit daily quota. So the official API is made for videos you manage. This Actor works on other people's public videos, channels, playlists and searches, needs no Google Cloud project, OAuth or quota, and puts the transcript and the video's details in one row.
Can I use it as a YouTube transcript generator? Yes. Give it one video link or many, a channel, a playlist or search words, and it makes each video's transcript from its captions, the author's or YouTube's auto-generated ones, in the language you choose: plain text, readable paragraphs, [1:23]-style timestamped text, SRT or VTT. The same input runs from n8n, Make, the API or an AI agent.
How do I download YouTube subtitles or captions as SRT or VTT? Add srt or vtt to Transcript formats to get them inside each row, or turn on Save .srt, .vtt and .txt files with download links to get a link to each file in fileUrls. Pick the language in Languages, or turn on Every language the video has to get all of them in one run.
What if a video has no captions? You get a free row with status: "no_transcript" and errorCode: "NO_CAPTIONS", plus the video's details.
What if my language is missing? With fallbackToAnyLanguage on (the default), the original language comes and languageMatch says fallback. With it off, a free row lists availableLanguages so you can choose.
Author or auto-generated captions? Author captions come first by default; set captionType to autoFirst, manualOnly or autoOnly to change that. captionType in each row says which one came.
Does it work for Shorts and live streams? Yes: Shorts links, a channel's Shorts tab, and recordings of past streams. A stream that is still live gives a free LIVE_NOW row; run it again once it ends.
Can I get the transcripts of a whole YouTube channel? Yes. Paste the channel link or @handle and set Videos per channel tab, playlist or search to 0 to take every video, newest first. Add shorts and streams to Channel tabs for Shorts and past live streams, and set Published on or after or Published on or before for a date range. For a playlist, paste its link the same way.
How do I get only new videos of a channel? Schedule the Actor with the channel link and publishedAfter set to the schedule's interval, for example 1 day.
Can I use inputs from another YouTube transcript Actor? Yes. Field names of the most used transcript Actors are read as they are. An unknown field stops the run before any charge and says which field it was, so a limit never goes unnoticed.
Is there a limit on videos per run? No fixed one. Use maxVideosPerSource per channel, playlist or search, and maxItems for the whole run.
Something does not work? Open an issue on the Actor's Issues tab and paste the link to the run. A run linked in an issue opens to the developer automatically: its log, input and results, and nothing else in your account. To share every run of this Actor instead, turn on Share run data with developers in Apify Console under Settings → Login & Privacy.