Home / Tools / YouTube Transcript Scraper

Jobs & content

YouTube Transcript Scraper

Get YouTube transcripts (captions/subtitles) in bulk for videos, Shorts, channels, playlists or search results. Plain text, timestamped segments, SRT, VTT or RAG-ready chunks, with language fallback and video metadata. No browser, no API key. Pay only for transcripts found.

Run it on Apify API & MCP

Sample output

VideoChannelLanguageWordsTranscript
Me at the zoojaweden39All right, so here we are, in fro…

Real rows from the prefilled example run (Oct 19, 2026), 5 of 31+ fields shown. Export as JSON, CSV, Excel or HTML, or read them through the API.

Full JSON of one real output row (1 rows in the example dataset)
{
  "videoId": "jNQXAC9IVRw",
  "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "status": "ok",
  "title": "Me at the zoo",
  "channelName": "jawed",
  "channelId": "UC4QobU6STFB0P71PMvOGN5A",
  "channelUrl": "https://www.youtube.com/channel/UC4QobU6STFB0P71PMvOGN5A",
  "publishDate": "2005-04-23T20:31:52-07:00",
  "durationSeconds": 19,
  "duration": "0:19",
  "viewCount": 445187321,
  "category": "Film & Animation",
  "isLive": false,
  "language": "en",
  "languageName": "English",
  "isAutoGenerated": false,
  "isTranslated": false,
  "transcriptAvailable": true,
  "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",
  "wordCount": 39,
  "availableLanguages": [
    {
      "code": "en",
      "name": "English",
      "isAutoGenerated": false
    },
    {
      "code": "de",
      "name": "German",
      "isAutoGenerated": false
    }
  ],
  "source": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "sourceType": "video",
  "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",
  "chapters": [
    {
      "start": 0,
      "title": "Intro"
    },
    {
      "start": 5,
      "title": "The cool thing"
    },
    {
      "start": 17,
      "title": "End"
    }
  ],
  "originalLanguage": "en",
  "languageMatch": "preferred",
  "segmentCount": 6,
  "segments": [
    {
      "start": 1.2,
      "end": 3.36,
      "text": "All right, so here we are, in front of the elephants"
    },
    {
      "start": 5.318,
      "end": 7.974,
      "text": "the cool thing about these guys is that they have really..."
    },
    {
      "start": 7.974,
      "end": 12.616,
      "text": "really really long trunks"
    },
    "... 3 more"
  ],
  "isUnlisted": false,
  "scrapedAt": "2026-10-19T10:00:12.452Z"
}

Output fields

From the Actor's dataset schema. Every row has the same flat shape, so it drops straight into a spreadsheet, a database or an agent's context.

FieldTypeDescription
videoIdstringYouTube video ID
urlstringVideo URL
statusstringok, no_transcript, no_videos or error (only ok rows are charged)
noTranscriptReasonstringno_captions, language_not_available, only_auto_generated, video_unavailable, private_video, age_restricted, members_only, geo_restricted, live_not_started, login_required
errorstringError or YouTube message
titlestringVideo title
channelNamestringChannel name
channelIdstringChannel ID (UC...)
channelUrlstringChannel URL
publishDatestringPublish date (ISO 8601 with offset)
durationSecondsintegerDuration in seconds
durationstringDuration (m:ss or h:mm:ss)
viewCountintegerView count
categorystringYouTube category
isLivebooleanLive stream / was live
isUnlistedbooleanUnlisted video
descriptionstringVideo description
chaptersarrayChapters from description timestamps [{start, title}]
languagestringTranscript language code
languageNamestringTranscript language name
originalLanguagestringSpoken (original) language
languageMatchstringpreferred = one of your languages, original = fallback to the original language
isAutoGeneratedbooleanAuto-generated (ASR) captions
isTranslatedbooleanMachine-translated by YouTube (autoTranslate)

Pricing

Pay per result, billed by Apify. No subscription and no minimum. Discount tiers apply automatically on paid Apify plans.

EventFree planBronzeSilverGold
Transcript result main
Charged once for each video transcript successfully saved to the dataset. Rows without a transcript are free.
$0.003$0.0026$0.0022$0.0019

Examples on the Free plan: 100 transcript results = $0.30, 1,000 transcript results = $3, 10,000 transcript results = $30. Apify's Free plan includes $5 of monthly usage credit. Prices read from the Apify API at build time (2026-10-19).

Scheduled price change from 2026-11-02 (Free-plan tier): Transcript result: $0.003 → $0.004. Paid-plan tiers change accordingly. The table shows today's prices.

Example input

This is the prefilled input on the Store page. Keep it and click Start to see real data in seconds.

