# 🌟Youtube Transcript Pro (`databuddy/youtube-transcript-pro`) Actor

One YouTube video transcript from captions, with SRT, chunks, translation and metadata. Failed, filtered and duplicate videos are free.

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

## Pricing

from $0.00005 / actor start

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 Pro: Subtitles, Captions, Translation & LLM Chunks

Get transcripts from YouTube **videos, Shorts, whole channels, playlists and search results** in one run. Every transcript comes back as clean text, **SRT**, **WebVTT**, timestamped lines, paragraphs, **chapters**, **keyword hits** and **LLM/RAG-ready chunks**, together with full video metadata. You can translate any transcript into 100+ languages. Videos with no captions at all can be transcribed by AI using your own Groq or OpenAI key.

**You only pay for transcripts you get.** Videos without captions, private or deleted videos, filtered videos and duplicates are free.

### What you can feed it

| Input | Example |
|---|---|
| Video / Shorts / live / embed | `https://www.youtube.com/watch?v=dQw4w9WgXcQ`, `youtu.be/…`, `/shorts/…`, `m.youtube.com`, `music.youtube.com` |
| Video ID | `dQw4w9WgXcQ` |
| Channel | `https://www.youtube.com/@3blue1brown`, `@3blue1brown`, `/channel/UC…`, `/c/…`, `/user/…` (videos, Shorts or live tab) |
| Playlist | `https://www.youtube.com/playlist?list=PL…` |
| Search | any search phrase, e.g. `claude ai tutorial` |

### What you get for each video

- **Transcript** as clean text, plus `word_count` and `line_count`.
- **Subtitles**: a ready `.srt` and `.vtt` file as text. Overlapping auto-caption cues are clipped, so the files play cleanly.
- **Segments**: `data` (text, start, duration for every line) and `lines`.
- **Timestamped text**: `[1:23] …` per line, easy to read and to cite (optional).
- **Paragraphs**: the transcript split on pauses into readable paragraphs (optional).
- **Chapters**: taken from the description (`0:00 Intro …`). Each chapter gets its own transcript text and a link to that moment.
- **LLM/RAG chunks**: about N words each, with optional overlap, start/end times and a deep link (`&t=123s`).
- **Keyword hits**: every moment a word or phrase is said, with the line, its context and a link to that second.
- **Translation**: `transcript_translated` in any language. YouTube's own caption translation is tried first; if YouTube refuses, Google Translate is used line by line and the timings are kept.
- **Metadata**: title, channel, channel ID and URL, duration, views, likes, category, exact publish date, thumbnail, description, tags, Short or not, available caption languages and tracks.
- **Evidence columns**: `language`, `is_auto_generated`, `matched_preferred_language`, `transcript_source` (captions or AI) and `translation_source`, so you always know where the text came from.

### How it is better than a basic transcript scraper

| | Basic transcript scrapers | YouTube Transcript Pro |
|---|---|---|
| Channels, playlists, search | Videos only | ✅ All, with per-source limits and channel tabs |
| Human vs auto captions | Takes whatever comes first | ✅ Prefers human-made captions; you choose |
| Chapters with their own text | ❌ | ✅ |
| LLM/RAG chunks with deep links | ❌ | ✅ |
| Keyword moments with links | ❌ | ✅ |
| Translation when YouTube throttles it | Fails | ✅ Falls back to Google Translate, timings kept |
| Likes, category, exact publish date | Partial | ✅ |
| Filters (date, length, Shorts) | ❌ | ✅ Filtered videos are free |
| Skip videos from previous runs | ❌ | ✅ Ideal for scheduled channel monitoring |
| Failed videos | Silent, or charged | ✅ Free row with the reason and how to fix it |
| Proxy blocked | Run fails | ✅ Switches automatically: residential → datacenter → server IP |

### Pricing (pay per event)

| Event | When it is charged | Price |
|---|---|---|
| `transcript` | One transcript saved from YouTube captions (one per language if you choose "every language") | $0.004 ($4 per 1,000) |
| `ai-transcript` | One transcript made by AI from the audio of a video with no captions | $0.008 ($8 per 1,000) |

The AI provider bills you directly for AI transcription, using your own key: Groq costs about $0.04 per audio hour, OpenAI about $0.36 per audio hour.

The run stops cleanly at your **Maximum cost per run**. Nothing is charged for failed, filtered, duplicate or previously seen videos.

