# YouTube Transcript Scraper (Fast & Cheap) (`juliob.rangel/youtube-transcript-fast`) Actor

Get the transcript (captions/subtitles) of any YouTube video as clean text and timestamped segments, in any available language, plus title, channel, views and duration. Great for AI, RAG and content research.

- **URL**: https://apify.com/juliob.rangel/youtube-transcript-fast.md
- **Developed by:** [Julio Barcellos Rangel](https://apify.com/juliob.rangel) (community)
- **Categories:** Videos, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 transcript extracteds

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 Scraper (Fast & Cheap)

YouTube Transcript Scraper gets the transcript (captions or subtitles) of any YouTube video as clean text and as timestamped segments, in any language the video has, plus its title, channel, views and duration. It is made for AI and RAG pipelines, content research and repurposing: download YouTube subtitles in bulk and export them to JSON, CSV or Excel, with no YouTube API key and no login.

### What does YouTube Transcript Scraper do?

You give it a list of videos. For each video, the robot reads the list of caption tracks that YouTube offers, picks the best one for your preferred language, downloads it and returns:

- the full transcript as one plain text string,
- every caption line with its start time and duration (optional),
- which language was used, whether the captions are auto-generated, and which other languages exist,
- the video's title, channel, channel ID, view count and length.

It accepts:

- Watch URLs: `https://www.youtube.com/watch?v=dQw4w9WgXcQ`
- Short links: `https://youtu.be/dQw4w9WgXcQ`
- Shorts URLs: `https://www.youtube.com/shorts/<id>`
- Embed and live URLs: `/embed/<id>`, `/live/<id>`
- Plain 11-character video IDs: `dQw4w9WgXcQ`

Both captions uploaded by the creator and YouTube's automatic captions are supported. The same video listed twice is processed once.

### What data can you extract?

| Field | What it means | Example |
|---|---|---|
| `videoId` | 11-character video ID | `dQw4w9WgXcQ` |
| `url` | Link to the video | `https://www.youtube.com/watch?v=dQw4w9WgXcQ` |
| `title` | Video title | `Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)` |
| `channel` | Channel name | `Rick Astley` |
| `channelId` | Channel ID | `UCuAXFkgsw1L7xaCfnd5JJOw` |
| `views` | Exact view count | `1824221265` |
| `lengthSeconds` | Video length in seconds | `213` |
| `language` | Language code of the transcript that was returned | `en` |
| `autoGenerated` | `true` if these are YouTube's automatic captions | `false` |
| `availableLanguages` | Language codes of all caption tracks of the video | `["en", "en", "de-DE", "ja", "pt-BR", "es-419"]` |
| `text` | The whole transcript as one string, lines joined with spaces | `[♪♪♪] ♪ We're no strangers to love ♪…` |
| `segments` | List of caption lines, each with `start`, `duration` and `text` (only when `includeSegments` is on) | see below |
| `error` | Only on error items: why no transcript was returned | `No transcript available` |

Each item in `segments` has:

| Key | What it means | Example |
|---|---|---|
| `start` | When the line starts, in seconds from the beginning of the video | `18.64` |
| `duration` | How long the line is shown, in seconds | `3.24` |
| `text` | The caption line | `♪ We're no strangers to love ♪` |

The default table view shows `title`, `channel`, `language`, `autoGenerated`, `lengthSeconds`, `text` and `url`. The full JSON export also has `segments`.

### How to use YouTube Transcript Scraper

1. Open the robot in Apify Console and go to the **Input** tab.
2. In **Video URLs or IDs**, paste one video per line.
3. Set **Preferred language** to a code such as `en`, `pt` or `es` (default `en`).
4. Keep **Include timestamped segments** on if you need start times, or turn it off to get only the plain text.
5. Click **Start**. Transcripts appear in the **Output** tab as they are ready.
6. Click **Export** to download JSON, CSV, Excel, HTML or XML, or read the dataset through the API. JSON keeps the `segments` list in its natural form.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `videos` | array of strings | `["https://www.youtube.com/watch?v=dQw4w9WgXcQ"]` | Video URLs (watch, youtu.be, shorts, embed, live) or 11-character IDs. |
| `language` | string | `en` | Preferred caption language code. If the video doesn't have it, another track is used (see Tips). |
| `includeSegments` | boolean | `true` | Also return each caption line with start time and duration. |
| `proxy` | object | `{ "useApifyProxy": true }` | Apify Proxy settings. |

Example input:

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://youtu.be/aircAruvnKk"
  ],
  "language": "en",
  "includeSegments": true,
  "proxy": { "useApifyProxy": true }
}
```

### Output example

A real item from a recent run (the `text` is shortened and only the first 4 of 61 segments are shown):

```json
{
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "channel": "Rick Astley",
  "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "views": 1824221265,
  "lengthSeconds": 213,
  "language": "en",
  "autoGenerated": false,
  "availableLanguages": ["en", "en", "de-DE", "ja", "pt-BR", "es-419"],
  "text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ ♪ A full commitment's what I'm thinking of ♪ …",
  "segments": [
    { "start": 1.36, "duration": 1.68, "text": "[♪♪♪]" },
    { "start": 18.64, "duration": 3.24, "text": "♪ We're no strangers to love ♪" },
    { "start": 22.64, "duration": 4.32, "text": "♪ You know the rules and so do I ♪" },
    { "start": 27.04, "duration": 4, "text": "♪ A full commitment's what I'm thinking of ♪" }
  ]
}
```

When a video has no captions, you get an error item with the video details you can still use:

```json
{
  "videoId": "xxxxxxxxxxx",
  "url": "https://www.youtube.com/watch?v=xxxxxxxxxxx",
  "title": "Some video without captions",
  "channel": "Some channel",
  "channelId": "UCxxxxxxxxxxxxxxxxxxxxxx",
  "views": 1234,
  "lengthSeconds": 95,
  "error": "No transcript available"
}
```

### How much does it cost?

The robot uses pay per event pricing. You pay only for the transcripts you get, and Apify platform usage is already included in the price.

| Event | Price (Free plan) |
|---|---|
| Transcript extracted | $0.004 per video transcript, which is **$4.00 per 1,000 transcripts** |

The price is per video, whatever its length. Paid Apify plans get a discount:

| Plan | Price per 1,000 transcripts |
|---|---|
| Free | $4.00 |
| Bronze (-10%) | $3.60 |
| Silver (-20%) | $3.20 |
| Gold and higher (-30%) | $2.80 |

Worked examples on the Free plan:

- One video: **$0.004**.
- A course of 100 lectures: **$0.40**.
- 10,000 podcast episodes: **$40.00** ($36.00 on Bronze, $32.00 on Silver, $28.00 on Gold).

What is NOT charged:

- Videos without captions (`No transcript available`).
- Videos that can't be played (`Video not available: …`), could not be loaded, or whose transcript could not be downloaded.
- Lines in your input that are not a YouTube video URL or ID (they are skipped).

### Use cases

- **AI, RAG and chatbots**: load transcripts into a vector database or send them to an LLM so you can ask questions about a channel, a course or a podcast.
- **Summaries and notes**: turn lectures, interviews and meetings posted on YouTube into summaries, study notes or show notes.
- **Content repurposing**: rewrite videos as blog posts, newsletters, social threads or e-books.
- **Quotes with timestamps**: use `segments` to find exactly when something was said and link to that moment.
- **Subtitle files**: build SRT or VTT files from `start`, `duration` and `text`.
- **SEO and content research**: analyse what top videos in your niche actually talk about.
- **Brand and topic monitoring**: search transcripts for mentions of a product, a person or a keyword.
- **Language learning and accessibility**: get the text of a video in the languages it offers.

### Tips and limits

- **How the language is chosen.** The robot picks, in this order: a creator-made track in your exact `language`; an automatic track in that language; a track whose code starts with your code (`pt` also matches `pt-BR`); any creator-made track; the first track. It does **not** translate. Always check `language` and `autoGenerated` in the output.
- **`availableLanguages` can repeat a code**, for example `["en", "en", …]`, when a video has both creator-made and automatic captions in that language.
- **Only existing captions.** If a video has no captions at all (creator-made or automatic), you get an error item `No transcript available`. The robot does not do speech-to-text.
- **Unavailable videos** that YouTube won't play (for example private or removed videos) return an error item `Video not available: <reason from YouTube>`.
- **Text cleanup.** Line breaks inside a caption line are replaced by spaces and HTML entities are decoded. Sound tags such as `[♪♪♪]` or `[Music]` stay as YouTube wrote them.
- **Turn off `includeSegments`** if you only need the plain text. The dataset gets much smaller for long videos.
- **Bot checks.** YouTube sometimes asks datacenter IPs to sign in. The robot then retries on fresh Apify Proxy IPs and, when your account has access to it, on the Residential proxy group. If every try fails, you get an error item and nothing is charged.
- **Videos are processed one after another**, and each transcript is saved as soon as it is ready.
- **Metadata language.** Title and channel are returned as YouTube serves them, with English as the interface language.

### Use it from the API, Python or JavaScript

JavaScript (Node.js):

```javascript
const { ApifyClient } = require('apify-client');

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const input = {
  videos: ['https://www.youtube.com/watch?v=dQw4w9WgXcQ'],
  language: 'en',
  includeSegments: false,
};
const run = await client.actor('juliob.rangel/youtube-transcript-fast').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) console.log(item.title, item.error ?? item.text.slice(0, 200));
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')
run_input = {
    'videos': ['https://www.youtube.com/watch?v=dQw4w9WgXcQ'],
    'language': 'en',
    'includeSegments': False,
}
run = client.actor('juliob.rangel/youtube-transcript-fast').call(run_input=run_input)
items = client.dataset(run['defaultDatasetId']).list_items().items
for item in items:
    print(item.get('title'), item.get('error') or item['text'][:200])
