# YouTube Transcript Scraper: Subtitles & Captions for AI / RAG (`tomstudio/youtube-transcript-scraper`) Actor

YouTube transcript scraper: get transcripts, subtitles and captions for videos, channels and playlists. Manual, auto or translated fallback, timestamps, chapters, clean text and RAG chunks. No login, no API key, reliable retries.

- **URL**: https://apify.com/tomstudio/youtube-transcript-scraper.md
- **Developed by:** [Tom Studio](https://apify.com/tomstudio) (community)
- **Categories:** Videos, AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 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 Scraper - subtitles & captions for AI / RAG

**Extract YouTube transcripts, subtitles and captions in bulk** - from single videos, whole channels or playlists - as clean JSON ready for LLMs, RAG pipelines, search and analysis. No login, no API key, no cookies.

Built for **reliability**: automatic retries with backoff, per-video error isolation (one failing video never breaks the run), automatic datacenter-to-residential proxy fallback if YouTube blocks the IP, and a clear error code for every video that has no subtitles.

### What you get

For every video:

| Field | Description |
|---|---|
| `videoId`, `url` | Video identifiers |
| `title`, `channel`, `channelUrl`, `durationSeconds`, `publishedAt`, `viewCount` | Video metadata |
| `languageCode`, `language` | Language of the transcript returned |
| `type` | `manual` (uploaded subtitles), `auto` (YouTube speech recognition) or `translated` |
| `text` | Full transcript as one string |
| `segments` | Timestamped segments `{start, duration, text}` |
| `chapters` | Video chapters (with their transcript text in `clean`/`rag` mode) |
| `chunks` | In `rag` mode: ~1,500-character chunks with start times, ready for embeddings |
| `status`, `errorCode`, `error` | `ok`, `no_captions` or `error` with a readable reason |

### Features

- **Smart language fallback**: manual subtitles in your language → auto-generated in your language → YouTube machine translation → original language of the video.
- **Videos, channels, playlists**: paste URLs (watch, youtu.be, shorts, embed, live) or plain IDs; add a channel/@handle/playlist to get its latest N videos.
- **Three output formats**: `full` (text + segments), `clean` (readable text without `[Music]` / `>>` noise - ideal for LLM prompts), `rag` (clean text + timestamped chunks for vector databases).
- **Chapters** with per-chapter transcript text for structured summaries.
- **Reliable**: retries with exponential backoff, concurrency control, automatic Apify Proxy fallback on IP blocks.
- **Pay only for results** (pay-per-event pricing planned): videos without subtitles are free.

### Input example

```json
{
  "videoUrls": ["https://www.youtube.com/watch?v=8jPQjjsBbIc", "M7lc1UVf-VE"],
  "channelOrPlaylistUrls": ["https://www.youtube.com/@TED"],
  "maxVideosPerSource": 5,
  "languages": ["en", "it"],
  "outputFormat": "rag"
}
```

### Output example

```json
{
  "videoId": "8jPQjjsBbIc",
  "title": "How to stay calm when you know you'll be stressed | Daniel Levitin | TED",
  "channel": "TED",
  "durationSeconds": 740,
  "languageCode": "en",
  "type": "manual",
  "status": "ok",
  "text": "A few years ago, I broke into my own house. ...",
  "segments": [{"start": 13.24, "duration": 2.56, "text": "A few years ago,\nI broke into my own house."}],
  "chapters": [{"title": "Introduction", "start": 0, "end": 85}]
}
```

### Use cases

- Feed YouTube video content to **ChatGPT / Claude / LLM agents** and **RAG** knowledge bases
- Summarise lectures, podcasts, interviews and webinars at scale
- SEO and content research, topic and keyword analysis on competitor channels
- Dataset building for NLP and speech research, accessibility and archiving
- Repurpose videos into blog posts, newsletters and social posts

### Reliability and proxies

YouTube blocks most datacenter IPs, so the connection method decides how many videos succeed. How the Actor escalates, per video:

1. **Datacenter Apify Proxy (default).** Included in the free Apify plan. In our cloud tests about **75%** of videos that have subtitles succeeded (3 of 4, small sample); direct connections without a proxy failed every time (0 of 3).
2. **RESIDENTIAL proxy (automatic fallback, `useResidentialFallback`, on by default).** If the datacenter proxy keeps getting blocked for a video, the Actor retries that video through the Apify RESIDENTIAL group. Residential proxies are billed to **your** Apify account by traffic. A transcript is roughly 30-60 KB, so we estimate about **0.0005 USD per video** at ~8 USD/GB (estimate from typical transcript size and public proxy pricing, not a guarantee). Residential IPs are recommended if you need more than 95% success; we have not yet measured the exact rate on large batches.
3. **If RESIDENTIAL is not available** on your account, the run does not crash: the video is saved with `status: error` and `errorCode: BLOCKED`. To fix it, enable residential proxies in your Apify plan, or select the `RESIDENTIAL` group in the **Proxy configuration** input to use it from the start. You can also simply re-run the failed videos later.

Set `useResidentialFallback` to `false` to never use residential traffic. Videos without any subtitles are reported as `NO_CAPTIONS` and are not retried.

### Limitations (honest notes)

- Only videos that **have subtitles** (manual or auto-generated) can be transcribed. Videos with captions disabled return `status: no_captions` and cost nothing.
- Age-restricted, private and members-only videos need a login and are reported as errors - the Actor never logs in.
- Machine translation is rate-limited by YouTube and may fall back to the original language.
- YouTube may block datacenter IPs, so some videos can end as `BLOCKED` - see *Reliability and proxies* above.

### FAQ

**Do I need a YouTube API key?** No. **Does it work for auto-generated captions?** Yes (`type: auto`). **Can I get a transcript in another language?** Set `languages`; if the video has no such track the Actor tries YouTube's translation, then falls back to the original language. **Is it legal?** It reads publicly available captions; you are responsible for complying with YouTube's terms and applicable law for your use case.

Use via API, schedules, webhooks, or integrations (Make, n8n, Zapier, LangChain, LlamaIndex) like any Apify Actor.

### Who is this for?

AI developers building RAG or summarisation tools, researchers and students, content marketers repurposing videos, and SEO teams analysing competitor channels.

### More free tools by tomstudio

- [ATS Jobs Scraper (Workday, Greenhouse, Lever, Ashby...)](https://apify.com/tomstudio/ats-jobs-scraper)
- [TED Tenders Monitor (EU & Swiss public procurement)](https://apify.com/tomstudio/ted-tenders-monitor)
- [SEC EDGAR Filings Monitor](https://apify.com/tomstudio/sec-edgar-filings-monitor)
- [Domain Availability & RDAP Bulk Checker](https://apify.com/tomstudio/domain-rdap-bulk-checker)
- [App Store Reviews Scraper](https://apify.com/tomstudio/app-store-reviews-scraper)
- [Hacker News Search & Comments](https://apify.com/tomstudio/hacker-news-search)
- [Wayback Machine Snapshots](https://apify.com/tomstudio/wayback-machine-snapshots)
- [RSS & Atom Feed Reader](https://apify.com/tomstudio/rss-feed-reader)
- [YouTube Transcript Scraper](https://apify.com/tomstudio/youtube-transcript-scraper)

### Ready-to-use examples

Copy any of these inputs into the Input tab (the same examples are saved as public Tasks on this Actor's page).

#### YouTube transcript: Rick Astley - Never Gonna Give You Up

Get the full timestamped transcript of a famous YouTube video.

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "languages": [
    "en"
  ],
  "outputFormat": "full"
}
```

#### YouTube transcript: Steve Jobs Stanford speech (RAG chunks)

Transcript of the Steve Jobs 2005 Stanford commencement speech, chunked for AI/RAG.

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=UF8uR6Z6KLc"
  ],
  "languages": [
    "en"
  ],
  "outputFormat": "rag",
  "chunkSize": 1500
}
```

# Actor input Schema

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

YouTube video URLs (watch, youtu.be, shorts, embed, live) or plain 11-character video IDs.

## `channelOrPlaylistUrls` (type: `array`):

Optional. Channel URLs (https://www.youtube.com/@TED), @handles or playlist URLs. The latest videos of each are added to the run.

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

How many of the latest videos to take from each channel or playlist.

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

Language codes in priority order (e.g. en, it, es). Manual subtitles are tried first, then auto-generated.

## `translateIfMissing` (type: `boolean`):

If no track exists in your preferred language, use YouTube's machine translation of another track.

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

If nothing matches (and translation is impossible), return the video's original-language transcript instead of an error.

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

full = text + timestamped segments. clean = readable text only (sound tags and >> removed) for LLMs. rag = clean text + timestamped chunks ready for embeddings.

## `chunkSize` (type: `integer`):

Approximate chunk length when output format is 'rag'.

## `includeMetadata` (type: `boolean`):

Adds video metadata and chapters (one extra request per video). Turn off for maximum speed.

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

Safety cap for the whole run.

## `concurrency` (type: `integer`):

Videos processed at the same time. Lower it if YouTube rate-limits you.

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

Apify Proxy (datacenter) is on by default and is included in the free plan. If YouTube blocks it, the Actor can retry the video with RESIDENTIAL proxies (see the next option). You can also pick the RESIDENTIAL group here from the start, or use your own proxies.

## `useResidentialFallback` (type: `boolean`):

When YouTube blocks the datacenter proxy for a video, retry that video with Apify RESIDENTIAL proxies (billed to YOUR Apify account by traffic, roughly 0.0005 USD per video; requires residential proxy access on your plan). If the group is unavailable the video is reported with errorCode BLOCKED - the run never crashes.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=8jPQjjsBbIc"
  ],
  "channelOrPlaylistUrls": [],
  "maxVideosPerSource": 10,
  "languages": [
    "en"
  ],
  "translateIfMissing": true,
  "fallbackToAnyLanguage": true,
  "outputFormat": "full",
  "chunkSize": 1500,
  "includeMetadata": true,
  "maxVideos": 1000,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "useResidentialFallback": true
}
```

# Actor output Schema

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

All transcripts (overview table view).

# 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=8jPQjjsBbIc"
    ],
    "languages": [
        "en"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tomstudio/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=8jPQjjsBbIc"],
    "languages": ["en"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tomstudio/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=8jPQjjsBbIc"
  ],
  "languages": [
    "en"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tomstudio/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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