# YouTube Transcript Scraper — Videos, Channels & Playlists (`datafabrik/youtube-transcripts`) Actor

Get the transcript of any YouTube video, Short, playlist or whole channel: full text plus timed segments, language, auto-generated or not, with title, channel, duration, views and description. Pay per transcript; videos without captions are free. No browser, no YouTube API key.

- **URL**: https://apify.com/datafabrik/youtube-transcripts.md
- **Developed by:** [Data Fabrik](https://apify.com/datafabrik) (community)
- **Categories:** Videos, AI, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.20 / 1,000 transcripts

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

### What is YouTube Transcript Scraper?

Get the **transcript of any YouTube video** as clean JSON, CSV or Excel: the **full text** and the **timed segments**, the **language**, whether the captions are **auto-generated**, plus the video's **title, channel, duration, views, tags and description**. Paste video, Shorts, playlist or channel links: the Actor finds every video and transcribes each one once.

- 💲 **Pay per transcript**: from **$3.20 per 1,000 transcripts** ($4.90 on the Free plan), video details included, plus Apify's minimum start fee of $0.00005 per run. Videos without captions, private or removed videos and failures are **free**.
- 📺 **Videos, Shorts, playlists and whole channels** in one run: `@handle`, `/channel/UC…`, `/videos`, `/shorts` or `/streams` tab.
- 🌍 **Any caption language**: pick one (`en`, `fr`, `pt-br`…) or keep YouTube's default track.
- ⚡ **No browser, no YouTube API key, no login**: light HTTP requests, about 10 videos at a time.

### What data can you extract from YouTube?

| Data | Example |
|---|---|
| Full transcript | "We're no strangers to love…" |
| Timed segments (start, duration, text) | `22.64`, `4.32`, "You know the rules and so do I" |
| Language, auto-generated or not | `en`, `English`, `false` |
| Every caption language of the video | `en`, `de-DE`, `ja`, `pt-BR`… |
| Title, channel, channel link | "Never Gonna Give You Up", "Rick Astley" |
| Duration, views, live or not | `213` s, `1827177355`, `false` |
| Tags, description, thumbnail | a list, the text, a link |

### What can you do with YouTube transcripts?

- 🤖 **AI and LLM apps**: feed videos to ChatGPT, Claude or your RAG pipeline, summarize, answer questions about a channel.
- ✍️ **Content creation**: turn videos into articles, newsletters, quotes and social posts; study what top creators say.
- 🔎 **SEO and marketing**: find the words and topics competitors use, track brand mentions in videos.
- 📊 **Research**: analyse speeches, lectures, interviews or news channels at scale.
- ♿ **Accessibility and translation**: get the text to subtitle, translate or index videos.

### Why run it on Apify?

- **API**: every run is an API call, with ready clients for Python and JavaScript (see below).
- **Scheduling**: transcribe the new videos of a channel every day without a server.
- **Integrations**: Google Sheets, Slack, Zapier, Make, n8n, webhooks and your own database.
- **AI agents**: available through Apify's MCP server, so Claude, ChatGPT or Cursor can call it.
- **Proxies included**: YouTube refuses servers, so the Actor uses residential IPs, included in the price.

### How does it work?

1. Each link in `urls` is recognised: a video (watch, youtu.be, Shorts, live, embed or a bare id), a playlist, or a channel (`@handle`, `/channel/`, `/c/`, `/user/`).
2. For a channel or a playlist, the Actor lists up to `maxVideosPerSource` videos (newest first for channels). Add `/videos`, `/shorts` or `/streams` to a channel link to keep one tab.
3. For each video, it reads the caption tracks YouTube offers, picks the one in `language` (or YouTube's default) and downloads it.
4. Each video becomes one item in the dataset with `status`. Only `ok` items are charged.

### How to get a YouTube transcript

1. Click **Try for free**.
2. Paste one or more YouTube links in **YouTube links**.
3. Optional: set **Language**, or **Max videos per channel or playlist**.
4. Click **Start**. The transcripts appear in the **Transcripts** view, usually within seconds.
5. Download them as JSON, CSV or Excel, or connect an integration.

### Input

| Field | What it does | Default |
|---|---|---|
| `urls` | Videos, Shorts, playlists or channels, one per line. | — |
| `language` | Language code of the captions (`en`, `fr`, `pt-br`…). Empty = YouTube's default track. | empty |
| `maxVideosPerSource` | Videos taken from each channel or playlist (1 to 10,000). | `50` |
| `includeSegments` | Add the timed segments next to the full text. | `true` |
| `maxConcurrency` | Videos processed at the same time (1 to 20). | `10` |

Example:

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/@TED/videos",
    "https://www.youtube.com/playlist?list=PLAqhIrjkxbuWI23v9cThsA9GvCAUhRvKZ"
  ],
  "language": "en",
  "maxVideosPerSource": 20
}
```

### Output

One item per video (and one free item per link that gave no video):

```json
{
  "status": "ok",
  "note": null,
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "channelName": "Rick Astley",
  "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "channelUrl": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
  "durationSeconds": 213,
  "viewCount": 1827177355,
  "isLiveContent": false,
  "language": "en",
  "languageName": "English",
  "isAutoGenerated": false,
  "availableLanguages": [{ "languageCode": "en", "name": "English", "isAutoGenerated": false }, { "languageCode": "en", "name": "English (auto-generated)", "isAutoGenerated": true }],
  "text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ …",
  "segments": [{ "start": 22.64, "duration": 4.32, "text": "♪ You know the rules and so do I ♪" }],
  "keywords": ["rick astley", "never gonna give you up"],
  "description": "The official video for “Never Gonna Give You Up” by Rick Astley…",
  "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
  "source": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "scrapedAt": "2026-10-16T18:00:00.000Z"
}
```

| Field | Meaning |
|---|---|
| `status` | `ok` (charged), or a free status: `no-transcript`, `language-unavailable`, `unavailable`, `not-found`, `invalid-url`, `failed`, `skipped-cost-limit`. |
| `note` | Why there is no transcript, in plain words. |
| `videoId`, `url` | The video. |
| `title`, `channelName`, `channelId`, `channelUrl` | Video title and channel. |
| `durationSeconds`, `viewCount`, `isLiveContent` | Length, views, live stream or not. |
| `language`, `languageName`, `isAutoGenerated` | The caption track delivered. |
| `availableLanguages` | Every caption track of the video. |
| `text` | The full transcript. |
| `segments` | Timed pieces: `start`, `duration` (seconds), `text`. |
| `keywords`, `description`, `thumbnailUrl` | Tags, description, thumbnail. |
| `source` | The input link the video came from. |
| `scrapedAt` | When the item was produced (UTC). |

The run summary (counts per status) is saved as `OUTPUT` in the key-value store.

### How much does it cost to scrape YouTube transcripts?

You pay **per transcript delivered**, video details included:

| Apify plan | Price per transcript | Per 1,000 |
|---|---|---|
| Free | $0.0049 | $4.90 |
| Starter (Bronze) | $0.0039 | $3.90 |
| Scale (Silver) | $0.0035 | $3.50 |
| Business (Gold) and above | $0.0032 | $3.20 |

Plus Apify's start fee of $0.00005 per run. **Free**: videos without captions or without captions in your language, private, removed, age-restricted or region-blocked videos, links that are not YouTube, failures. The $5 monthly credit of Apify's Free plan covers about **1,000 transcripts** a month. Set **Maximum cost per run** in the run options to cap a run: the Actor stops before going over it.

### Is it free to try?

Yes. Apify's Free plan gives $5 of credit every month, with no card needed, which covers about 1,000 transcripts.

### Use it from code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("datafabrik/youtube-transcripts").call(run_input={
    "urls": ["https://www.youtube.com/@TED/videos"],
    "maxVideosPerSource": 10,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["status"] == "ok":
        print(item["title"], len(item["text"]))
```

