# YouTube Transcript Pro — Videos, Shorts, Playlists & Channels (`huzhihua/youtube-transcript-pro`) Actor

Extract YouTube transcripts from videos, Shorts, playlists, channels, and search. Get text, timestamped segments, SRT, VTT, RAG chunks, and metadata. Supports language selection, auto captions, translation, and reliable proxy fallback. Pay only for successful transcripts.

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

## Pricing

from $5.99 / 1,000 successful 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?

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 — Videos, Shorts, Playlists & Channels

Extract clean, structured YouTube transcripts from videos, Shorts, playlists, channels, and search results. Use the results for AI, RAG, automation, research, content analysis, and subtitle workflows.

**$5.99 per 1,000 successful transcripts.** Failed videos are not charged as successful transcripts. Platform usage is included.

### Why use this Actor

- Collect captions from videos, Shorts, playlists, channels, and search results, with batch processing and duplicate handling.
- Choose manual captions, auto-generated captions, language priority, and translation where YouTube supports it.
- Return plain text, timestamped segments, SRT, WebVTT, and RAG-ready chunks.
- Include video metadata when publicly available.
- Isolate failures so successful transcripts are preserved, and use configured proxy fallback and persistent transcript caching to reduce repeated network work.

### Use cases

- Ingest transcripts into a RAG pipeline or vector database.
- Build or curate LLM training and evaluation datasets.
- Research topics and references across YouTube videos.
- Monitor public channel uploads with scheduled runs.
- Analyze themes, terminology, or content across a video collection.
- Connect transcript results to n8n, Make, or Zapier workflows through Apify integrations or the API.
- Export subtitles for editing and localization workflows.
- Search and review interviews, talks, and podcast episodes.

### Supported inputs

Provide one source or mix multiple sources in a batch:

- Single video URL or 11-character video ID
- YouTube Shorts URL
- Playlist URL
- Channel URL or `@handle`
- Search query using `searchQueries` or a `search:` source
- Multiple mixed video, Shorts, playlist, channel, and search sources

Examples:

```text
https://www.youtube.com/watch?v=dQw4w9WgXcQ
https://www.youtube.com/@TEDEd
https://www.youtube.com/playlist?list=PLAYLIST_ID
search:quantum computing explained
```

### Output formats

Choose plain text, timestamped segments, SRT, WebVTT, or RAG chunks. Segment records include caption text and timing. RAG chunks include chunk text, start and end times, and a timestamp link to the corresponding point in the video.

### Metadata

Metadata is best effort and returned when publicly available. It can include title, channel name and URL, duration, thumbnail, upload date, views, likes, comments, playlist details, and Shorts classification. Individual fields may be `null` when YouTube does not provide them.

### Reliability

The Actor separates failures by video, so one unavailable video does not discard other successful results. It uses bounded retry and bot-check-aware behavior, with direct, datacenter, and optional residential proxy routing according to your settings. A persistent transcript cache can reduce repeated transcript network requests on later runs. YouTube availability and route responses can still vary.

### Pricing

- **$5.99 per 1,000 successful transcripts**
- Equivalent to **$0.00599 per successful transcript**
- Failed, no-caption, and private videos do not trigger the **Successful Transcript** event.
- **Actor Start:** $0.00005 per run
- **Platform usage:** Included

The Successful Transcript event is emitted for a successfully delivered transcript. Failed videos are not charged as successful transcripts.

### Input examples

#### Example 1: Single video

```json
{
  "sources": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "languages": ["en"],
  "outputFormats": ["text", "segments"]
}
```

#### Example 2: Channel Shorts

```json
{
  "sources": ["https://www.youtube.com/@TEDEd"],
  "includeVideos": false,
  "includeShorts": true,
  "includeLive": false,
  "outputFormats": ["text", "segments"]
}
```

#### Example 3: Playlist and search query

```json
{
  "sources": ["https://www.youtube.com/playlist?list=PLAYLIST_ID"],
  "searchQueries": ["quantum computing explained"],
  "maxVideosPerSource": 10,
  "maxVideosPerSearch": 5,
  "outputFormats": ["text", "segments", "srt", "vtt", "rag"]
}
```

### Output example

The following compact example shows the available fields when the matching formats are selected. Metadata fields may be `null` when unavailable.

```json
{
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Example video",
  "channelName": "Example channel",
  "transcriptLanguage": "English",
  "languageCode": "en",
  "isAutoGenerated": false,
  "isShort": false,
  "durationSeconds": 212,
  "fullText": "A short transcript excerpt…",
  "segments": [
    {"start": 0.0, "duration": 2.1, "end": 2.1, "text": "A short transcript excerpt."}
  ],
  "srt": "1\n00:00:00,000 --> 00:00:02,100\nA short transcript excerpt.",
  "vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:02.100\nA short transcript excerpt.",
  "ragChunks": [
    {
      "chunkIndex": 0,
      "text": "A short transcript excerpt.",
      "start": 0.0,
      "end": 2.1,
      "timestampUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=0s"
    }
  ],
  "success": true,
  "status": "OK"
}
```

### API and automation

Run the Actor from Apify Console, call it through the Apify API, or connect it through Apify integrations. It can be used in n8n, Make, and Zapier workflows, as well as MCP and AI workflows connected to Apify. No dedicated third-party n8n node is required to use the Apify API or integration options.

### Limitations

- A transcript is available only when YouTube provides caption or transcript data for the video.
- Some videos may be private, unavailable, age- or region-restricted, or blocked from access.
- YouTube may temporarily apply bot checks or rate limits.
- Rich metadata fields are not available for every video.
- Captions for live or recently uploaded videos may not be ready immediately.

