YouTube Transcript & Subtitle Scraper icon

YouTube Transcript & Subtitle Scraper

Extract transcripts and subtitles from YouTube videos in bulk using video, playlist, channel URLs, or keyword search. Returns timed transcript…

Start using this actor on Apify ↗Need a custom scraper?Contact us ↗

YouTube Transcript & Subtitle Scraper at a glance

YouTube Transcript & Subtitle Scraper is a ready-to-run Apify actor from abotapi for collecting videos data. Its documented output includes video id, title, channel, lang and chars, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.20 per 1,000 transcripts on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.

Runs on
Apify cloud: console, API, schedules and integrations
Data type
Videos, Developer Tools, AI
Pricing
$2.20 per 1,000 transcripts (Free plan), from $1.00 on paid plans
Output
Documented below · JSON, CSV, Excel
Inputs
19 options

Extract transcripts and subtitles from YouTube videos in bulk using video, playlist, channel URLs, or keyword search. Returns timed transcript segments, plain text, SRT, and WebVTT subtitle files, with optional auto-translation to other languages.

What YouTube Transcript & Subtitle Scraper can do

  • Four ways in. Mix direct video links or IDs, playlist links, and channel links (@handle, /channel/UC..., /c/..., /user/...) in one run, or switch to search mode to find videos by keyword.
  • Three formats per video. Every record carries the transcript as timed segments, a single plain text transcript field, and srt plus vtt strings you can save straight to disk.
  • Language control. List your preferred languages in priority order, or translate the result into another language YouTube supports.
  • Handles both caption types. Works with human written captions and auto generated ones, and falls back to whatever the video offers when none of your preferred languages are available.
  • Time windows on demand. Trim every transcript to a specific second range, and pay only for the trimmed text.
  • Built for large pulls. Resume an interrupted playlist or channel crawl, or schedule the actor to run on a recurring basis and get only what's new, updated, or gone since last time.

Choose what to collect

These inputs let you configure YouTube Transcript & Subtitle Scraper. Open the actor on Apify to enter your values and review the current options.

Supported input fields
InputWhat it controls
modestring · requiredPick how to specify videos.

Choices: url, search

videoUrlstringAlias for a single URL; added to 'Video / playlist / channel URLs'. Used only in URL mode.
searchQueriesarrayOne per line. Top results per query (up to 'Max videos per source') are fetched.
startSecintegerTrim each transcript to start at this second. 0 keeps from the beginning of each video.
durationSecintegerTrim each transcript to this many seconds from Start above. 0 keeps until the end of each video.
maxVideosPerSourceintegerHow many videos to take from each playlist, channel, or search query.
maxVideosintegerHard cap on the total number of videos processed across all sources. Up to 100000; 0 (from older saved tasks) is read as 100000.
Show 12 more inputs
More input fields
InputWhat it controls
languagesarrayLanguage codes in priority order, for example ["en", "en-US", "de"]. The first available one is used; if none are available, any transcript YouTube offers is returned.
translateToLanguagestringOptional. A language code (e.g. "en") to translate the transcript into using YouTube's auto-translation. Leave empty to keep the original.
targetLanguagestringAlias of 'Translate transcript to'. Used only when that field is empty.
preserveFormattingbooleanKeep inline formatting tags (e.g. italics) in the transcript text instead of stripping them.
incrementalModebooleanTurn this on for daily or recurring monitoring of the same videoUrls/searchQueries. The first run returns every video as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED videos. Turn on "Emit unchanged" or "Emit expired" only when you also want those videos returned (and billed). State is kept separately for each mode/URL/query/language setup; use State key when you want to name or deliberately share a monitoring campaign. A video counts as UPDATED when any returned field differs from the last run (transcript text and segments, language, title, channel, duration, and so on); the run timestamp fetchedAt is never compared, and neither are fields you list in Ignore fields. To continue one specific interrupted run instead, use Resume from a previous run above.
emitUnchangedbooleanOff by default. Turn on to also return videos whose transcript has not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want the full snapshot every run.
emitExpiredbooleanOff by default. Turn on to also return videos that were present in a previous run but no longer appear, marked EXPIRED. Only produced in Keyword search mode, and only once a run has fully scanned every tracked search query, not when Max videos capped it, when Resume was used, or when a search may have been truncated. In URL mode this can never fire: the tracked set is whatever URLs you pasted, so a missing one just wasn't pasted this run, not confirmed gone. EXPIRED rows are synthesized from the last known data, so they are never re-billed. Leave off unless you need expiry tracking.
stateKeystringOptional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the mode/URLs/queries/language settings, different setups then never mix state with each other.
ignoreFieldsForChangesarrayIncremental mode only. Field names that must NOT count as a change, so a difference in them alone keeps a video UNCHANGED (and unbilled). The fetchedAt timestamp is always ignored. Use a top-level name such as videoTitle or channelName, or a dotted path for a nested field such as segments.start (lists are searched element by element). Ignored fields still appear in the output.
mcpConnectorsarrayOptionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).
notionParentPageUrlstringURL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset.

