# YouTube Transcript Scraper (`calm_builder/youtube-transcript-scraper`) Actor

Scrape YouTube transcripts and captions from videos, Shorts, channels and playlists. Full text in every result plus downloadable TXT and SRT files, timed segments, and every caption language the video offers. Fast and low cost.

- **URL**: https://apify.com/calm_builder/youtube-transcript-scraper.md
- **Developed by:** [Coder](https://apify.com/calm_builder) (community)
- **Categories:** Automation, Social media, Videos
- **Features:** Limited permissions
- **Stats:** 23 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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

Scrape **YouTube transcripts and captions** from videos, Shorts, live replays, and whole channels or playlists. Every transcript comes as **full text in the results**, plus **downloadable .txt and .srt files**, optional **timed segments**, in **any caption language the video has**. No YouTube account, no login and no API key needed.

Use it for **AI / LLM datasets and RAG**, **content research and summaries**, **SEO and keyword research**, **subtitles and translation workflows**, **accessibility**, and **quotes and fact-checking**.

### What you get

#### One row per video and language

Each row has the video (ID, link, title, type, channel, duration, publish date), the caption **language**, whether it is **auto-generated**, the **languages the video offers**, a **word count**, the **full transcript text**, and links to the **.txt** and **.srt** files.

#### Downloadable files

Every transcript is also saved to the run's key-value store as `<videoId>_<language>.txt` and `.srt` (and `.json` with timed segments when turned on), so you can download subtitles directly or skip the text in the results to keep them small.

#### Timed segments (optional)

Every caption line with its start time and duration - ready for search-inside-video, clipping or your own subtitle format.

#### Video details (optional add-on)

Description, views, likes, comment count, tags, category and more for each video, in a separate table.

### Input

| Field | What it does |
| --- | --- |
| **YouTube links** | Video, Short and live links, `youtu.be` links, and channel (URL or `@handle`) or playlist links |
| **Transcript languages** | e.g. `en`, `es`, `pt-BR` - one row per language the video has. Empty = each video's own language |
| **Include transcript text in results** | On by default. Turn off to use only the file links |
| **Include timed segments** | Every caption line with start time and duration (+ a .json file) |
| **Videos per channel or playlist** | For channel and playlist links: this many of the newest videos |
| **Published after** | For channel and playlist links: only newer videos |
| **$ Add video details** | Adds a full video row per video in its own table |

#### Example input

```json
{
    "startUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://www.youtube.com/@mkbhd"
    ],
    "transcriptLanguages": ["en"],
    "maxVideos": 10
}
```

### Example output

```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)",
    "videoType": "video",
    "channel": { "id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley", "handle": "@RickAstleyYT", "url": "https://www.youtube.com/@RickAstleyYT" },
    "duration": "3:34",
    "durationSeconds": 214,
    "publishedAt": "2009-10-25T06:57:33Z",
    "language": "en",
    "languageName": "English",
    "isAutoGenerated": false,
    "availableLanguages": ["en", "de-DE", "ja", "pt-BR", "es-419"],
    "wordCount": 402,
    "text": "We're no strangers to love You know the rules and so do I ...",
    "txtUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/dQw4w9WgXcQ_en.txt",
    "srtUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/dQw4w9WgXcQ_en.srt"
}
```

***

### Pricing

You pay only for transcripts you receive - never for links, retries, or videos without captions in your language.

| Result | Price per 1,000 |
| --- | --- |
| Transcript (one video, one language, text + files) | **$2.00** |
| Video details add-on (per video) | **$1.50** |

Prices are for the Apify Free plan; paid Apify plans get lower prices automatically. **Files, timed segments and date filters are free.** You can set a maximum cost per run in the run options - the Actor stops cleanly when it is reached.

### Free plan

On Apify's free plan a run uses up to 5 links, 5 videos per channel or playlist and 1 language. Every feature works, so you can try all of them before upgrading.

### Good to know

- **Languages:** only the caption languages YouTube offers for that video are returned (`availableLanguages` lists them); a language the video does not have is skipped. Manual captions are preferred over auto-generated ones.
- **Excel:** a spreadsheet cell holds about 32,000 characters (roughly a 30-minute video). For longer videos use the `.txt` link, or export as JSON / CSV.
- **No captions:** videos without captions in your languages, upcoming streams, and private or removed videos are skipped and not charged; the run log says how many.
- Want comments, channel profiles, search results or community posts too? Use our **YouTube Scraper**.

### FAQ

**Do I need a YouTube account or API key?** No. Everything is public data, collected without logging in.

**Where are the files?** In the run's key-value store (Storage tab), and each row links to its own files (`txtUrl`, `srtUrl`, `jsonUrl`).

**Can I get transcripts for a whole channel?** Yes - paste the channel link or `@handle` and set "Videos per channel or playlist". Use "Published after" for only recent uploads.

# Actor input Schema

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

One per row: video, Short or live links (watch, youtu.be, /shorts/, /live/), and channel (URL or @handle) or playlist links. For a channel or playlist, the transcripts of its newest videos are collected.

## `transcriptLanguages` (type: `array`):

Language codes, e.g. en, es, de, pt-BR. One row per language the video offers (manual captions preferred over auto-generated). Leave empty for each video's own language. A language the video does not offer is skipped.

## `includeTranscriptText` (type: `boolean`):

Put the full transcript text in each row. Turn off to keep rows small and use only the .txt / .srt file links.

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

Adds every caption line with its start time and duration (in the row and as a .json file).

## `maxVideos` (type: `integer`):

For channel and playlist links: how many of the newest videos to take. Video links are always used.

## `publishedAfter` (type: `string`):

For channel and playlist links: only videos published after this date (exact date or e.g. '30 days').

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

Extra charge per video. Adds one row per video in its own table: description, views, likes, comment count, tags, category and more. Title, channel, duration and publish date are already in every transcript row for free.

## `country` (type: `string`):

YouTube shows content availability for this country.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/@mkbhd"
  ],
  "transcriptLanguages": [
    "en"
  ],
  "includeTranscriptText": true,
  "includeTimestamps": false,
  "maxVideos": 10,
  "includeVideoDetails": false,
  "country": "US"
}
```

# Actor output Schema

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

No description

## `videos` (type: `string`):

No description

## `files` (type: `string`):

No description

# 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 = {
    "startUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://www.youtube.com/@mkbhd"
    ],
    "transcriptLanguages": [
        "en"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("calm_builder/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 = {
    "startUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://www.youtube.com/@mkbhd",
    ],
    "transcriptLanguages": ["en"],
}

# Run the Actor and wait for it to finish
run = client.actor("calm_builder/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 '{
  "startUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/@mkbhd"
  ],
  "transcriptLanguages": [
    "en"
  ]
}' |
apify call calm_builder/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,calm_builder/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/miHJCf57BH6l4PD2H/builds/Okd0bObWyET3AOvAL/openapi.json
