# YouTube Transcript Scraper - Subtitles, Captions & Channels (`scrapesage/youtube-transcript-scraper`) Actor

Extract YouTube transcripts, subtitles & captions in bulk — from video URLs, entire channels, playlists, or search. Timestamped segments, SRT/VTT, auto + manual captions, translation to 100+ languages, rich video metadata, and monitoring for new uploads. No login, no API key, no browser.

- **URL**: https://apify.com/scrapesage/youtube-transcript-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Videos, AI, Automation
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 transcript extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Transcript Scraper — Subtitles, Captions & Channel Transcripts in Bulk

Extract **YouTube transcripts, subtitles and captions at scale** — with **timestamps, SRT/VTT subtitle files, translation to 100+ languages, and rich video metadata** on every record. Feed it single videos, whole channels, playlists, or search queries and get clean, LLM-ready transcript data back.

No login, no cookies, no API key, no browser — fast JSON extraction straight from YouTube's own mobile endpoints.

### Why this YouTube transcript scraper?

Most transcript actors return just a wall of text. This one ships the **richest transcript record in the category** — the transcript *and* everything you'd otherwise scrape a separate video-details actor for:

| Data | Typical scrapers | This actor |
|---|---|---|
| Plain-text transcript | ✅ | ✅ |
| Timestamped segments (start / dur / end) | partial | ✅ |
| Ready-to-save **SRT** and **WebVTT** files | ❌ | ✅ opt-in |
| Auto-generated **and** human-written captions | partial | ✅ |
| **Translate** the transcript to any language | ❌ | ✅ (YouTube caption translation) |
| List of every available caption language | ❌ | ✅ |
| Title, channel, views, **likes**, publish date, duration | ❌ | ✅ |
| Category, keywords/tags, chapters, thumbnail | ❌ | ✅ |
| Expand a **channel / playlist / search** into transcripts | partial | ✅ |
| **Monitor mode** — only new videos | ❌ | ✅ |
| Videos without captions flagged (not silently dropped) | ❌ | ✅ with reason |

### Use cases

- **AI, RAG & LLM pipelines** — turn any channel, playlist, or search into a clean transcript corpus for summarization, semantic search, fine-tuning, or retrieval-augmented generation. Every record is LLM-ready JSON.
- **Content repurposing** — pull transcripts to draft blog posts, newsletters, show notes, timestamps/chapters, and social clips from long-form video.
- **Subtitle & localization workflows** — export SRT/VTT and use YouTube's own translation to caption or localize videos into 100+ languages.
- **Research & analysis** — build datasets of what creators actually *say* — competitor messaging, market research, sentiment, keyword and topic mining across thousands of videos.
- **Accessibility** — generate readable transcripts of talks, lectures, and tutorials at scale.
- **Monitoring** — track a channel or search and transcribe only the newest uploads on a schedule.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **YouTube Transcript Scraper**, paste video URLs (or a channel, playlist, or search query), and click **Start**.
3. Watch transcripts stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "channelUrls": ["@lexfridman"],
    "playlistUrls": ["https://www.youtube.com/playlist?list=PLrAXtmErZgOdP_8GztsuKi9nrraNbKKp4"],
    "searchQueries": ["ai agents tutorial"],
    "language": "en",
    "translateTo": "",
    "includeSegments": true,
    "includeSrt": false,
    "includeVtt": false,
    "includeVideoMetadata": true,
    "monitorMode": false,
    "maxResults": 25,
    "maxVideosPerSource": 25
}
```

- **videoUrls** — YouTube video URLs or 11-char IDs. Watch, `youtu.be`, Shorts, embed, and live URLs all work.
- **channelUrls** — `@handle`, channel URL, or `UC…` ID → expands to the channel's latest videos.
- **playlistUrls** — playlist URL or `PL…`/`UU…` ID → expands to the playlist's videos.
- **searchQueries** — YouTube search keywords → expands to the top result videos (`searchSort`: relevance / date / views / rating).
- **startUrls** — paste any mix of YouTube URLs; each is auto-detected as a video, playlist, channel, or search page.
- **language** *(default `en`)* — preferred transcript language (ISO code). Picks a human-written track first, then auto-generated captions.
- **fallbackToAutoCaptions** *(default true)* — use auto-generated (ASR) captions when no human track exists in the language.
- **fallbackToAnyLanguage** *(default true)* — take the video's original caption track when nothing exists in the preferred language (rather than skipping it).
- **translateTo** — optional ISO code to translate the transcript into, using YouTube's own caption translation (100+ languages).
- **includeSegments** *(default true)* — include the `segments` array (`{ start, dur, end, text }` in seconds).
- **includeSrt / includeVtt** *(default false)* — add ready-to-save `srt` / `vtt` subtitle-file content.
- **includeVideoMetadata** *(default true)* — add publish date, category, likes, chapters, keywords, and channel handle (turn off for the fastest possible bulk transcript sweeps).
- **monitorMode** *(default false)* — remember delivered videos and emit only new ones on later runs (great with [Schedules](https://docs.apify.com/platform/schedules) on a channel/search).
- **maxResults** *(default 25)* — total cap. `0` = no limit (opt-in).
- **maxVideosPerSource** *(default 25)* — per channel/playlist/search cap so one source can't crowd out the rest.

### Output

One record per video (`type: "transcript"`; videos without captions come back as `type: "video"` with the reason):

```json
{
    "type": "transcript",
    "videoId": "dQw4w9WgXcQ",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
    "channelTitle": "Rick Astley",
    "channelHandle": "@RickAstleyYT",
    "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
    "channelUrl": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
    "publishedDate": "2009-10-24T07:57:33-07:00",
    "viewCount": 1788562314,
    "likeCount": 19214235,
    "lengthSeconds": 213,
    "durationFormatted": "3:33",
    "category": "Music",
    "keywords": ["rick astley", "never gonna give you up", "…"],
    "chapters": [],
    "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg",
    "hasTranscript": true,
    "language": "en",
    "languageName": "English",
    "trackKind": "manual",
    "isTranslated": false,
    "availableLanguages": [
        { "code": "en", "name": "English", "kind": "manual", "translatable": true },
        { "code": "de-DE", "name": "German (Germany)", "kind": "manual", "translatable": true }
    ],
    "wordCount": 487,
    "charCount": 2089,
    "segmentCount": 61,
    "transcript": "We're no strangers to love. You know the rules and so do I…",
    "segments": [
        { "start": 18.64, "dur": 3.24, "end": 21.88, "text": "We're no strangers to love" }
    ],
    "source": "videoUrl",
    "scrapedAt": "2026-07-02T12:00:00.000Z"
}
```

Turn on `includeSrt` / `includeVtt` to also get `srt` and `vtt` fields with subtitle-file text you can save directly as `.srt` / `.vtt`.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it hourly/daily/weekly with `monitorMode` to transcribe only new uploads from a channel or search.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (feed a RAG index, post to Slack, kick off summarization) the moment a run finishes.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/youtube-transcript-scraper').call({
    channelUrls: ['@lexfridman'],
    maxResults: 25,
    includeSrt: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} transcripts`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new transcripts straight into Docs, Notion, or your CMS.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored channel posts a new video.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. You can call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "get transcripts of the last 20 videos from this channel and summarize the key points" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **video, creator & content pipeline**:

