# YouTube Transcript Scraper: Subtitles, SRT, VTT & Chunks (`hxckya/youtube-transcript-subtitles-scraper`) Actor

Scrape YouTube transcripts, subtitles and captions from videos, Shorts, playlists and channels, with views, likes and publish date on every row. Pick or translate languages and export text, timestamps, SRT, WebVTT or LLM-ready chunks. No charge for videos without captions.

- **URL**: https://apify.com/hxckya/youtube-transcript-subtitles-scraper.md
- **Developed by:** [KO HYESONEUNG](https://apify.com/hxckya) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 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?

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 & Subtitles Scraper

Get the transcript of any public YouTube video, and of whole **playlists** and **channels**, in the language you want. Timestamps are kept. Captions can be **translated into 100+ languages** by YouTube's own caption translation.

Paste video links, Shorts, playlists or channel handles. You get one clean row per video: the full text, timed segments, and optionally SRT, WebVTT, `[mm:ss]` timestamped text, or **AI-ready chunks** with their start and end times. The same row carries the **video stats**: publish date, views, likes, category, duration, thumbnail and whether it is a Short, so one run answers both "what was said" and "how did it do".

### YouTube transcripts for AI, SEO and subtitles

- **Feed videos to an LLM:** summarise a talk, answer questions about a course, or build a RAG index of a channel. Chunks come with timestamps, so answers can cite the exact moment.
- **Content and SEO:** turn videos into blog posts, show notes and quotes. Research what a niche talks about across hundreds of videos.
- **Subtitles:** download SRT or VTT in the original language or a translation, ready for an editor or player.
- **Research and monitoring:** collect everything a channel said about a topic, with publish dates, views and likes next to each transcript.

### YouTube transcript API: what you get

- **Every URL shape:** `watch?v=`, `youtu.be`, Shorts, `/live/`, `/embed/`, bare video IDs, playlist URLs, and channels (`@handle`, `/channel/UC…`, `/c/…`, `/user/…`).
- **Channels and playlists expanded:** set *Max videos per playlist or channel*. For channels, the newest uploads come first.
- **Language control:** give an ordered list such as `en, en-GB, es`. Creator-uploaded captions are preferred over automatic ones, and you can fall back to the video's own language.
- **Translation:** set *Translate to* (`ko`, `de`, `pt`…). YouTube's caption translation keeps every timestamp.
- **Formats:** plain text, timed segments (`start`, `duration`, `text`), timestamped text, SRT, WebVTT and chunks of a size you choose.
- **Video stats:** title, channel name, channel ID and URL, publish date, view and like counts, category, duration, the largest thumbnail, and Short and live flags. You can add the description, and every row lists the caption languages available.
- **No API key or login:** no Google Cloud project, no YouTube Data API key and no YouTube account.
- **Fair billing:** videos without captions, private videos and bad links still get a row with an `error`, and **you are not charged** for them.

### How to scrape YouTube transcripts from videos, playlists and channels

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=aircAruvnKk",
    "https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi",
    "@3blue1brown"
  ],
  "languages": ["en"],
  "translateTo": "",
  "maxVideosPerSource": 50,
  "includeSegments": true,
  "includeTimestampedText": false,
  "includeSrt": false,
  "includeVtt": false,
  "chunkChars": 0
}
```

### Transcript output: text, timestamps, SRT, VTT and chunks

One row per video. The dataset has *Overview*, *Video stats* and *Transcript text* views, and exports to JSON, CSV, Excel or HTML, or through the API. This row was produced with `translateTo: "ko"` and `chunkChars: 1500`:

```json
{
  "videoId": "aircAruvnKk",
  "url": "https://www.youtube.com/watch?v=aircAruvnKk",
  "title": "But what is a neural network? | Deep learning chapter 1",
  "channelName": "3Blue1Brown",
  "channelId": "UCYO_jab_esuFRV4b17AJtAw",
  "channelUrl": "https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw",
  "publishDate": "2017-10-05T08:11:25-07:00",
  "durationSeconds": 1120,
  "viewCount": 24251528,
  "likeCount": 560552,
  "category": "Education",
  "isShort": false,
  "isLive": false,
  "thumbnailUrl": "https://i.ytimg.com/vi/aircAruvnKk/maxresdefault.jpg",
  "language": "ko",
  "languageName": "Korean",
  "originalLanguage": "en",
  "isAutoGenerated": false,
  "translatedTo": "ko",
  "wordCount": 3218,
  "segmentCount": 280,
  "transcript": "이건 숫자 3입니다. 글씨도 엉성하고 해상도도 28x28 픽셀로 아주 낮지만, 당신의 뇌는 아무 문제 없이 이걸 3으로 인식합니다. 뇌가 이렇게 쉽게 뭔가를 인식할 수 있다는 게 얼마나 신기한 일인지 잠시 생각해 보 …",
  "segments": [
    {
      "start": 4.22,
      "duration": 1.18,
      "text": "이건 숫자 3입니다."
    },
    {
      "start": 6.06,
      "duration": 4.653,
      "text": "글씨도 엉성하고 해상도도 28x28 픽셀로 아주 낮지만,"
    }
  ],
  "timestampedText": "[0:04] 이건 숫자 3입니다.\n[0:06] 글씨도 엉성하고 해상도도 28x28 픽셀로 아주 낮지만,\n…",
  "chunks": [
    {
      "index": 0,
      "start": 4.22,
      "end": 171.66,
      "text": "이건 숫자 3입니다. 글씨도 엉성하고 해상도도 28x28 픽셀로 아주 낮지만, 당신의 뇌는 아무 문제 없이 이걸 3으로 인식합니다. 뇌가 이렇게 …"
    }
  ],
  "availableLanguages": [
    {
      "code": "ar",
      "name": "Arabic",
      "isAutoGenerated": false,
      "isTranslatable": true
    },
    {
      "code": "bn",
      "name": "Bangla",
      "isAutoGenerated": false,
      "isTranslatable": true
    },
    {
      "code": "zh",
      "name": "Chinese",
      "isAutoGenerated": false,
      "isTranslatable": true
    }
  ]
}
```

### Pricing: one event is one transcript

You pay **per transcript delivered**: one event is one video that returned a transcript. The price is on the Pricing tab. Videos that have no captions, or cannot be read, are free. You can cap the cost of each run, and the run stops cleanly at the cap.

### YouTube transcript API and integrations

- **API:** start a run with a list of URLs and read the dataset. The *API* tab has snippets for curl, Node.js and Python.
- **Integrations:** Make, Zapier, n8n and Google Sheets through Apify integrations.

### Use it with AI agents (MCP)

AI assistants such as Claude, ChatGPT and Cursor can find and run this Actor through the [Apify MCP server](https://mcp.apify.com): they search the Store with `search-actors`, read the input with `fetch-actor-details` and start a run with `call-actor`. To give an agent only this tool, connect it to `https://mcp.apify.com?tools=hxckya/youtube-transcript-subtitles-scraper`. Because the Actor is priced per event, agents can also pay for runs with the MCP server's agentic payments.