### FAQ

#### Do I pay for failed videos?

Failed, no-caption, and private videos do not trigger the Successful Transcript event. A run can still have its Actor Start event; see the Pricing section for the current event rates.

#### Can it process Shorts?

Yes. Provide a Shorts URL directly or include Shorts when discovering a channel.

#### Can it process channels and playlists?

Yes. Provide a public channel URL or handle, or a playlist URL. Available videos are discovered and processed in a batch.

#### Does it support SRT and VTT?

Yes. Select `srt` and/or `vtt` in `outputFormats`.

#### Can I use the results for RAG?

Yes. Select `rag` in `outputFormats` or enable `ragChunks`. Chunks contain text, timing, and a timestamp link.

#### Does it use AI transcription?

No. This Actor retrieves available YouTube caption/transcript tracks. It does not currently perform Whisper or audio transcription.

#### What happens when YouTube blocks a request?

The Actor uses bounded retry and the proxy routes allowed by your settings. If a video remains unavailable, it is reported as failed while other successful transcripts are retained. Failed videos are not charged as successful transcripts.

# Changelog

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

# Actor input Schema

## `sources` (type: `array`):

Video URLs/IDs, playlist or channel URLs, @handles, or search:query entries. Defaults to a short public captioned video for a health check.

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

Optional additional list of video URLs or bare 11-character IDs.

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

Optional search terms that yt-dlp resolves into public video results.

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

Language priority list; exact match and locale-compatible variants are selected deterministically.

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

When enabled, use a manual track then an auto track only if none of the requested languages match.

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

Prefer human-created captions over auto-generated tracks when language priority allows.

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

If false, auto-generated tracks are not eligible for selection.

## `translateToLanguage` (type: `string`):

Optional target language code when the selected YouTube caption track supports translation.

## `outputFormats` (type: `array`):

Choose any of text, segments, SRT, VTT, or RAG chunks. All are outputs of one transcript event.

## `ragChunks` (type: `boolean`):

Also create timestamped RAG chunks, grouped near the selected chunk duration.

## `chunkSeconds` (type: `integer`):

Target duration for RAG chunks; actual boundaries follow caption segments.

## `startSec` (type: `integer`):

Optional lower bound for transcript segments; original timestamps are preserved.

## `endSec` (type: `integer`):

Optional end timestamp; use with startSec or durationSec.

## `durationSec` (type: `integer`):

Optional duration used with startSec when endSec is not supplied.

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

Limit playlist/channel discovery; 0 means all discovered items.

## `maxVideosPerSearch` (type: `integer`):

Maximum results to resolve for each search query.

## `includeVideos` (type: `boolean`):

Include the channel Videos tab during channel discovery.

## `includeShorts` (type: `boolean`):

Include the channel Shorts tab during channel discovery.

## `includeLive` (type: `boolean`):

Include the channel Streams tab during channel discovery.

## `timeoutSeconds` (type: `integer`):

Maximum wait per metadata or caption request.

## `retryCount` (type: `integer`):

Number of short retries for retryable per-video failures.

## `retryFreshCaptions` (type: `boolean`):

Retry NO_CAPTIONS only for videos published within 48 hours or recently-ended live replays with recent metadata.

## `freshCaptionRetryMaxMinutes` (type: `integer`):

Total upper bound for fresh-caption retries using finite 30/60/120-second backoff.

## `proxyMode` (type: `string`):

Direct uses no proxy; datacenter and residential use that group directly; auto tries direct, then datacenter, then optional residential.

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

Optional Apify Proxy settings for legitimate public-access reliability. Proxy mode controls the selected network group.

## `allowResidentialFallback` (type: `boolean`):

Allow residential proxy only after direct and datacenter network/bot failures in auto mode. Residential remains disabled by default.

## `maxSuccessfulTranscripts` (type: `integer`):

Optional local cap on the number of confirmed successful-transcript events; 0 uses the Apify run charge limit only.

## `incrementalMode` (type: `boolean`):

When prior state exists, skip items with a previously stored identical transcript hash.

## `stateKey` (type: `string`):

Optional key suffix used for persistent resume and incremental state.

## `resume` (type: `boolean`):

Skip previously confirmed successful transcripts under the selected state key.

## `metadata` (type: `boolean`):

Fetch public video metadata with yt-dlp. Metadata fields may be null when unavailable.

## Actor input object example

```json
{
  "sources": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "videoUrls": [],
  "searchQueries": [],
  "languages": [
    "en"
  ],
  "fallbackToAnyLanguage": false,
  "preferManualCaptions": true,
  "includeAutoGenerated": true,
  "outputFormats": [
    "text",
    "segments"
  ],
  "ragChunks": false,
  "chunkSeconds": 60,
  "maxVideosPerSource": 20,
  "maxVideosPerSearch": 10,
  "includeVideos": true,
  "includeShorts": true,
  "includeLive": true,
  "timeoutSeconds": 30,
  "retryCount": 1,
  "retryFreshCaptions": false,
  "freshCaptionRetryMaxMinutes": 3,
  "proxyMode": "auto",
  "allowResidentialFallback": false,
  "maxSuccessfulTranscripts": 0,
  "incrementalMode": false,
  "resume": false,
  "metadata": true
}
```

# Actor output Schema

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

Successful transcript rows in the default dataset.

## `runReport` (type: `string`):

Run counters and execution diagnostics.

## `unprocessed` (type: `string`):

Videos left pending for resume after charge limit or interrupted delivery.

## `errors` (type: `string`):

Failed source discovery and transcript outcomes.

# 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 = {
    "sources": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

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

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

```

## MCP server setup

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