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

Cheap, Reliable and best YouTube transcript scraper.

- **URL**: https://apify.com/naz\_here/youtube-transcript-scraper.md
- **Developed by:** [Nazmul Hasan](https://apify.com/naz_here) (community)
- **Categories:** Social media
- **Stats:** 177 total users, 1 monthly users, 100.0% runs succeeded, 5 bookmarks
- **User rating**: 3.37 out of 5 stars

## Pricing

$3.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.

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 Scraper

This project is a **YouTube Transcript Scraper** that retrieves transcripts for YouTube videos using the `youtube-transcript-api` library. It supports features like proxy management via WebShare, handling rate limits, and concurrent processing of multiple videos. The scraper is designed to work efficiently even when YouTube blocks requests by rotating proxies.

***

### Features

1. **Retrieve Transcripts**: Fetch transcripts for YouTube videos in multiple formats (JSON, SRT, VTT, or plain text).
2. **Proxy Management**: Use WebShare proxies to bypass IP bans and rate limits.
3. **Concurrency Control**: Process multiple videos concurrently with configurable concurrency limits.
4. **Retry Mechanism**: Automatically retry failed requests up to a configurable number of attempts.
5. **Rate Limiting Handling**: Detect and handle rate limits by switching proxies and adding cooldown periods.
6. **Custom Logging**: Minimal logging in non-debug mode with detailed logs available in debug mode.
7. **Language Preference**: Specify preferred languages for transcripts.

***

#### Input Parameters

| Parameter               | Type    | Description                                                                 |
|-------------------------|---------|-----------------------------------------------------------------------------|
| `videoUrls`             | List    | List of YouTube video URLs to process.                                      |
| `language`              | String  | Preferred language for transcripts (e.g., `en` for English).               |
| `includeAutoGenerated`  | Boolean | Whether to include auto-generated transcripts.                              |
| `outputFormat`          | String  | Output format for transcripts (`json`, `txt`, `srt`, or `vtt`).            |
| `maxConcurrency`        | Integer | Maximum number of videos to process concurrently.                          |
| `minDelayBetweenVideos` | Integer | Minimum delay (in seconds) between processing batches of videos.           |
| `cooldownPeriod`        | Integer | Cooldown period (in seconds) when rate limits are detected.                |
| `youtubeApiKey`         | String  | YouTube Data API key for fetching video metadata (optional).               |
| `debugMode`             | Boolean | Enable debug mode for detailed logging.                                    |

***

#### Example Input

```json
{
  "videoUrls": ["https://youtu.be/oFqwcngsts8", "https://youtu.be/another_video_id"],
  "language": "en",
  "includeAutoGenerated": true,
  "outputFormat": "json",
  "maxConcurrency": 3,
  "minDelayBetweenVideos": 5,
  "cooldownPeriod": 60,
  "youtubeApiKey": "YOUR_YOUTUBE_API_KEY",
  "useWebshareProxy": true,
  "debugMode": false
}
```

#### Output

```
[
  {
    "videoId": "oFqwcngsts8",
    "url": "https://www.youtube.com/watch?v=oFqwcngsts8",
    "success": true,
    "language": "en",
    "transcript": [
      {
        "start": 0.2,
        "duration": 1.233,
        "text": "Hello there."
      },
      {
        "start": 1.433,
        "duration": 2.7,
        "text": "You see that? Those are three"
      },
      {
        "start": 4.133,
        "duration": 3,
        "text": "AI agents all chasing a cuboid."
      },
      {
        "start": 7.7,
        "duration": 3.783,
        "text": "Now, they have already been trained\non this channel before."
      },
      {
        "start": 12.416,
        "duration": 2.6,
        "text": "And today we have something"
      },
      {
        "start": 15.016,
        "duration": 3,
        "text": "even more exciting."
      },
      {
        "start": 24.016,
        "duration": 1.867,
        "text": "This is a centipede."
      },
      {
        "start": 25.883,
        "duration": 3.717,
        "text": "A multi-legged organism\nbelonging to family myriapods."
      },
      {
        "start": 29.633,
        "duration": 5.45,
        "text": "At the moment, it is nothing\nbut a 3D model capable of nothingness."
      },
      {
        "start": 35.1,
        "duration": 3.116,
        "text": "In order to bring it alive,\nit needs a brain."
      },
      {
        "start": 38.25,
        "duration": 3,
        "text": "Ladies and gentlemen, let's call the brain"
      },
      {
        "start": 41.25,
        "duration": 3,
        "text": "a neural network."
      },
      {
        "start": 48.616,
        "duration": 0.734,
        "text": "Today"
      },
      {
        "start": 49.35,
        "duration": 4.383,
        "text": "we are using a network with 2048 nodes\nand two layers."
      },
      {
        "start": 53.75,
        "duration": 2.7,
        "text": "We will train it\nusing a classic reinforcement"
      },
      {
        "start": 56.45,
        "duration": 3.033,
        "text": "algorithm called proximal policy\noptimization."
      },
      {
        "start": 59.516,
        "duration": 1.65,
        "text": "Now hold your horses, folks."
      },
      {
        "start": 61.166,
        "duration": 4.384,
        "text": "You see, this centipede\nmodel is very clean and realistic."
      },
      {
        "start": 65.566,
        "duration": 5.05,
        "text": "Too clean, I must say. The first prototype\nwas nowhere near this accurate."
      },
      {
        "start": 70.65,
        "duration": 3.833,
        "text": "In fact, it was an absolute nightmare."
      },
      {
        "start": 79.5,
        "duration": 2.4,
        "text": "Ladies and gentlemen, introducing."
      },
      {
        "start": 81.9,
        "duration": 0.916,
        "text": "He don't bite."
      },
      {
        "start": 82.816,
        "duration": 4.667,
        "text": "This mutation has seven body segments\nand 14 elongated limbs."
      },
      {
        "start": 87.5,
        "duration": 3.716,
        "text": "We will now attempt to train this creature\nto walk."
      },
      {
        "start": 91.25,
        "duration": 4.716,
        "text": "To achieve this, we will give the AI\nfull body control over all of its limbs."
      },
      {
        "start": 95.966,
        "duration": 3,
        "text": "Precisely two degrees of freedom\nper leg in the"
      },
      {
        "start": 98.966,
        "duration": 3,
        "text": "Y and Z rotational axis is."
      },
      {
        "start": 102.35,
        "duration": 3.4,
        "text": "We will reward the\nAI for matching the arrows direction"
      },
      {
        "start": 105.75,
        "duration": 3.733,
        "text": "and maintaining velocity\nas fast as it possibly can."
      },
      {
        "start": 109.5,
        "duration": 3.05,
        "text": "For self-awareness,\nwe will feed the neural network"
      },
      {
        "start": 112.55,
        "duration": 3.25,
        "text": "the XYZ,\nthe angles of each controllable bone."
      },
      {
        "start": 115.8,
        "duration": 2.75,
        "text": "This helps the agent understand\nits current pose."
      },
      {
        "start": 118.55,
        "duration": 3.216,
        "text": "The angles will be stacked twice,\nso the AI can also"
      },
      {
        "start": 121.766,
        "duration": 3,
        "text": "infer angular velocities over time."
      },
      {
        "start": 125.666,
        "duration": 3.05,
        "text": "Each leg is equipped\nwith a ground detection raycast."
      },
      {
        "start": 128.716,
        "duration": 3.9,
        "text": "This provides the agent\nlive data of its distance to the ground."
      },
      {
        "start": 133.933,
        "duration": 0.667,
        "text": "Gentlemen and"
      },
      {
        "start": 134.6,
        "duration": 3.333,
        "text": "ladies, we are now ready\nfor our first training session."
      },
      {
        "start": 137.933,
        "duration": 5.283,
        "text": "Let's find out how such a creature\nwould walk if one were to exist in nature."
      },
      {
        "start": 230.116,
        "duration": 1.35,
        "text": "Well, that was dramatic."
      },
      {
        "start": 231.466,
        "duration": 1.784,
        "text": "Do you know what's even more dramatic?"
      },
      {
        "start": 233.25,
        "duration": 3,
        "text": "The second prototype."
      },
      {
        "start": 237.983,
        "duration": 1.35,
        "text": "Our second prototype"
      },
      {
        "start": 239.333,
        "duration": 4.117,
        "text": "is much closer to a real life\ncentipede, boasting 21"
      },
      {
        "start": 243.45,
        "duration": 4.033,
        "text": "body segments\nwith a whopping 42 individual legs."
      },
      {
        "start": 247.5,
        "duration": 4.466,
        "text": "We will train this prototype\nusing similar methods as the first one."
      },
      {
        "start": 251.966,
        "duration": 3.384,
        "text": "Comrades, let's now train\na real centipede."
      },
      {
        "start": 332.416,
        "duration": 1.3,
        "text": "Congratulations!"
      },
      {
        "start": 333.716,
        "duration": 5,
        "text": "Our AI now exhibits locomotion\nsimilar to real life myriapods."
      },
      {
        "start": 339.233,
        "duration": 1.983,
        "text": "A biped has two legs."
      },
      {
        "start": 341.216,
        "duration": 3.65,
        "text": "Quadrupedal\nfour and myriapods have many legs."
      },
      {
        "start": 344.866,
        "duration": 3.234,
        "text": "The resulting movement\nis an excellent achievement."
      },
      {
        "start": 348.116,
        "duration": 3.834,
        "text": "Let me tell you why. You see the goal of an\nAI agent"
      },
      {
        "start": 351.95,
        "duration": 4.233,
        "text": "in a reinforcement learning\nsimulation is to maximize its rewards."
      },
      {
        "start": 356.216,
        "duration": 3.45,
        "text": "We rewarded the\nAI for matching the arrow's direction"
      },
      {
        "start": 359.666,
        "duration": 2.934,
        "text": "and most importantly, maintaining velocity."
      },
      {
        "start": 362.6,
        "duration": 3.483,
        "text": "The resulting gait is very close\nto real life centipedes,"
      },
      {
        "start": 366.083,
        "duration": 3.417,
        "text": "and scientifically it's called a metachronal gait."
      },
      {
        "start": 369.5,
        "duration": 4.016,
        "text": "A metachronal gait is a wave-like pattern\nof leg movements"
      },
      {
        "start": 373.516,
        "duration": 2.5,
        "text": "that ripples across the animal's body."
      },
      {
        "start": 376.016,
        "duration": 3.834,
        "text": "The legs don't move all at once,\nbut in a sequence,"
      },
      {
        "start": 379.85,
        "duration": 4.2,
        "text": "as some legs push off, others\nprepare to make contact with the ground."
      },
      {
        "start": 384.05,
        "duration": 2.516,
        "text": "This creates an illusion of a wave."
      },
      {
        "start": 386.566,
        "duration": 4.717,
        "text": "What fascinates me is,\ndespite this being a simplified simulation"
      },
      {
        "start": 391.283,
        "duration": 5.333,
        "text": "of a centipede body, the AI still learned\nto move in a metachronal manner."
      },
      {
        "start": 396.616,
        "duration": 1.3,
        "text": "Looks like evolution and"
      },
      {
        "start": 397.916,
        "duration": 4.917,
        "text": "our AI are in harmony\non how a many-legged organisms should walk."
      },
      {
        "start": 406.616,
        "duration": 1.384,
        "text": "Folks programing these"
      },
      {
        "start": 408,
        "duration": 3.3,
        "text": "AIs require knowledge of coding\nand mathematics"
      },
      {
        "start": 411.316,
        "duration": 3.067,
        "text": "concepts which can be difficult to master\non your own."
      },
      {
        "start": 414.383,
        "duration": 4.733,
        "text": "Luckily, it's 2025\nand you don't need an MIT degree"
      },
      {
        "start": 419.116,
        "duration": 3.067,
        "text": "to get started. With Brilliant's\ninteractive lessons,"
      },
      {
        "start": 422.183,
        "duration": 2.783,
        "text": "Having fun\nwhile learning has never been easier,"
      },
      {
        "start": 424.966,
        "duration": 5.2,
        "text": "they break down complex concepts into bite\nsized, engaging lessons, a method proven"
      },
      {
        "start": 430.166,
        "duration": 4.284,
        "text": "to be six times more effective\nfor learning than boring lecture videos."
      },
      {
        "start": 434.45,
        "duration": 3.183,
        "text": "Their programing courses\nteach you how to think in code"
      },
      {
        "start": 437.633,
        "duration": 4.583,
        "text": "rather than just memorizing syntax\nwith lessons on loops, conditionals,"
      },
      {
        "start": 442.216,
        "duration": 4.034,
        "text": "and algorithms that get you building\nreal programs from day one."
      },
      {
        "start": 446.25,
        "duration": 5.416,
        "text": "For those curious about AI, Brilliant's\ncourses on how large language models work"
      },
      {
        "start": 451.666,
        "duration": 4.8,
        "text": "provides fascinating insights into modern\nAI systems, showing you everything"
      },
      {
        "start": 456.466,
        "duration": 4.867,
        "text": "from how models build vocabularies to how\nthey make predictions and generate text."
      },
      {
        "start": 461.333,
        "duration": 4.117,
        "text": "To try, everything brilliant\nhas to offer free for a full 30 days"
      },
      {
        "start": 465.45,
        "duration": 4.216,
        "text": "visit brilliant.org/cozmouz\nor scan the QR code on screen."
      },
      {
        "start": 469.666,
        "duration": 3.517,
        "text": "You will also get 20% off\nan annual premium subscription."
      },
      {
        "start": 475.583,
        "duration": 1.433,
        "text": "It was 3 a.m."
      },
      {
        "start": 477.016,
        "duration": 4.184,
        "text": "and I was done with this project,\nbut something was bugging me."
      },
      {
        "start": 481.2,
        "duration": 5.5,
        "text": "While the model we trained is decent,\nit is very slow, I want faster."
      },
      {
        "start": 486.716,
        "duration": 1.584,
        "text": "So besides leg movement,"
      },
      {
        "start": 488.3,
        "duration": 3.933,
        "text": "we will now also allow the\nAI to control its body segments."
      },
      {
        "start": 492.233,
        "duration": 0.933,
        "text": "Remember folks,"
      },
      {
        "start": 493.166,
        "duration": 4.7,
        "text": "you enjoy the training montage\nwith delightful music in the background."
      },
      {
        "start": 497.866,
        "duration": 4.334,
        "text": "But for the AI,\nevery second of existence is mere"
      },
      {
        "start": 502.233,
        "duration": 3.383,
        "text": "torture, a negative penalty\nevery time step."
      },
      {
        "start": 505.616,
        "duration": 5.9,
        "text": "To make things worse, we will now\nalso bombard the AI with projectiles."
      },
      {
        "start": 511.516,
        "duration": 3.584,
        "text": "Comrades, this is cozmouz signing out."
      }
    ]
  }
]
```

### Features and Their Purposes

#### 1. **Retrieve Transcripts**

- Fetch transcripts for YouTube videos in multiple formats.
- Supports both manual and auto-generated transcripts.

#### 3. **Concurrency Control**

- Processes multiple videos concurrently to improve efficiency.
- Configurable `maxConcurrency` parameter to control the number of concurrent requests.

#### 4. **Retry Mechanism**

- Retries failed requests up to 10 times (configurable).
- Handles transient errors like network issues or temporary IP bans.

#### 5. **Rate Limiting Handling**

- Detects rate limits (HTTP 429) and switches proxies.
- Adds a cooldown period before retrying to avoid further bans.

#### 6. **Custom Logging**

- Minimal logging in non-debug mode for cleaner output.
- Detailed logs in debug mode for troubleshooting.

#### 7. **Language Preference**

- Specify preferred languages for transcripts (e.g., `en` for English, `es` for Spanish).
- Falls back to auto-generated transcripts if preferred language is unavailable.

### Debugging

Enable debug mode by setting the `debugMode` parameter to `true` in the input JSON. This will:

- Show detailed logs, including errors and stack traces.
- Log sensitive information like proxy details (use with caution).

***

### Error Handling

#### Common Errors and Solutions

1. **YouTube Blocking Requests**
   - Increase the `cooldownPeriod` to avoid triggering rate limits.

2. **No Transcript Found**
   - Ensure the video has a transcript available.
   - Check if the video is restricted or private.

***

# Actor input Schema

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

List of YouTube video URLs to extract transcripts from

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

Preferred language code for transcripts (e.g., 'en' for English, 'fr' for French)

## `includeAutoGenerated` (type: `boolean`):

Include auto-generated transcripts if manual ones aren't available

## `outputFormat` (type: `string`):

Format of transcript output

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

Maximum number of videos to process simultaneously

## `minDelayBetweenVideos` (type: `integer`):

Minimum delay in seconds between processing batches of videos

## `cooldownPeriod` (type: `integer`):

Period to wait in seconds when rate limits are detected

## `youtubeApiKey` (type: `string`):

Optional YouTube Data API key to retrieve additional video metadata

## `debugMode` (type: `boolean`):

Enable debug mode for verbose logging (disables emojis and hides sensitive information)

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "language": "en",
  "includeAutoGenerated": true,
  "outputFormat": "json",
  "maxConcurrency": 2,
  "minDelayBetweenVideos": 5,
  "cooldownPeriod": 60,
  "debugMode": false
}
```

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("naz_here/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"] }

# Run the Actor and wait for it to finish
run = client.actor("naz_here/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=dQw4w9WgXcQ"
  ]
}' |
apify call naz_here/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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