### Example input

```json
{
  "urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ", "https://www.youtube.com/@3blue1brown"],
  "maxVideosPerSource": 20,
  "languages": ["en"],
  "translateTo": "es",
  "chunkWords": 300,
  "transcriptKeywords": ["neural network"],
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### Example output (shortened)

```json
{
  "status": "ok",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "video_id": "dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "channel": "Rick Astley",
  "duration_seconds": 213,
  "view_count": 1829606583,
  "like_count": 19492345,
  "publish_date": "2009-10-24T23:57:33-07:00",
  "category": "Music",
  "language": "en",
  "is_auto_generated": false,
  "transcript_source": "youtube_captions",
  "word_count": 487,
  "transcript": "[♪♪♪] ♪ We're no strangers to love ♪ …",
  "srt": "1\n00:00:01,360 --> 00:00:03,040\n[♪♪♪]\n…",
  "translated_to": "es",
  "transcript_translated": "[♪♪♪] ♪ No somos ajenos al amor ♪ …",
  "chunks": [{ "index": 0, "start": 1.36, "end": 102.04, "word_count": 207, "text": "…", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=1s" }],
  "keyword_matches": [{ "keyword": "never gonna", "time_hms": "0:43", "text": "♪ Never gonna give you up ♪", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=43s" }]
}
```

Videos without a transcript come back as free rows, for example `"status": "no_captions"` with `error` and `fix_hint`. Possible statuses: `no_captions`, `no_matching_language`, `unavailable`, `age_restricted`, `upcoming`, `blocked`, `not_found`, `no_results`, `invalid_input`. Turn off "Show videos without a transcript" to hide them.

### Run summary

Each run saves a `RUN_SUMMARY` record in the key-value store. It contains:

- videos found and saved, and the charged events;
- the reasons videos were skipped;
- the status of each input, and its counts per channel, playlist or search;
- caption languages, and how many captions were human-made vs auto-generated;
- how many transcripts were translated, and by which service;
- which network routes were used and how often YouTube blocked each one.

### Tips

- **Use residential proxy (the default).** YouTube bot-checks datacenter and cloud IPs. Residential costs about $0.0002 per video (≈25 KB per video). Keep "Automatic proxy fallback" on.
- **Monitor a channel cheaply:** schedule the actor with the channel URL, `publishedAfter: "7 days"` and "Skip videos saved in previous runs" turned on.
- **For RAG / AI apps:** set `chunkWords` to 300–500 and `chunkOverlapWords` to about 50. Each chunk links to its exact second in the video.
- **Age-restricted and members-only videos** need sign-in, which this actor does not do. They come back as free `age_restricted` rows.

### FAQ

**Which languages are supported?** Every caption language YouTube has (100+). Translation also covers 100+ target languages.

**What happens if a video has no captions?** You get a free `no_captions` row. To get a transcript anyway, turn on AI transcription and add your Groq or OpenAI key. Audio over 25 MB, or longer than your AI minutes limit, is skipped and not charged. YouTube sometimes refuses audio downloads; when it does, the video comes back as a free `no_captions` row that gives the reason.

**Is my API key safe?** The key field is a secret input. Apify stores it encrypted, and it is only sent to the provider you choose.

# Actor input Schema

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

Videos (watch, youtu.be, Shorts, embed, live, m./music.youtube.com), channels (@handle, /channel/UC…, /c/…, /user/…), playlists, or plain 11-character video IDs. Channels and playlists are expanded into their videos.

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

Find videos by YouTube search, e.g. "claude ai tutorial". Each query is treated like a channel: up to "Max videos per channel / playlist / search" videos.

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

How many videos to take from each channel, playlist or search query (newest first for channels).

## `channelTab` (type: `string`):

Which channel tab to read. A tab in the URL (e.g. /@name/shorts) overrides this.

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

Caption languages in order of preference, as codes: en, hi, es, fr, de, ja, pt-BR… "en" also matches en-US / en-GB.

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

If none of your languages exist, take the video's own caption track instead of skipping it.

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

Use creator-uploaded captions over YouTube's auto-generated ones when both exist in the chosen language.

## `allLanguages` (type: `boolean`):

One result per caption track (each language, manual and auto). Each is charged as a transcript.

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

Optional language code (e.g. hi, en, es). Adds transcript_translated using YouTube's own caption translation, or Google Translate line by line when YouTube refuses. Leave empty for no translation.

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

Add a ready-to-use .srt subtitle file as text.

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

Add a ready-to-use .vtt subtitle file as text.

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

Add "data" (text, start, dur for every line) and "lines".

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

Add transcript_timestamped: one line per caption with \[m:ss] in front — easy to read and to cite.

## `includeParagraphs` (type: `boolean`):

Add the transcript as readable paragraphs (split on pauses), each with its start time.

## `chunkWords` (type: `integer`):

Split the transcript into chunks of about this many words, each with start/end time and a link to that moment in the video. 0 = off. 200–500 suits most RAG setups.

## `chunkOverlapWords` (type: `integer`):

Words repeated between neighbouring chunks, for better retrieval. 0 = no overlap.

## `includeChapters` (type: `boolean`):

When the description lists chapters (0:00 Intro …), add each chapter with its own transcript text and link.

## `transcriptKeywords` (type: `array`):

Every moment these words or phrases are said, with the line, context and a link to that second of the video.

## `extraMetadata` (type: `boolean`):

One small extra request per video for category, exact publish date and like count.

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

A date (2025-01-31) or a period ("30 days", "6 months"). Uses the exact publish date.

## `minDurationSeconds` (type: `integer`):

Skip videos shorter than this. 0 = off.

## `maxDurationSeconds` (type: `integer`):

Skip videos longer than this. 0 = off.

## `skipShorts` (type: `boolean`):

Leave out YouTube Shorts.

## `aiProvider` (type: `string`):

When a video has no captions, download its audio and transcribe it with your own API key. You pay the AI provider directly (Groq ≈ $0.04 / audio hour, OpenAI ≈ $0.36 / audio hour).

## `aiApiKey` (type: `string`):

Your Groq or OpenAI API key. Stored encrypted by Apify and only sent to the provider you chose.

## `aiMaxMinutes` (type: `integer`):

Longer caption-less videos are skipped (and not charged). Audio files above 25 MB are skipped too.

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

Stop after this many saved (and charged) transcripts. 0 = no limit.

## `includeFailedVideos` (type: `boolean`):

Adds a free row (status = no_captions / unavailable / age_restricted / blocked / invalid_input …) with the reason and how to fix it.

## `skipPreviouslyScraped` (type: `boolean`):

Remembers saved video + language pairs in a named key-value store — ideal for scheduled channel monitoring.

## `dedupeStoreName` (type: `string`):

Key-value store used by "Skip videos saved in previous runs". Lowercase letters, numbers and hyphens.

## `proxyFallback` (type: `boolean`):

If YouTube keeps bot-checking the chosen proxy, switch automatically to Apify residential, then datacenter proxy, then the server IP.

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

YouTube bot-checks server IPs. Residential works best and costs about $0.0002 per video (≈25 KB per video).

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/@3blue1brown"
  ],
  "searchQueries": [],
  "maxVideosPerSource": 20,
  "channelTab": "videos",
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": true,
  "preferManualCaptions": true,
  "allLanguages": false,
  "translateTo": "",
  "includeSrt": true,
  "includeVtt": true,
  "includeSegments": true,
  "includeTimestampedText": false,
  "includeParagraphs": false,
  "chunkWords": 0,
  "chunkOverlapWords": 0,
  "includeChapters": true,
  "transcriptKeywords": [],
  "extraMetadata": true,
  "publishedAfter": "",
  "minDurationSeconds": 0,
  "maxDurationSeconds": 0,
  "skipShorts": false,
  "aiProvider": "none",
  "aiMaxMinutes": 60,
  "maxResults": 0,
  "includeFailedVideos": true,
  "skipPreviouslyScraped": false,
  "dedupeStoreName": "youtube-transcript-pro-seen",
  "proxyFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

## `failed` (type: `string`):

No description

## `runSummary` (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 = {
    "urls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://www.youtube.com/@3blue1brown"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("databuddy/youtube-transcript-pro").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=dQw4w9WgXcQ",
        "https://www.youtube.com/@3blue1brown",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("databuddy/youtube-transcript-pro").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=dQw4w9WgXcQ",
    "https://www.youtube.com/@3blue1brown"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call databuddy/youtube-transcript-pro --silent --output-dataset

```

## MCP server setup

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

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/49zavHSLHnNnsa3PX/builds/b8O8pKU1PJg4w03gW/openapi.json