JavaScript (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('datafabrik/youtube-transcripts').call({ urls: ['dQw4w9WgXcQ'], language: 'en' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].text);
```

### Limits

- Only videos **with captions** (human-made or auto-generated by YouTube) have a transcript. The Actor does not transcribe audio itself.
- Captions are delivered in the languages the video has; **machine translation is not offered** (YouTube refuses it to automated requests).
- Videos are read from the United States: a video blocked there comes back as `unavailable` (free).
- Publish date and like count are not included yet.

### FAQ

#### Is it legal to scrape YouTube transcripts?

The Actor reads public captions that YouTube shows to any visitor, without login. It does not collect personal data. You are responsible for how you use the content, in line with YouTube's terms and copyright law; check with a lawyer for commercial reuse.

#### Why did a video come back without a transcript?

Look at `status` and `note`: no captions at all, no captions in the language you asked (the note lists the available ones), or a private, removed, age-restricted or region-blocked video. None of these is charged.

#### Can I get the transcripts of a whole channel?

Yes: paste the channel link (`https://www.youtube.com/@handle`) and set `maxVideosPerSource` up to 10,000. Add `/videos` to skip Shorts and lives.

#### Can I get only the text, without timestamps?

Turn off `includeSegments`: `text` stays, `segments` is `null`.

#### Do I need a YouTube API key or an account?

No. The Actor uses the same public endpoints as YouTube's apps.

#### Can you add a feature or build a custom scraper?

Yes: open an issue on the **Issues** tab, we answer within a day.

# Actor input Schema

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

Videos, Shorts, playlists or channels, one per line: https://www.youtube.com/watch?v=…, https://youtu.be/…, /shorts/…, /playlist?list=…, https://www.youtube.com/@handle (add /videos, /shorts or /streams to keep one tab), /channel/UC…, or a bare video id. Each video is transcribed once, even if it appears in several links.

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

Language code of the captions to get (en, fr, es, de, pt-br…). A 2-letter code also matches its regional variants (pt → pt-BR). Human-made captions come before auto-generated ones. Leave empty to get the captions YouTube shows by default, usually the spoken language. A video without captions in this language is free and lists the languages it has.

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

How many videos to take from each channel or playlist, newest first for channels (1 to 10,000). Single video links are not limited.

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

Add the transcript split into timed segments (start and duration in seconds) next to the full text. Turn off if you only need the text.

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

How many videos are processed at the same time (1 to 20). The default suits most runs.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxVideosPerSource": 50,
  "includeSegments": true,
  "maxConcurrency": 10
}
```

# Actor output Schema

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

No description

## `summary` (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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datafabrik/youtube-transcripts").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"] }

# Run the Actor and wait for it to finish
run = client.actor("datafabrik/youtube-transcripts").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"
  ]
}' |
apify call datafabrik/youtube-transcripts --silent --output-dataset

```

## MCP server setup

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

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/FBuUUZvlX8Kp7e0rb/builds/F27nYy5dJtqPih2rt/openapi.json