Fields in the output

The documented dataset includes the fields below. Availability can depend on the source page and selected mode.

videoIdVideo ID
videoTitleTitle
channelNameChannel
languageCodeLang
charCountChars
successOK
transcriptTranscript (preview) (text)
changeTypeChange type
changedFieldsChanged fields
firstSeenAtFirst seen at (date)
lastSeenAtLast seen at (date)
fetchedAtFetched at (date)

Example output

An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.

{
  "videoId": "EXAMPLE_ID1",
  "videoUrl": "https://www.youtube.com/watch?v=EXAMPLE_ID1",
  "videoTitle": "Sample Video Title",
  "channelName": "Sample Channel",
  "channelUrl": "https://www.youtube.com/@SampleChannel",
  "durationSeconds": 213,
  "source": "https://www.youtube.com/watch?v=EXAMPLE_ID1",
  "sourceType": "video",
  "language": "English",
  "languageCode": "en",
  "isGenerated": false,
  "isTranslated": false,
  "translatedTo": null,
  "charCount": 5234,
  "segmentCount": 142,
  "transcript": "Hello and welcome to this sample transcript.\nThis is the second line of the transcript.",
  "segments": [
    {
      "text": "Hello and welcome to this sample transcript.",
      "start": 0,
      "duration": 2.32
    },
    {
      "text": "This is the second line of the transcript.",
      "start": 2.32,
      "duration": 2.08
    }
  ],
  "srt": "1\n00:00:00,000 --> 00:00:02,320\nHello and welcome to this sample transcript.\n",
  "vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:02.320\nHello and welcome to this sample transcript.\n",
  "trimmedStart": 0,
  "trimmedDuration": 0,
  "success": true,
  "error": null,
  "fetchedAt": "2026-07-30T08:13:20Z"
}

Ways to use this data

  • Content repurposing: turn a video's spoken words into blog posts, show notes, or social captions without watching it end to end.
  • Research and note taking: skim long lectures, podcasts, or interviews as searchable text instead of sitting through the video.
  • Localization and accessibility: generate subtitle files or translated transcripts for viewers who need them.
  • SEO and content indexing: feed video transcripts into your own search tool or content database.
  • Media monitoring: track new uploads from a channel or keyword and pull their transcripts automatically on a schedule.

Before you run

Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.

Questions about this actor

What data does YouTube Transcript & Subtitle Scraper return?

The documented output for YouTube Transcript & Subtitle Scraper includes video id, title, channel, lang, chars, ok, transcript (preview) and change type. Availability of each field depends on the source page and the selected mode.

How much does YouTube Transcript & Subtitle Scraper cost?

It costs $2.20 per 1,000 transcripts on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.

Why did I get an auto generated transcript instead of the creator's captions?

The actor prefers a human written transcript over an auto generated one whenever both exist in one of your Preferred transcript languages. If the creator did not upload captions in any of your preferred languages, the actor falls back to whatever the video offers, which may be auto generated.

Why did my run fail instead of returning an empty or partial dataset?

The run fails outright when no page could be read at all (see Plan Requirement), when a resumeFromRunId that cannot be resolved to a run or dataset you own, or when you turn on Incremental mode together with resumeFromRunId when that monitoring setup already has saved state from an earlier run. Otherwise, including empty videoUrls/searchQueries, a video with disabled captions, a private or region locked video, or a temporary block from YouTube on some of the videos, still finishes the run and adds a dataset row explaining what happened, with success set to false, so a partial run always gives you every transcript that could be read. The exception is a run in which not one video got an answer from YouTube (for example every video was temporarily blocked): that run ends FAILED with the connection message described under Plan Requirement, though the rows describing each blocked video are still in the dataset.

Can I get only new or changed transcripts on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then classifies every video, and only new, updated, and reappeared rows are returned and billed by default.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to send a summary of each transcript to Notion, Linear, or Airtable at the end of each run.

Ready to collect with YouTube Transcript & Subtitle Scraper?

Run it on Apify with your own input and export the results as JSON, CSV or Excel.