{
  "urls": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "maxVideos": 1,
  "channelContentType": "videos",
  "maxTotalVideos": 1000,
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": true,
  "autoTranslate": false,
  "preferManualCaptions": true,
  "skipAutoGenerated": false,
  "outputFormats": [
    "text",
    "segments"
  ],
  "chunkSize": 2000,
  "chunkOverlap": 200,
  "includeDescription": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "maxConcurrency": 20,
  "maxRetries": 6
}

Use it from code, no-code or an AI agent

cURL (one request, returns rows)
curl -X POST \
  "https://api.apify.com/v2/acts/wrenfield-data~youtube-transcript-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"], "maxVideos": 1, "channelContentType": "videos", "maxTotalVideos": 1000, "languages": ["en"], "fallbackToAnyLanguage": true, "autoTranslate": false, "preferManualCaptions": true, "skipAutoGenerated": false, "outputFormats": ["text", "segments"], "chunkSize": 2000, "chunkOverlap": 200, "includeDescription": true, "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": true, "maxConcurrency": 20, "maxRetries": 6}'
Python
# pip install apify-client
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("wrenfield-data/youtube-transcript-scraper").call(
    run_input={
    "urls": [
        "https://www.youtube.com/watch?v=jNQXAC9IVRw"
    ],
    "maxVideos": 1,
    "channelContentType": "videos",
    "maxTotalVideos": 1000,
    "languages": [
        "en"
    ],
    "fallbackToAnyLanguage": True,
    "autoTranslate": False,
    "preferManualCaptions": True,
    "skipAutoGenerated": False,
    "outputFormats": [
        "text",
        "segments"
    ],
    "chunkSize": 2000,
    "chunkOverlap": 200,
    "includeDescription": True,
    "proxyConfiguration": {
        "useApifyProxy": True
    },
    "residentialFallback": True,
    "maxConcurrency": 20,
    "maxRetries": 6
},
    max_total_charge_usd=1.00,  # hard cap for this run
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
JavaScript / Node
// npm i apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('wrenfield-data/youtube-transcript-scraper').call({
  "urls": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "maxVideos": 1,
  "channelContentType": "videos",
  "maxTotalVideos": 1000,
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": true,
  "autoTranslate": false,
  "preferManualCaptions": true,
  "skipAutoGenerated": false,
  "outputFormats": [
    "text",
    "segments"
  ],
  "chunkSize": 2000,
  "chunkOverlap": 200,
  "includeDescription": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "maxConcurrency": 20,
  "maxRetries": 6
}, { maxTotalChargeUsd: 1 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
MCP (Claude, Cursor, VS Code, any MCP client)
{
  "mcpServers": {
    "wrenfield-youtube-transcript-scraper": {
      "url": "https://mcp.apify.com?tools=wrenfield-data/youtube-transcript-scraper"
    }
  }
}

Remote MCP server hosted by Apify. Sign in with OAuth on first use, or send Authorization: Bearer <APIFY_TOKEN>. The tool appears as wrenfield-data--youtube-transcript-scraper. More client setups on the MCP page.

n8n, Make, Zapier

Use the official Apify node or app, pick Run Actor, enter wrenfield-data/youtube-transcript-scraper and paste the input JSON above. Then read the run's dataset items. Ready-made n8n workflows are on the n8n templates page.

FAQ

How much does YouTube Transcript Scraper cost?

$0.003 per transcript result on the Apify Free plan ($3 per 1,000), billed per result by Apify with no subscription. Higher Apify plans get the discounted tiers shown in the pricing table. You can cap any run with a maximum cost.

Do I need a YouTube API key or account?

No. The Actor uses no login, no cookies and no API key.

Which videos have no transcript?

Videos whose creator turned off captions and that YouTube didn't auto-caption (often music, live news streams and very short clips). Also private, members-only, age-restricted and removed videos, and live streams that haven't started. These return a free row with noTranscriptReason.

Does it work for Shorts and live streams?

Yes. Use Shorts URLs, a channel's /shorts tab, or set Channel tab to Shorts. Finished live streams (replays) work when YouTube has captions for them.

How many videos can I get from a channel?

As many as the channel has. Set Max videos per channel (up to 5,000 per source). Channels are listed newest first.

Can I use it from an AI agent / MCP / n8n / Make / Zapier?

Yes. Call the Actor through the Apify API, MCP server or any Apify integration with a single video URL, and read text from the first dataset item. Rows are small, flat JSON.

Is it legal to scrape YouTube transcripts?

This Actor collects publicly available captions and metadata only, and no personal data beyond public channel names. Transcripts are the creators' copyrighted content. Make sure your use (e.g. research, analysis, summarization) complies with YouTube's Terms of Service and copyright law in your country. If you are unsure, consult a lawyer.

Related tools

Compare and plan

Try YouTube Transcript Scraper now

Open it on Apify, keep the prefilled example and click Start. The Apify Free plan includes $5 of monthly credit, no card needed.

Open on Apify