Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
YouTube Transcript Scraper icon

YouTube Transcript Scraper

YouTube transcripts from links or a keyword search: text, timed segments, SRT, VTT and video details. No API key. $0.80 per 1,000.

215 runs on Apify $0.0008 per transcript ($0.8 / 1,000)
Run this in the cloudRun on Apify →

YouTube & Creator Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust videoUrls, videoIds, searchKeywords (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.0008 per transcript = $0.8 per 1,000

You are charged forWhenPrice
Transcript extractedOne successfully extracted transcript. Failed or unavailable videos are not charged.$0.0008

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-30, and they are what you are actually charged.

Inputs

FieldWhat it doesType
videoUrlsYouTube watch, Shorts, live, embed, or youtu.be URLs. Raw 11-character video IDs are also accepted. Duplicate videos are processed once.array
videoIdsOptional additional list of raw 11-character YouTube video IDs. This is useful for programmatic runs that already have IDs.array
searchKeywordsSearch YouTube and get transcripts for the videos it finds, one search per line. Use it on its own or next to links: a video that turns up twice is fetched once.array
maxVideosPerSearchHow many videos to take from each search, top results first. Videos without captions aren't charged, so you can end up with fewer transcripts than this.integer
retriesRetries for temporary rate limits and YouTube server errors. Backoff is automatic.integer
languagePreferencesBCP 47 language codes in priority order, for example en, es, fr, or pt-BR. The first available preference is used. If none match, the actor falls back to another available transcript.array
maxConcurrencyNumber of videos processed at once. Keep this low to reduce YouTube throttling and compute cost.integer
requestTimeoutSecsMaximum time for all transcript requests for one video.integer

What you get

A structured dataset — each result includes fields like:

okvideoIdtitledetectedLanguagesegmentCounttexturlsearchKeyworderrorCode

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

2 ready-to-run use cases

YouTube Transcript in Spanish, English as Fallback

Spanish subtitles first, English when there is no Spanish track, as text, SRT and VTT. Each row says which language it actually came back with.

Download YouTube Transcript as Text, SRT and VTT

Paste links and get the transcript as plain text, timed segments, SRT and VTT. No API key, no login. Videos with captions off return an error row.

Ready-made automation using this tool

A finished workflow you can import into n8n and run — this tool does the data-gathering inside it. Free, and yours to change.

Get a short summary whenever a channel uploads

Watches the YouTube channels you pick. When one uploads, it reads the transcript, writes a few lines on what the video actually covers, and posts that to Slack, Notion or a spreadsheet — so you can decide whether to watch it.

All automations →

Related tools in YouTube & Creator Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

YouTube Trending Scraper iconYouTube & Creator Tools

YouTube Trending Scraper

Get the most-viewed YouTube videos for any topic, no login or key. Rows carry views, titles, channels, duration, thumbnails. $0.40 per 1,000 videos.

Ready to run — no setup

YouTube Channel Email Scraper iconYouTube & Creator Tools

YouTube Channel Email Scraper

Find the business emails creators publish in their YouTube channel description, plus their linked site's contact pages. $1.50 per 1,000 channels.

Ready to run — no setup

YouTube Scraper iconYouTube & Creator Tools

YouTube Scraper

Search YouTube or scrape a channel: title, channel, views, publish date, length and thumbnail. No API key or quota. $0.135 per 1,000 videos.

18 use cases

YouTube Channel Monitor — New Upload Tracker iconYouTube & Creator Tools

YouTube Channel Monitor — New Upload Tracker

Watch YouTube channels and get only their new uploads: title, URL, publish date, views, thumbnail. $0.01 per new video.

17 use cases

YouTube Video & Audio Downloader iconYouTube & Creator Tools

YouTube Video & Audio Downloader

Download YouTube videos as MP4 up to 8K, audio as MP3 or subtitles as .srt. No login or API key. You pay per megabyte delivered.

17 use cases

YouTube Video Uploader iconYouTube & Creator Tools

YouTube Video Uploader

Upload videos to your YouTube channel from a URL with OAuth. Set title, tags, category, thumbnail, privacy and publish time. $0.05 per upload.

2 use cases

See all YouTube & Creator Tools →

YouTube Transcript Scraper: captions as text, timed segments, SRT and VTT

Paste watch, Shorts, live, embed or youtu.be links or bare 11 character ids, or just type a search, and each video comes back as one row holding the full plain text, the timed segments, a ready-to-save SRT and a ready-to-save WebVTT. No API key, no cookies, no login.

The honest limit: it reads caption tracks the video already has. It does not listen to the audio, so a video nobody captioned and that YouTube never auto-captioned comes back as NO_TRANSCRIPT, and no setting changes that.

InputYouTube links, video ids, or search keywords
OutputOne row per video, with text, segments, SRT and VTT
Ceiling400 videos per run
Account neededNone from you
Price$0.80 per 1,000 transcripts, flat on every plan

📝 What YouTube Transcript Scraper does

For each video it finds the caption tracks, picks one using languagePreferences in order, and pulls the cues. An exact match wins, then a base-language match, so pt-BR falls back to pt. If none of your preferences exist it takes another available track rather than failing the video, and detectedLanguage tells you what it actually used.

Manual captions are preferred over auto-generated ones when both exist. isAutoGenerated says which you got, and availableLanguages lists everything the video had, so you can re-run for a different one.

Type something into searchKeywords instead and it searches YouTube, takes the top maxVideosPerSearch videos from each search, and handles them like pasted links. Shorts, channels and playlists are left out of the results. Each row it finds carries searchKeyword and searchRank.

One charge covers the whole row: the plain text, the segments, the SRT, the VTT, the language list and the metadata. There is no per-format or per-language extra. A video that turns up in more than one place, links or searches, is processed once.

📥 What you give it

{
  "videoUrls": [
    "https://www.youtube.com/watch?v=M7lc1UVf-VE",
    "https://youtu.be/dQw4w9WgXcQ",
    "aqz-KE-bpKQ"
  ],
  "languagePreferences": ["fr-CA", "fr", "en"]
}

Or search instead of pasting:

{
  "searchKeywords": ["sourdough for beginners", "no knead bread recipe"],
  "maxVideosPerSearch": 10
}
FieldDefaultWhat it is
videoUrls[]Watch, Shorts, live, embed and youtu.be links, or bare ids. Up to 200.
videoIds[]A second list for raw ids, handy when your pipeline stores them separately. Up to 200.
searchKeywords[]Searches to run, one per line. Up to 20. Works on its own or next to links.
maxVideosPerSearch10How many top results to take from each search, 1 to 100.
languagePreferences["en"]BCP 47 codes in priority order, such as en, es, pt-BR. Up to 20.
maxConcurrency2Videos handled at once, 1 to 10. Low on purpose: it keeps the run steady and cheap.
retries2Retries for rate limits and server errors, 0 to 5. Backoff is automatic.
requestTimeoutSecs45Total time allowed per video, 10 to 180 seconds.
proxyConfigurationoffOff by default, which is the right setting almost always. Turn it on only if a run is being rate limited.

Run it with empty input and you get one labelled sample row, uncharged, so you can see the shape first.

📤 What you get back

A real row from a real run. text, segments, srt and vtt are cut short here, because the full row is about 20 KB of the same transcript in four shapes:

{
  "ok": true,
  "_sample": false,
  "_diagnostic": false,
  "videoId": "M7lc1UVf-VE",
  "url": "https://www.youtube.com/watch?v=M7lc1UVf-VE",
  "title": "YouTube Developers Live: Embedded Web Player Customization",
  "author": "Google for Developers",
  "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
  "viewCount": 1656845,
  "durationSeconds": 1344,
  "detectedLanguage": "en",
  "requestedLanguage": "en",
  "isAutoGenerated": false,
  "segmentCount": 466,
  "text": "JEFF POSNICK: Hey, everybody. Welcome to this week's show of YouTube Developers Live. ...",
  "segments": [
    { "text": "JEFF POSNICK: Hey, everybody.", "start": 10.349, "duration": 1, "end": 11.349 },
    { "text": "Welcome to this week's show of YouTube Developers Live.", "start": 11.349, "duration": 2.681, "end": 14.03 }
  ],
  "srt": "1\n00:00:10,349 --> 00:00:11,349\nJEFF POSNICK: Hey, everybody. ...",
  "vtt": "WEBVTT\n\n00:00:10.349 --> 00:00:11.349\nJEFF POSNICK: Hey, everybody. ...",
  "availableLanguages": [
    { "languageCode": "en", "languageName": "English", "isAutoGenerated": false },
    { "languageCode": "en", "languageName": "English (auto-generated)", "isAutoGenerated": true }
  ]
}
FieldWhat it is
textThe whole transcript as one string, cues joined.
segmentsEvery cue with start, duration and end in seconds, for anything timestamp driven.
srt, vttThe same cues formatted as subtitle files. Save the string straight to .srt or .vtt.
detectedLanguage, requestedLanguageWhat you got, and the first thing you asked for. Compare them to spot a fallback.
isAutoGeneratedtrue when the track is machine-made, which is where the punctuation and names get loose.
availableLanguagesEvery track the video carried, so a second run can fetch a different one.
title, author, channelId, viewCount, thumbnailUrlVideo metadata. Any of them can be null when YouTube did not return it.
searchKeyword, searchRankWhich search found the video and where it ranked. Only on rows that came from a search.

🧾 Reading the output

Three kinds of row can land in your dataset, and the flags are how you tell them apart.

RowHow to spot itBilled
A transcriptok: true and _sample: falseyes
The sample row_sample: true, videoId SAMPLE00000no
A diagnosticok: false, _diagnostic: true, an errorCodeno

The Overview table has no _sample column, so the free sample row reads there as a perfectly good transcript. Filter on _sample == false before counting anything.

The error codes are the useful part of a diagnostic row, and each carries a hint:

errorCodeWhat happened
NO_TRANSCRIPTThe video has no caption track in any language.
VIDEO_UNAVAILABLEPrivate, removed, or the id does not exist.
LOGIN_REQUIREDAge-gated or members-only, so a signed-out reader cannot open it.
INVALID_VIDEOThe string you passed is not a YouTube link or an 11 character id.
RATE_LIMITEDYouTube pushed back on that video. Re-running usually clears it.
NO_SEARCH_RESULTSA search found no videos. Try fewer or different words.
SEARCH_FAILEDA search could not be run. Try again in a few minutes.
EXTRACTION_FAILEDTracks were found but no cues came back.
TIME_LIMITThe run got close to its time limit and stopped early. Every transcript delivered before that is in your dataset; give the run more time, or ask for fewer videos, to get the rest. If none came back at all, the run is marked as failed.
RUN_ERRORThe run itself failed, written as one row so the reason survives.

A batch where every video fails still finishes as a successful run, with diagnostics and nothing else. Count ok: true rows rather than trusting the run status.

▶️ How to run it

1. Open YouTube Transcript Scraper and click Try for free. 2. Press Start with the input empty to see the free sample row. 3. Paste links or ids into Video URLs or IDs, or type what you want into Search keywords. 4. Set Preferred transcript languages if English is not what you want. 5. Download the dataset as JSON, or pull srt out of a row and save it as a subtitle file.

💰 How much does it cost?

$0.80 per 1,000 transcripts, the same on every Apify plan.

You pay per transcript returned. The sample row, diagnostic rows and duplicate ids are never billed, so a batch of 100 videos where 12 have no captions bills 88 transcripts, not 100.

💡 What people use it for

  • Turning a talk or interview into text you can search, quote and paste into notes.
  • Feeding transcripts to a model for summaries, without paying a speech-to-text bill.
  • Making .srt files for re-uploads, or as the starting point for a translation pass.
  • Finding the exact moment a phrase was said, using segments to jump to the second.

🚧 What it does not do

  • No speech to text. Published caption tracks only, auto-generated ones included. Nothing

captioned means nothing to return.

  • No translation. It fetches tracks that exist. If the video has no French track, asking for

French gets you another language, not a translation.

  • One video per entry. Channel and playlist links are not expanded here. There is a bulk actor

below for that.

  • durationSeconds can be the transcript's length, not the video's, when YouTube returned no

metadata for that video. Sanity check it against the last segment's end if it matters.

  • Metadata can be null. Title, author, view count and thumbnail come from YouTube's own

response and are sometimes absent, while the transcript itself is fine.

  • Auto-generated tracks have no reliable punctuation or speaker names, and get proper nouns

wrong. isAutoGenerated is how you know which you are reading.

  • Rows are large, roughly 18 to 24 KB each, because text, segments, SRT and VTT hold the same

words four ways. A 400 video run is a chunky dataset.

  • Search takes YouTube's own top results. There is no filter for upload date, length or views, and

a video without captions still uses up one of the places you asked for.

  • 400 videos per run in total, links and search results together.

🧭 Which YouTube scraper do you need?

If you wantUse
Transcripts for videos you already have links forThis one
Transcripts for a whole channel or playlist in one runYouTube Transcript Bulk Scraper
The video or its audio as a fileYouTube Downloader
The comments under the videoYouTube Comments Scraper
Videos to run this on, by keyword or channelYouTube Scraper

❓ Questions people ask

Do I need a YouTube Data API key? No. No key, no cookies, no OAuth, no quota.

What if the video has no captions? You get an uncharged NO_TRANSCRIPT row and the batch carries on. It does not transcribe the audio.

Which language do I get? The first one in languagePreferences that exists, an exact match before a base-language one. Otherwise another available track, named in detectedLanguage.

Can I get the SRT file directly? The srt field is the file's contents. Write the string to a .srt and it plays.

Why is one video missing from my results? Look for its diagnostic row. LOGIN_REQUIRED and VIDEO_UNAVAILABLE are permanent for a signed-out reader, RATE_LIMITED is worth retrying.

Is scraping YouTube legal? This reads publicly available captions. What you then do with somebody else's words is your call, and copyright still applies. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Include the video link and the run ID, and the errorCode on the diagnostic row if you got one.