```

You can also call it over plain HTTP with the Apify API (for example the `run-sync-get-dataset-items` endpoint of `juliob.rangel~youtube-transcript-fast`).

It works with Make, Zapier, n8n, Google Sheets export, webhooks and AI agents through the Apify MCP server, so an agent can fetch a transcript on demand.

### FAQ

**Do I need a login, cookies or a YouTube API key?**
No. The robot reads the public captions of a video. You only need an Apify account.

**Does it work with YouTube Shorts?**
Yes. Paste the `/shorts/` URL or the video ID. If a Short has no captions, you get a free error item.

**Does it translate transcripts?**
No. It returns one of the caption tracks the video already has. If your preferred language is not there, you get another available language, shown in `language`.

**Can I get auto-generated captions?**
Yes. When there is no creator-made track in your language, the automatic one is used, and `autoGenerated` is `true`.

**Can I export transcripts to Excel or CSV?**
Yes. Click **Export** in the Output tab. For CSV and Excel, turning off `includeSegments` gives a cleaner table with one row per video. JSON keeps the full segments list.

**Why did I get an error item?**
The video has no captions, is not available (for example private or removed), or YouTube kept blocking the request. Error items are not charged.

**Is scraping YouTube transcripts legal?**
The robot only collects publicly available data. You are responsible for complying with YouTube's terms, copyright and privacy laws such as GDPR and LGPD. If you store personal data, you need a legitimate reason.

### Related scrapers

- [YouTube Video Details Scraper (Views, Likes, Comments)](https://apify.com/juliob.rangel/youtube-video-details)
- [YouTube Comments Scraper (Fast & Cheap)](https://apify.com/juliob.rangel/youtube-comments-fast)
- [YouTube Search Scraper (Fast & Cheap)](https://apify.com/juliob.rangel/youtube-search-fast)
- [YouTube Playlist Scraper (All Videos, Views, Duration)](https://apify.com/juliob.rangel/youtube-playlist-scraper-fast)
- [YouTube Channel Videos Scraper (Fast & Cheap)](https://apify.com/juliob.rangel/youtube-channel-videos)
- [Website to Markdown Crawler](https://apify.com/juliob.rangel/website-to-markdown-crawler)

***

## Transcrição de Vídeos do YouTube

Pegue a transcrição (legenda) de qualquer vídeo do YouTube em texto limpo e com tempo de cada trecho, em qualquer idioma disponível. Ideal para IA, resumos e reaproveitar vídeos em texto. Você paga só por transcrição retornada; vídeos sem legenda não são cobrados.

# Actor input Schema

## `videos` (type: `array`):

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

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

Language code like 'en', 'pt', 'es'. Falls back to the video's default language.

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

Also return each caption line with start time and duration.

## `proxy` (type: `object`):

Apify Proxy settings.

## Actor input object example

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "language": "en",
  "includeSegments": true,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

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

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

```

## MCP server setup

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

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/JXHmx6nyRSW7Dbh3z/builds/lMJ6aIQLEinbf3FKb/openapi.json