Example prompt:

> Get the English transcripts of the last 10 videos on @3blue1brown, split into 1,500-character chunks, then summarise each video in three bullets and give the timestamp each bullet comes from.

### Good to know: captions, private videos and proxies

- The Actor reads **captions that already exist** on YouTube, whether uploaded by the creator or generated automatically. It does not download video or audio or run speech recognition, so a video without captions returns an error row, free of charge.
- Publish date, likes, category and the Short flag come from a second, very small request per video. If that request fails, the transcript is still delivered and those fields are `null`. `likeCount` is also `null` when YouTube shows no like count for the video.
- Only public videos are supported. Private, members-only and some age-restricted videos cannot be read.
- Requests go directly to YouTube first. If YouTube asks to confirm they are not from a bot, which is common from cloud servers, the run switches to the **Proxy** automatically (Apify residential proxy by default). Turn on *Always use the proxy* if runs keep getting challenged.
- This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by YouTube or Google. "YouTube" is used only to describe which site the captions come from.
- Transcripts belong to the video creators. Use them in line with YouTube's terms and copyright law. Summaries, research, accessibility and quotes with attribution are common uses.

### FAQ

#### Does it work without a YouTube Data API key?

Yes. There is no API key, Google Cloud project or login to set up. For other people's videos the official YouTube Data API is not an option anyway: its `captions.download` method requires permission to edit the video and costs 200 quota units per call.

#### Does it work with YouTube Shorts and live streams?

Yes. Shorts, `/live/` and `youtu.be` links are read like any other video: if YouTube has captions for it, you get the transcript.

#### Can I get all the transcripts of a channel or playlist?

Yes. Add the channel (`@name`) or the playlist URL and set *Max videos per playlist or channel*.