- **[YouTube Scraper](https://apify.com/scrapesage/youtube-scraper)** — channels, videos, and creator-contact leads (emails, socials).
- **[TikTok Ad Library Scraper](https://apify.com/scrapesage/tiktok-ad-library-scraper)** — TikTok ads and Creative Center intelligence.
- **[Twitter (X) Scraper](https://apify.com/scrapesage/twitter-scraper)** — tweets, profiles, and monitoring.
- **[Reddit Scraper](https://apify.com/scrapesage/reddit-scraper)** — posts, comments, subreddits, and users.
- **[Substack Scraper](https://apify.com/scrapesage/substack-scraper)** — newsletters, posts, and creator leads.
- **[Apple Podcasts Scraper](https://apify.com/scrapesage/apple-podcasts-scraper)** — shows, episodes, reviews, and host leads.
- **[Google News Scraper](https://apify.com/scrapesage/google-news-scraper)** — articles, sources, and monitoring.
- **[Keyword Research Scraper](https://apify.com/scrapesage/keyword-research-scraper)** — Google, YouTube, and Amazon keyword ideas.

### Tips

- **Fastest bulk sweeps**: turn `includeVideoMetadata` off — you'll get transcript + core video info from a single request per video (skips the metadata page).
- **Auto vs manual captions**: `trackKind` tells you whether a transcript is `manual` (human-written, most accurate) or `auto` (ASR). Keep the fallbacks on so you never miss a video that only has one.
- **Translate anything**: set `translateTo` to any ISO code (e.g. `en`, `es`, `ja`) — YouTube translates the source captions on the fly, even for auto-generated tracks.
- **Exhaust a channel/playlist**: raise `maxVideosPerSource` (and `maxResults`), or set `maxResults: 0` for no cap. The run self-limits before the platform timeout and reports where it stopped.
- **Recurring monitoring**: combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` to transcribe only newly uploaded videos.

### FAQ

**Does it work without the YouTube Data API?** Yes. There's no API key, quota, or login. The actor reads YouTube's own public endpoints — the same caption data the site and app use — so there's no 10,000-unit daily quota to worry about.

**Manual vs auto-generated captions — which do I get?** Both. It prefers a human-written track in your chosen `language`, then falls back to auto-generated (ASR) captions, then to the video's original language. The `trackKind` field says which one each transcript came from.

**Can it translate transcripts?** Yes — set `translateTo` to an ISO language code and YouTube translates the captions into that language (works for 100+ languages, including auto-generated source tracks).

**Can I get SRT or VTT subtitle files?** Yes — enable `includeSrt` and/or `includeVtt` and each record gets ready-to-save `srt` / `vtt` text.

**A video came back with `hasTranscript: false` — why?** Some videos genuinely have no captions (neither uploaded nor auto-generated), or are private/age-restricted/unavailable. Those are returned as `type: "video"` with a `transcriptUnavailableReason` (e.g. `no_captions`, `age_restricted`, `video_unavailable`) instead of being silently dropped.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**Is scraping YouTube transcripts legal?** This actor collects publicly available data only. You are responsible for using the data in compliance with applicable laws (including copyright and YouTube's terms). Transcripts are the creator's content — use them accordingly.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

## `videoUrls` (type: `array`):

YouTube video URLs or 11-character video IDs. All formats work: watch URLs, youtu.be, Shorts, embeds, live URLs.

## `channelUrls` (type: `array`):

Channels to expand into their latest videos — @handle, full URL, or UC… channel ID. Combine with Monitor mode to transcribe only newly uploaded videos on a schedule.

## `playlistUrls` (type: `array`):

Playlists to expand into videos (playlist URL or PL…/UU… ID).

## `searchQueries` (type: `array`):

YouTube search keywords — each query is expanded into its top result videos.

## `startUrls` (type: `array`):

Paste any YouTube URLs — video, Shorts, playlist, channel, or search-results pages are detected automatically.

## `searchSort` (type: `string`):

How search-query results are ordered before taking the top videos.

## `language` (type: `string`):

ISO language code (en, es, de, fr, pt, hi, ja, ko, zh…). The scraper picks a human-written track in this language first, then auto-generated captions (see fallbacks below).

## `fallbackToAutoCaptions` (type: `boolean`):

When no human-written track exists in the preferred language, use YouTube's auto-generated (ASR) captions.

## `fallbackToAnyLanguage` (type: `boolean`):

When nothing exists in the preferred language at all, take the video's default/original caption track instead of skipping the video.

## `translateTo` (type: `string`):

Optional ISO language code — uses YouTube's own caption translation (100+ languages, e.g. en, es, fr, de, pt, ar, hi, ja). Leave empty for the original language.

## `includeSegments` (type: `boolean`):

Include the segments array ({ start, dur, end, text } in seconds) alongside the plain-text transcript.

## `includeSrt` (type: `boolean`):

Add an srt field with ready-to-save SubRip subtitles.

## `includeVtt` (type: `boolean`):

Add a vtt field with ready-to-save WebVTT subtitles.

## `includeVideoMetadata` (type: `boolean`):

Title, channel, views, likes, publish date, duration, category, keywords and chapters on every record (no extra requests — it comes from the same page).

## `monitorMode` (type: `boolean`):

Remember every video already delivered and emit only videos not seen in previous runs. Combine with an Apify Schedule on channel/playlist/search inputs to get transcripts of new uploads only — the schedule triggers the runs, monitor mode deduplicates across them.

## `maxResults` (type: `integer`):

Stop after this many records in total. 0 = no limit (opt-in; mind the run timeout on huge sweeps).

## `maxVideosPerSource` (type: `integer`):

Per-source expansion cap so one huge channel can't crowd out the others. 0 = use the global limit.

## `proxyConfiguration` (type: `object`):

Residential proxies strongly recommended — YouTube limits caption downloads from datacenter IPs.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://youtu.be/jNQXAC9IVRw",
    "iG9CE55wbtY"
  ],
  "channelUrls": [
    "@mkbhd",
    "https://www.youtube.com/@lexfridman"
  ],
  "playlistUrls": [
    "https://www.youtube.com/playlist?list=PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj"
  ],
  "searchQueries": [
    "ai agents tutorial"
  ],
  "searchSort": "relevance",
  "language": "en",
  "fallbackToAutoCaptions": true,
  "fallbackToAnyLanguage": true,
  "translateTo": "en",
  "includeSegments": true,
  "includeSrt": false,
  "includeVtt": false,
  "includeVideoMetadata": true,
  "monitorMode": false,
  "maxResults": 25,
  "maxVideosPerSource": 25,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped records in the default dataset. Transcript rows carry the full text, segments and video metadata; no-caption videos carry metadata plus transcriptUnavailableReason.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://youtu.be/jNQXAC9IVRw",
        "iG9CE55wbtY"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/youtube-transcript-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://youtu.be/jNQXAC9IVRw",
        "iG9CE55wbtY",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/youtube-transcript-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://youtu.be/jNQXAC9IVRw",
    "iG9CE55wbtY"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapesage/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/youtube-transcript-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/YZfMLDx0XAbWI4vSx/builds/fGGXI8CON5ksDnBDq/openapi.json
