# YouTube Transcript Scraper — Bulk Captions & Subtitles (`vero-api/youtube-transcript-scraper`) Actor

Get YouTube transcripts in bulk: clean text, timestamped lines and SRT/VTT subtitles for any list of videos, Shorts and live replays, with title, channel and views. Original language or any caption language. Ready for AI, RAG and automation.

- **URL**: https://apify.com/vero-api/youtube-transcript-scraper.md
- **Developed by:** [VeroAPIs](https://apify.com/vero-api) (community)
- **Categories:** Videos, AI, Social media
- **Features:** Limited permissions
- **Stats:** 8 total users, 1 monthly users, 94.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 transcripts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Transcript Scraper: bulk captions & subtitles

**YouTube Transcript Scraper** extracts the **full transcript, captions and subtitles** of any YouTube video, including **Shorts and live replays**, and returns them as **clean, readable text**, **timestamped segments** and ready-to-use **SRT/WebVTT subtitle files**. Paste **one video or thousands** in a single run. You get each transcript in the **language spoken in the video** automatically, or in any caption language the video offers, together with **video details** (title, channel, thumbnail, views, duration, description and tags) at no extra cost. **Just $2 per 1,000 transcripts.**

It runs in the cloud, needs **no API key** and **no setup**, and exports to **JSON, CSV, Excel or XML**. Paste your links, click **Start**, and get structured transcript data ready for your app, **AI agent**, or **RAG / LLM** pipeline.

### What data does it extract?

| Data | Details |
|---|---|
| 📝 **Full text** | The whole transcript as one clean, continuous block of text, ready for summarizing, search or NLP |
| ⏱️ **Timestamped segments** | Every caption line with its `start` time and `duration` in seconds |
| 🎬 **Subtitle files** | The transcript as ready-to-use **SRT** and/or **WebVTT** subtitles |
| 🈳 **Languages** | The transcript's language, whether YouTube auto-generated it, and every other caption language the video offers |
| 📺 **Video details** | Title, channel name, channel URL, thumbnail, view count, duration, description, tags and live-stream status |
| 📊 **Stats** | Word count (counted properly for every language, Japanese and Chinese included), character count and number of caption lines |

### How to scrape YouTube transcripts

1. **Add your videos.** Paste one or many YouTube video links (`watch`, `youtu.be`, `shorts`, `embed` or `live`) or bare 11-character video IDs. You get one transcript per video, and duplicate links are skipped.
2. **Pick a language** *(optional)*. Leave it on **Auto-detect** to get the language spoken in each video, or choose any caption language. Add **fallback languages** to try next, in order, when a video doesn't have your first choice.
3. **Choose the captions** *(optional)*. Accept any captions (human-made first), or only human-made or only auto-generated ones.
4. **Choose the output** *(optional)*. Include timestamped segments, add SRT/WebVTT subtitle files, and fetch video details.
5. **Click Start.** Download the results from the **Output** tab in any format, or send them anywhere with integrations.

### Input example

Send your videos as a list in `videoUrls`:

```json
{
    "videoUrls": [
        "https://www.youtube.com/watch?v=IELMSD2kdmk",
        "https://youtu.be/dQw4w9WgXcQ",
        "https://www.youtube.com/shorts/VIDEO_ID"
    ],
    "transcriptLanguage": "en",
    "fallbackLanguages": ["auto"],
    "captionType": "any",
    "includeTimestamps": true,
    "additionalFormats": ["srt"],
    "includeVideoDetails": true
}
```

This asks for English captions and falls back to the language spoken in the video when a video has no English track.

### Output example (abridged)

```json
{
    "url": "https://www.youtube.com/watch?v=IELMSD2kdmk",
    "videoId": "IELMSD2kdmk",
    "title": "Apache Spark in 100 Seconds",
    "channelName": "Fireship",
    "channelUrl": "https://www.youtube.com/channel/UCsBjURrPoezykLs9EqgamOA",
    "channelId": "UCsBjURrPoezykLs9EqgamOA",
    "thumbnailUrl": "https://i.ytimg.com/vi_webp/IELMSD2kdmk/sddefault.webp",
    "viewCount": 569973,
    "language": "English (auto-generated)",
    "languageCode": "en",
    "isGenerated": true,
    "durationSeconds": 199,
    "snippetCount": 101,
    "wordCount": 675,
    "characterCount": 3826,
    "text": "Apache spark an open- Source data analytics engine that can process massive streams of data from multiple sources…",
    "segments": [
        { "text": "Apache spark an open- Source data", "start": 0.32, "duration": 4.08 },
        { "text": "analytics engine that can process", "start": 2.48, "duration": 3.839 }
    ],
    "srt": "1\n00:00:00,320 --> 00:00:02,480\nApache spark an open- Source data\n\n2\n…",
    "availableLanguages": [
        { "language": "English (auto-generated)", "languageCode": "en", "isGenerated": true }
    ],
    "retrievedAt": "2026-10-24T12:00:00.000Z"
}
```

Every result tells you which language you got, plus every other caption language the video offers. A video that has no transcript gets its own row with an `error` code and a plain explanation, such as `TranscriptsDisabled` or `NoTranscriptInLanguage`, so you always know what happened to each link. The **Output** table shows that explanation in its **Note** column.

### Why scrape YouTube transcripts?

- **AI, RAG & LLMs**: feed clean transcripts to an LLM to summarize, answer questions, generate show notes, or build **retrieval-augmented generation (RAG)** pipelines, embeddings and semantic search over video content.
- **Content repurposing**: turn videos into blog posts, newsletters or social media threads.
- **SEO**: publish transcripts to make video content indexable and searchable.
- **Research & analysis**: collect and text-mine spoken content at scale, across whole lists of videos.
- **Accessibility & localization**: generate subtitles in any caption language the video provides.
- **Search archives**: build a searchable database of everything said across your list of videos on a topic.

### Pricing

**$2 per 1,000 transcripts** ($0.002 each), with video details included at no extra cost and no subscription. You pay only for the transcripts you get: videos without captions, private or unavailable videos, and languages a video doesn't have are reported for free. The run stops right at the spending limit you set, so you never pay more than you planned, and the run summary tells you how many links were left for next time.

### FAQ

#### Do I need an API key or login?

No. The actor reads publicly available transcripts. Just provide the video links.

#### Do I need to set anything up?

No. Reliable access to YouTube is handled for you, with nothing to configure.

#### How many videos can I transcribe in one run?

As many as you like. Paste a long list and the actor works through it, up to 20 videos at a time, delivering one row per video. Rows arrive as each video finishes, so match them to your list by their `url` or `videoId`.

#### Which languages can I get?

Leave `transcriptLanguage` on **Auto-detect** (`"auto"`) to get the language spoken in each video, the most reliable option since it always returns a track the video actually has. For videos with only human-made captions, such as music videos, Auto-detect picks the captions written in the same language as the video's title and description.

To request a specific language, pick it from the list or type any YouTube caption code, for example `"de"`, `"pt-BR"`, `"zh-Hant"`, `"es-419"` or `"iw"` (Hebrew; `"he"` works too). A base language like `en` also matches regional tracks such as `en-US` or `en-GB`, and human-made captions are preferred over auto-generated ones. Regional Chinese codes pick the right script: `zh-TW` and `zh-HK` get Traditional Chinese, `zh-CN` gets Simplified. Transcripts are always genuine YouTube caption tracks, never machine translations. If a video has no captions in the language you ask for, its row carries a `NoTranscriptInLanguage` error listing the languages it does offer, free of charge.

#### Can I give a list of languages to try?

Yes. Put your first choice in `transcriptLanguage` and add more codes to `fallbackLanguages`. They are tried in order, and `"auto"` at the end falls back to the language spoken in the video. For example, `"transcriptLanguage": "es"` with `"fallbackLanguages": ["en", "auto"]` gives you Spanish, then English, then the original language.

#### Can I get only human-made or only auto-generated captions?

Yes. Set `captionType` to `"manual"` for human-made captions only, or `"generated"` for YouTube's auto-generated captions only. The default, `"any"`, takes human-made captions first.

#### Can I get subtitle files?

Yes. Add `srt` and/or `vtt` to `additionalFormats` and each result includes ready-to-use subtitle text you can save as `.srt` or `.vtt` files. Auto-generated lines end where the next one begins, so they no longer overlap on screen, and human-made subtitles keep their original timing.

#### What kinds of links can I paste?

Standard watch URLs, `youtu.be` short links, Shorts, `embed` and `live` URLs, mobile and music URLs, and bare 11-character video IDs. Paste links to individual videos: each one gives you a transcript. Playlist and channel pages are listed in the results as not being single videos, free of charge.

#### What happens if a video has no transcript?

You get a row for it with an `error` code and a plain-language `errorMessage`, and you are not charged for it. The rest of the run carries on.

#### Can I run it on a schedule?

Yes. Use the **Schedule** option to run it on any cron expression, and pair it with webhooks or integrations to push fresh transcripts wherever you need them.

#### Can I call it like an API?

Yes. Start runs and fetch results with the [Apify API](https://docs.apify.com/api/v2):

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('vero-api/youtube-transcript-scraper').call({
    videoUrls: ['https://www.youtube.com/watch?v=IELMSD2kdmk', 'https://youtu.be/dQw4w9WgXcQ'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Can I use it from my AI assistant?

Yes. Claude, Cursor, VS Code and any assistant that supports MCP can call it. Add this server to its MCP settings:

```json
{
    "mcpServers": {
        "youtube-transcript-scraper": {
            "url": "https://mcp.apify.com?tools=vero-api/youtube-transcript-scraper"
        }
    }
}
```

Then ask, for example: *"Summarize the transcripts of these three YouTube videos."*

#### Is this an official YouTube product?

No. YouTube Transcript Scraper is an independent tool. It is not affiliated with, endorsed by or sponsored by YouTube or Google.

### Integrations

Connect YouTube Transcript Scraper to **Google Sheets, Make, Zapier, n8n, Slack, Airbyte**, or any tool via webhooks. Developers can start runs and fetch results with the [Apify API](https://docs.apify.com/api/v2) using the JavaScript or Python clients. See the **API** tab for ready-made code.

### More tools from us

- [Instagram Reels & Posts Downloader](https://apify.com/vero-api/instagram-reels-posts-downloader): turn any reel or video post link into a direct MP4 download link, with its caption and stats.
- [Instagram Posts Scraper](https://apify.com/vero-api/instagram-posts-scraper): get the caption, hashtags, likes, comments and media behind any Instagram post link.
- [Threads Scraper](https://apify.com/vero-api/threads-scraper): export posts, profiles, search results and replies from Threads.
- [Telegram Channel Scraper](https://apify.com/vero-api/telegram-channel-scraper): get posts, views, reactions and media from public Telegram channels.
- [Spotify Play Count Scraper](https://apify.com/vero-api/spotify-play-count-scraper): get the exact play count of any Spotify track, plus listeners and credits.

### Feedback and feature requests

Missing a field you need? Open an issue in the **Issues** tab. Feedback directly shapes what gets added next.

# Changelog

This Actor's version history is a separate document: https://apify.com/vero-api/youtube-transcript-scraper/changelog.md

# Actor input Schema

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

Paste one or many YouTube video links or 11-character video IDs. Watch links, youtu.be links, Shorts and live replays all work, and you get one transcript per video. Use links to individual videos, not playlist or channel pages.

## `transcriptLanguage` (type: `string`):

Pick a language or type any YouTube caption code, such as en, pt-BR, zh-Hant or iw. Leave it on Auto-detect to get the language spoken in each video. A base code like en also matches regional captions such as en-US, and human-made captions come first. A video without captions in this language gets a free row listing the languages it does offer.

## `fallbackLanguages` (type: `array`):

Language codes to try, in order, when a video has no captions in the transcript language, for example es and then en. Add auto at the end to fall back to the language spoken in the video.

## `captionType` (type: `string`):

Which captions to accept. Any takes human-made captions first and auto-generated ones when that is all a video has.

## `additionalFormats` (type: `array`):

Also include the transcript as ready-to-use subtitle files in the chosen formats.

## `includeTimestamps` (type: `boolean`):

Include the segments list: every caption line with its start time and duration in seconds. Turn it off for plain text only.

## `includeVideoDetails` (type: `boolean`):

Add the video's title, channel name, channel URL, thumbnail, view count, description, tags and live-stream status. Included at no extra cost.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=IELMSD2kdmk"
  ],
  "transcriptLanguage": "auto",
  "fallbackLanguages": [],
  "captionType": "any",
  "additionalFormats": [],
  "includeTimestamps": true,
  "includeVideoDetails": true
}
```

# Actor output Schema

## `transcripts` (type: `string`):

One item per video with every field: url, videoId, title, channelName, language, languageCode, isGenerated, durationSeconds, wordCount, text, segments, srt/vtt when requested, and availableLanguages. Videos without a transcript carry error and errorMessage instead.

# 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=IELMSD2kdmk"
    ],
    "transcriptLanguage": "auto"
};

// Run the Actor and wait for it to finish
const run = await client.actor("vero-api/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=IELMSD2kdmk"],
    "transcriptLanguage": "auto",
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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=IELMSD2kdmk"
  ],
  "transcriptLanguage": "auto"
}' |
apify call vero-api/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vero-api/youtube-transcript-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bsvweSramilEZcLUi/builds/HdQgsIzpteX6YPw0r/openapi.json