#### Which languages are available?

Whatever the video has, listed in `availableLanguages` on each row, plus any translation target YouTube supports through *Translate to*.

#### Why does a video return "no captions"?

Its creator turned captions off, or YouTube has not generated any yet. The Actor does not transcribe audio itself. You are not charged for it.

#### Can I get subtitles for my video editor?

Turn on *SRT subtitles* or *WebVTT subtitles* and copy the field into a `.srt` or `.vtt` file.

#### Can I get likes, publish dates and subscriber counts too?

Views, likes, publish date, category and the thumbnail are on every row with a transcript, at no extra cost. For channel subscriber counts, use [YouTube Scraper: Channels, Search & Playlists](https://apify.com/hxckya/youtube-scraper-channels-search-playlists).

### Changelog

- **1.1:** Video stats on every transcript row: publish date, like count, category, Short flag and the largest thumbnail, next to the views, duration and channel already there, plus a *Video stats* view. Same price per transcript.
- **1.0:** First release. Videos, Shorts, playlists and channels; language preference and translation; text, segments, timestamped text, SRT, VTT and chunks. No charge for videos without captions.

# Actor input Schema

## `urls` (type: `array`):

One per line. Video or Shorts URLs, youtu.be links, 11-character video IDs, playlist URLs, or channels (https://www.youtube.com/@name, @name, or a channel URL). Playlists and channels are expanded into their videos.

## `languages` (type: `array`):

Caption languages to look for, in order of preference (ISO codes such as en, es, ko, pt-BR). The first one the video has is used.

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

If none of the preferred languages exist, use the video's own captions instead of skipping it.

## `preferManualCaptions` (type: `boolean`):

Use captions uploaded by the creator when both they and YouTube's automatic captions exist.

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

Optional language code (for example en, ko, es, de). YouTube's own caption translation is used, so timestamps are kept. Leave empty to keep the original language.

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

Limit for each playlist or channel you add. Newest uploads come first for channels.

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

Include every caption line with its start time and duration in seconds.

## `includeTimestampedText` (type: `boolean`):

Include a readable text with \[mm:ss] markers, handy for notes and for citing a moment in LLM answers.

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

Include the transcript as an SRT subtitle file.

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

Include the transcript as a WebVTT subtitle file.

## `chunkChars` (type: `integer`):

Split the transcript into chunks of about this many characters, each with its start and end time, ready for embeddings or RAG. 0 turns chunking off.

## `includeDescription` (type: `boolean`):

Include the video's description text.

## `maxConcurrency` (type: `integer`):

How many videos to process at the same time.

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

Requests go directly to YouTube first. If YouTube asks to confirm they are not from a bot (common from cloud servers), the run switches to this proxy automatically. Residential proxies work best.

## `alwaysUseProxy` (type: `boolean`):

Skip the direct attempt and send every request through the proxy.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=aircAruvnKk"
  ],
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": true,
  "preferManualCaptions": true,
  "maxVideosPerSource": 50,
  "includeSegments": true,
  "includeTimestampedText": false,
  "includeSrt": false,
  "includeVtt": false,
  "chunkChars": 0,
  "includeDescription": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "alwaysUseProxy": false
}
```

# Actor output Schema

## `overview` (type: `string`):

Per video: ID, URL, title, channel, caption language, whether captions are automatic, translation target, word count, duration, and an error if no transcript was available.

## `stats` (type: `string`):

Per video: thumbnail, title, URL, channel, publish date, views, likes, category, duration, whether it is a Short, caption language and word count.

## `text` (type: `string`):

Per video: title, URL, language and the full transcript as plain text.

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

Complete rows including segments with timings, SRT/VTT if requested, chunks, available caption languages and video metadata.

# 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 = {
    "urls": [
        "https://www.youtube.com/watch?v=aircAruvnKk"
    ],
    "languages": [
        "en"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("hxckya/youtube-transcript-subtitles-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 = {
    "urls": ["https://www.youtube.com/watch?v=aircAruvnKk"],
    "languages": ["en"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("hxckya/youtube-transcript-subtitles-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 '{
  "urls": [
    "https://www.youtube.com/watch?v=aircAruvnKk"
  ],
  "languages": [
    "en"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call hxckya/youtube-transcript-subtitles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hxckya/youtube-transcript-subtitles-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/WBAejuxZVqGWMZScP/builds/aqxwNzjlctocvXsNQ/openapi.json
