# YouTube Transcript API (`glassventures/youtube-transcript-api`) Actor

Extract transcripts, captions, and subtitles from YouTube videos. Supports 100+ languages, auto-generated captions, SRT/VTT export, playlists, and channels.

- **URL**: https://apify.com/glassventures/youtube-transcript-api.md
- **Developed by:** [Glass Ventures](https://apify.com/glassventures) (community)
- **Categories:** Videos, Agents, Automation
- **Features:** Limited permissions
- **Stats:** 26 total users, 5 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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 API

Extract transcripts, captions, and subtitles from any YouTube video. Supports 100+ languages, auto-generated captions, timestamps, SRT/VTT export, playlists, channels, and search queries.

### What does YouTube Transcript API do?

YouTube Transcript API extracts the full transcript (captions/subtitles) from YouTube videos and returns them as structured data with timestamps, video metadata, and multiple export formats.

Unlike other transcript tools, this actor doesn't require any API keys, browser extensions, or YouTube Data API quotas. It works directly with YouTube's public caption system, supporting both manually created and auto-generated (speech-to-text) captions.

You can input individual video URLs, video IDs, entire playlists, channel pages, or even search queries — the actor will discover all videos and extract their transcripts automatically.

### Use Cases

- **Content creators** — Repurpose video content into blog posts, social media, or newsletters
- **Researchers** — Analyze spoken content at scale for academic studies or market research
- **SEO professionals** — Extract video transcripts to create text-based content for search engines
- **AI/ML engineers** — Build training datasets from YouTube content for language models
- **Accessibility teams** — Generate text versions of video content for deaf/hard-of-hearing users
- **Journalists** — Quickly get searchable text from interviews and press conferences
- **Language learners** — Extract bilingual transcripts for study materials

### Features

- Extract transcripts from any YouTube video with captions
- Support for 100+ languages with automatic language detection
- Auto-generated (speech-to-text) and manual caption support
- Translate transcripts to any language using YouTube's built-in translation
- Multiple output formats: JSON with timestamps, plain text, SRT, VTT
- Batch processing: playlists, channels, and search results
- Full video metadata: title, channel, views, publish date, description, thumbnail
- Direct video ID input for maximum speed
- Shows all available caption languages per video
- Handles private/unavailable videos gracefully with clear error messages
- Proxy support for reliable scraping at scale

### How much will it cost?

YouTube Transcript API is extremely efficient — it uses only HTTP requests (no browser), making it very fast and cheap.

| Videos | Estimated Cost | Time |
|--------|---------------|------|
| 10     | < $0.01       | ~10 sec |
| 100    | ~$0.02        | ~1 min |
| 1,000  | ~$0.15        | ~5 min |
| 10,000 | ~$1.50        | ~45 min |

| Cost Component | Per 1,000 Videos |
|----------------|-----------------|
| Platform compute (256 MB) | ~$0.05 |
| Datacenter proxy | ~$0.10 |
| **Total** | **~$0.15** |

YouTube has generous rate limits, so datacenter proxies work well — no expensive residential proxies needed.

### How to use

1. Go to the YouTube Transcript API page on Apify Store
2. Click "Start" or "Try for free"
3. Enter YouTube URLs, video IDs, or search terms
4. Choose your preferred language and output format
5. Click "Start" and download the results

### Input parameters

| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| startUrls | array | YouTube video, playlist, or channel URLs | - |
| videoIds | array | Direct video IDs (11 characters) | - |
| searchTerms | array | Search YouTube and extract from results | - |
| language | string | Preferred transcript language (ISO code) | en |
| includeAutoGenerated | boolean | Use auto-generated captions when manual ones are unavailable | true |
| translationLanguage | string | Translate transcript to this language | - |
| outputFormat | string | json, plaintext, srt, or vtt | json |
| includeTimestamps | boolean | Include start/duration per segment | true |
| includeVideoMetadata | boolean | Include title, channel, views, etc. | true |
| maxItems | number | Maximum videos to process | 50 |
| proxyConfig | object | Proxy configuration | Apify Proxy |

### Output

The actor produces a dataset with the following fields:

```json
{
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "videoId": "dQw4w9WgXcQ",
    "title": "Rick Astley - Never Gonna Give You Up (Official Music Video)",
    "channelName": "Rick Astley",
    "channelUrl": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
    "description": "The official video for "Never Gonna Give You Up" by Rick Astley...",
    "viewCount": 1500000000,
    "publishDate": "2009-10-25",
    "duration": "3:33",
    "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
    "language": "en",
    "languageName": "English",
    "isAutoGenerated": true,
    "isTranslated": false,
    "availableLanguages": ["en (auto)"],
    "transcript": [
        { "text": "We're no strangers to love", "start": 18.0, "duration": 3.5 },
        { "text": "You know the rules and so do I", "start": 22.0, "duration": 3.2 }
    ],
    "fullText": "We're no strangers to love You know the rules and so do I...",
    "formattedTranscript": null,
    "segmentCount": 68,
    "totalDurationSecs": 213,
    "scrapedAt": "2024-01-15T10:30:00.000Z"
}
```

| Field | Type | Description |
|-------|------|-------------|
| url | string | YouTube video URL |
| videoId | string | 11-character video ID |
| title | string | Video title |
| channelName | string | Channel name |
| channelUrl | string | Channel URL |
| description | string | Video description |
| viewCount | number | Total view count |
| publishDate | string | Upload date (YYYY-MM-DD) |
| duration | string | Video duration (M:SS or H:MM:SS) |
| thumbnailUrl | string | Highest resolution thumbnail |
| language | string | Transcript language code |
| languageName | string | Language display name |
| isAutoGenerated | boolean | Whether captions are auto-generated |
| isTranslated | boolean | Whether the transcript was translated |
| availableLanguages | array | All available caption languages |
| transcript | array | Array of segments with text, start time, and duration |
| fullText | string | Complete transcript as a single string |
| formattedTranscript | string | SRT or VTT formatted transcript (when format is srt/vtt) |
| segmentCount | number | Number of transcript segments |
| totalDurationSecs | number | Total transcript duration in seconds |
| scrapedAt | string | ISO 8601 scrape timestamp |

### Output formats

#### JSON (default)

Returns structured data with timestamps per segment. Best for programmatic access and analysis.

#### Plain Text

The `fullText` field contains the entire transcript as a single string. Best for content repurposing and text analysis.

#### SRT

Industry-standard subtitle format. The `formattedTranscript` field contains:

```
1
00:00:18,000 --> 00:00:21,500
We're no strangers to love

2
00:00:22,000 --> 00:00:25,200
You know the rules and so do I
```

#### VTT

Web-native subtitle format. The `formattedTranscript` field contains:

```
WEBVTT

00:00:18.000 --> 00:00:21.500
We're no strangers to love

00:00:22.000 --> 00:00:25.200
You know the rules and so do I
```

### Integrations

Connect YouTube Transcript API with other tools:

- **Apify API** — REST API for programmatic access
- **Webhooks** — Get notified when extraction finishes
- **Zapier / Make** — Connect to 5,000+ apps
- **Google Sheets** — Export transcripts directly to spreadsheets

#### API Example (Node.js)

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('glassventures/youtube-transcript-api').call({
    videoIds: ['dQw4w9WgXcQ'],
    language: 'en',
    outputFormat: 'json',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].fullText);
```

#### API Example (Python)

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')

run = client.actor('glassventures/youtube-transcript-api').call(run_input={
    'videoIds': ['dQw4w9WgXcQ'],
    'language': 'en',
    'outputFormat': 'json',
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items[0]['fullText'])
```

#### API Example (cURL)

```bash
curl "https://api.apify.com/v2/acts/glassventures~youtube-transcript-api/runs" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"videoIds": ["dQw4w9WgXcQ"], "language": "en"}'
```

### Tips and tricks

- **Use video IDs** for fastest processing — skip URL parsing overhead
- **Batch by playlist** — paste a playlist URL to extract all video transcripts at once
- **Translation** — set `translationLanguage` to get transcripts in any language, even if the original isn't in that language
- **Cost optimization** — set `includeVideoMetadata: false` if you only need the transcript text
- **SRT/VTT export** — use these formats for direct import into video editors like Premiere Pro, Final Cut, or DaVinci Resolve

### FAQ

**Q: Does this actor require a YouTube API key?**
A: No. It works without any API keys or authentication. It uses YouTube's public caption system.

**Q: How fast is the extraction?**
A: Approximately 100-500 videos per minute depending on concurrency settings. Each video requires only 2 HTTP requests.

**Q: What if a video has no captions?**
A: The actor returns the video with `transcript: null` and `segmentCount: 0`. The `availableLanguages` field will be empty.

**Q: Can I get transcripts from private or age-restricted videos?**
A: No. Only publicly available videos with captions are supported. Private and age-restricted videos are reported with a clear error message.

**Q: Does this work with YouTube Shorts?**
A: Yes. YouTube Shorts URLs are automatically detected and processed.

**Q: Can I extract transcripts in multiple languages from the same video?**
A: Run the actor multiple times with different `language` settings, or use the `translationLanguage` field to translate from the base language.

**Q: What should I do if I get blocked?**
A: YouTube rarely blocks transcript extraction. If you experience issues, try using Apify Proxy with the default datacenter settings.

### Is it legal to scrape YouTube transcripts?

Extracting publicly available captions from YouTube is generally considered legal for personal use, research, and analysis purposes. This actor only accesses publicly available caption data that YouTube makes available to all viewers. Always review YouTube's Terms of Service for your specific use case. For more information, see [Apify's blog on web scraping legality](https://blog.apify.com/is-web-scraping-legal/).

### Limitations

- Only works with videos that have captions (manual or auto-generated)
- Private, age-restricted, and deleted videos are not accessible
- YouTube auto-generated captions may contain inaccuracies (speech-to-text errors)
- Translation quality depends on YouTube's auto-translation engine
- Channel and playlist extraction is limited to the initially loaded videos (~30-100)

### Changelog

- **v0.1** — Initial release with full transcript extraction, multi-language support, SRT/VTT export, playlist/channel/search support

# Actor input Schema

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

YouTube video, playlist, or channel URLs. The actor auto-detects the URL type and extracts transcripts from all discovered videos.

## `videoIds` (type: `array`):

Direct YouTube video IDs (11-character strings). Faster than full URLs.

## `searchTerms` (type: `array`):

Search YouTube for these terms and extract transcripts from the results.

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

ISO language code for the transcript. Falls back to any available language if not found.

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

If enabled, auto-generated (speech-to-text) captions are used when manual captions are not available.

## `translationLanguage` (type: `string`):

Translate the transcript to this language using YouTube's built-in translation. Leave empty to use original language.

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

Format for the transcript output. JSON includes timestamps, plaintext is just text.

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

Include start time and duration for each transcript segment (JSON format only).

## `includeVideoMetadata` (type: `boolean`):

Include video title, channel, views, publish date, description, and thumbnail URL.

## `maxItems` (type: `integer`):

Maximum number of video transcripts to extract. Use 0 for unlimited.

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

Maximum parallel requests. YouTube has generous rate limits, so 10-20 works well.

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

Enables verbose logging for troubleshooting.

## `proxyConfig` (type: `object`):

Proxy settings. Residential proxies are recommended for YouTube to avoid bot detection.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "videoIds": [
    "dQw4w9WgXcQ"
  ],
  "language": "en",
  "includeAutoGenerated": true,
  "outputFormat": "json",
  "includeTimestamps": true,
  "includeVideoMetadata": true,
  "maxItems": 50,
  "maxConcurrency": 10,
  "debugMode": false,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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": [
        {
            "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
        }
    ],
    "videoIds": [
        "dQw4w9WgXcQ"
    ],
    "proxyConfig": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("glassventures/youtube-transcript-api").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": [{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }],
    "videoIds": ["dQw4w9WgXcQ"],
    "proxyConfig": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("glassventures/youtube-transcript-api").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": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "videoIds": [
    "dQw4w9WgXcQ"
  ],
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call glassventures/youtube-transcript-api --silent --output-dataset

```

## MCP server setup

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

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/5PWyotRnsgK770m1w/builds/C8cj1y1KOAROSTHVD/openapi.json
