# YouTube Transcript Scraper (`socialdataapi/youtube-transcript-scraper`) Actor

YouTube Transcript Scraper — Extract YouTube video transcripts and subtitles, including spoken text, timestamps, language details, and video metadata. Useful for content repurposing, SEO research, video summarization, keyword analysis, and AI training workflows.

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

## Pricing

from $3.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 — Captions, Metadata and Analytics

YouTube Transcript Scraper pulls the transcript of any public YouTube video — the uploader's subtitles or YouTube's automatic captions, as plain text or timed lines — plus the title, length, channel name and view count. Every response is structured JSON, ready to pass directly to an LLM, index into a vector store, or feed a content-research pipeline. **No YouTube account, login or API key is needed.** Turn on video details, a channel's subscriber count and engagement analytics when you want them, then scale from one link to a full list.

***

### What data can I extract with YouTube Transcript Scraper?

Using this YouTube Transcript API, you will be able to extract the following YouTube video data:

| 📝 Transcript (text or timed lines) | 🎬 Video title | ⏱️ Video length | 📺 Channel name |
| --- | --- | --- | --- |
| 👁️ View count | 🌍 Caption language and whether it's auto-generated | 🆔 Video ID and URL | 💬 Reason when there's no transcript |
| 📅 Publish date | 🏷️ Category and tags | 👍 Like count | 🖼️ Thumbnail links |
| 📡 Live-stream status | 🔗 Channel ID, handle and link | ✅ Channel verified badge | 👥 Channel subscriber count (if shown) |
| 📈 Caption coverage of the video | 🗣️ Estimated speaking rate (words/min) | 💯 Engagement rate (likes ÷ views) | 🕒 When the row was scraped |

***

### How to use YouTube Transcript Scraper

YouTube Transcript Scraper is for anyone who needs what's said in a YouTube video as text — researchers, content teams, and AI builders — and one run gives you a clean row per video.

**Copy to your AI assistant:**

```text
YouTube Transcript Scraper is an Apify Actor that returns a YouTube video's transcript as structured JSON: language, whether it's auto-generated, the caption text or timed lines, plus the video title, length, channel name and view count. Use it whenever someone needs a video's spoken content without cookies, a login, or a browser - turning a talk or tutorial into an article, feeding a video's transcript into a RAG pipeline, or tracking a fixed list of videos over time. Inputs: urls (array, required, YouTube watch/youtu.be/shorts/embed/live links, one or more per entry, comma-separated entries allowed), includeEnglishAG (boolean, default true, adds English auto-generated captions), includeNonEnglish (boolean, default false, adds every other language offered), languageCode (string, default empty, get exactly one transcript in this language instead of the two switches above), outputFormat ("timestamp" | "text", default "text", controls each transcript's content shape), fetchVideoMetadata (boolean, default false, adds description/publish date/category/tags/thumbnails/duration/views/likes/live status/channel details), includeEngagementMetrics (boolean, default false, adds engagement rate, speaking rate and caption coverage), includeChannelInfo (boolean, default false, adds the channel's subscriber count), proxyConfiguration (object, optional). A video with no transcript, an unavailable video, or an entry that isn't a YouTube link returns one uncharged row with the reason in message instead of a normal row.
```

#### YouTube Transcript Scraper MCP Server: use these Actors from ChatGPT, Claude or Cursor

Point your AI assistant at Apify's MCP server and it can find and run this Actor on its own — no glue code, no scraping logic in your prompts.

```bash
claude mcp add --transport http apify "https://mcp.apify.com"
```

#### Step by step

1. [Create a free Apify account](https://console.apify.com/sign-up).
2. Open YouTube Transcript Scraper in the Apify Store.
3. Paste one or more YouTube video links into YouTube video URLs.
4. Click **Start** (or send your API request).
5. Download or stream your results in JSON, CSV or Excel.

#### How to scale YouTube Transcript Scraper to bulk

`urls` takes a list, and one entry may hold several links separated by commas or new lines, so a single run works as a bulk youtube transcript scraper across as many videos as you list — the same video listed twice is only scraped once. Videos run at the same time (up to 16 at once), and each row is saved to the dataset the moment that video is done, so a long list fills the output table while the run is still going instead of all at the end.

***

### ✨ Features

YouTube Transcript Scraper fetches clean, structured video transcripts from YouTube. It's ideal for turning talks and tutorials into text, feeding video content into an LLM or RAG pipeline, comparing what's said across many videos, and tracking a fixed list of videos over time. It extracts, per video:

- **Transcript** – the caption text, as one clean string or as timed lines with start and end times
- **Language and source** – which language, and whether it's the uploader's own subtitles, an automatic caption, or a machine translation
- **Title, length, channel name and views** – always included, even for a video with no transcript
- **Video details** – description, publish date, category, tags, thumbnails, duration, like count and live status, when switched on
- **Channel subscriber count** – read from the channel's own page, never a guessed number
- **Engagement analytics** – engagement rate, estimated speaking rate and caption coverage, computed from the video's own numbers

⚡ Each video is saved to the dataset as soon as it's done, and a video with no transcript still returns its basic facts in an uncharged row instead of nothing. It works equally well as a one-off youtube caption extractor for a single link or a youtube transcript downloader for a whole list.

***

### Use cases 💡

- **Content team** — turn a tutorial's transcript into a blog post or show notes in minutes.
- **AI builder** — extract youtube transcript text for each video and feed it into a RAG pipeline so an agent can answer questions about it.
- **Researcher** — download youtube subtitles across many videos, channels or languages to compare what's said on the same topic.
- **SEO analyst** — study the spoken keywords and tags of videos that already rank for your topics.
- **Growth team** — schedule runs over a fixed video list and track views, likes and engagement rate.

Building an AI agent? [Connect YouTube Transcript Scraper over MCP](#youtube-transcript-scraper-mcp-server-use-these-actors-from-chatgpt-claude-or-cursor) and let it call the actor on its own.

***

### Why choose this actor?

1. **A five-step language fallback, not a single guess.** When you ask for one language, the actor tries the uploader's own subtitles in that language, then the matching automatic caption, then YouTube's machine translation, before falling back to the original-language transcript — so a language request rarely comes back empty just because that exact track doesn't exist.
2. **The numbers behind each video, not just the transcript.** A recorded test row for one video came back with its subscriber count (6.66M), publish date, category, tags, duration and an engagement rate of 4.5%, computed from its real view and like counts.
3. **16 videos at once, one row each as soon as it's ready.** Up to 16 videos are processed in parallel, and every row — including the ones with no transcript — is saved to the dataset the moment that video finishes, not held back to the end of the run.

***

### ⬇️ Input

YouTube Transcript Scraper accepts one or more YouTube video links; `urls` is the only required field.

| Parameter | Required | Type | Description | Example |
| --- | --- | --- | --- | --- |
| `urls` | Yes | Array | YouTube watch, `youtu.be`, shorts, embed or live links; an entry may hold several links separated by commas | `["https://www.youtube.com/watch?v=jNQXAC9IVRw"]` |
| `includeEnglishAG` | No | Boolean | Add English auto-generated captions when the video has them (default `true`) | `true` |
| `includeNonEnglish` | No | Boolean | Add the transcripts in every other language the video offers (default `false`) | `false` |
| `languageCode` | No | String | Get exactly one transcript in this language instead of the two switches above (default empty) | `""` |
| `outputFormat` | No | String (`text` or `timestamp`) | How each transcript's content is written (default `text`) | `"text"` |
| `fetchVideoMetadata` | No | Boolean | Add description, publish date, category, tags, thumbnails, duration, views, likes, live status and channel details (default `false`) | `true` |
| `includeEngagementMetrics` | No | Boolean | Add engagement rate, speaking rate and caption coverage; switches on video details (default `false`) | `true` |
| `includeChannelInfo` | No | Boolean | Add the channel's subscriber count; switches on video details (default `false`) | `true` |
| `proxyConfiguration` | No | Object | Proxy settings; left off, the first try goes direct and retries use Apify's residential proxy | `{}` |

#### Example input

A real input from a test run of this build:

```json
{
  "urls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],
  "includeEnglishAG": true,
  "includeNonEnglish": false,
  "languageCode": "",
  "outputFormat": "text",
  "fetchVideoMetadata": true,
  "includeEngagementMetrics": true,
  "includeChannelInfo": true
}
```

***

### ⬆️ Output

One row per video, every row with the same fields. The plain-text output format gives a simple youtube transcript to text conversion in one string; timestamped cues give a list of lines with start and end times instead. When a video has no transcript, is unavailable, or the entry isn't a YouTube link, the row still comes back with whatever basic facts could be read and an uncharged row explaining why in `message`. Export as JSON, CSV or Excel for a quick youtube video transcript export straight from the run's dataset.

#### Example output

A real row from a test run of this build (`description` and `thumbnails` shortened here):

```json
{
  "id": "jNQXAC9IVRw",
  "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "input": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "transcripts": [],
  "title": "Me at the zoo",
  "length": "00:19",
  "channel_name": "jawed",
  "views": 441294098,
  "transcript": [],
  "message": "Failed to download transcript (rate limited)",
  "description": "Microplastics are accumulating in human brains at an alarming rate...",
  "publishDate": "2005-04-23T20:31:52-07:00",
  "publishDateSince": "21 years ago",
  "category": "Film & Animation",
  "tags": ["me at the zoo", "jawed karim", "first youtube video"],
  "durationSeconds": 19,
  "viewCount": 441294098,
  "likeCount": 20019136,
  "isLiveNow": false,
  "thumbnailUrl": "https://i.ytimg.com/vi/jNQXAC9IVRw/hqdefault.jpg",
  "thumbnails": ["https://i.ytimg.com/vi/jNQXAC9IVRw/hqdefault.jpg"],
  "channelId": "UC4QobU6STFB0P71PMvOGN5A",
  "channelUsername": "jawed",
  "channelDisplayName": "jawed",
  "channelUrl": "https://www.youtube.com/channel/UC4QobU6STFB0P71PMvOGN5A",
  "channelIsVerified": true,
  "metadataFetched": true,
  "channelSubscriberCountText": "6.66M",
  "channelSubscriberCount": 6660000,
  "channelExternalId": "UC4QobU6STFB0P71PMvOGN5A",
  "channelInfoCoverage": "ok",
  "transcriptCoveragePercent": null,
  "estimatedSpeakingRateWpm": null,
  "engagementRate": 0.045365,
  "scrapedAt": "2026-10-08T10:51:08Z"
}
```

This particular run couldn't reach this video's captions and the row was not charged, which is why `transcripts` and `transcript` are empty here — everything else (title, length, channel, view/like counts, video details, subscriber count and engagement rate) came back real and filled in. A video whose captions load successfully returns the same shape with `transcripts` and `transcript` filled in and the row charged.

***

### How does it work?

YouTube Transcript Scraper, a plain-HTTP youtube subtitles scraper, reads the same public video and caption data any visitor can see — no YouTube account, password or browser automation involved. Plain HTTP requests go out directly first; when YouTube refuses a request, the run automatically switches to Apify's residential proxy and retries with growing pauses before giving up on that video. Only publicly visible data is collected — nothing behind a login is accessed or guessed, and a channel's subscriber count is only ever read from text the channel itself shows, never estimated. The output fields stay the same shape on every run, so a change on YouTube's side does not change the JSON your code reads.

***

### How do you integrate YouTube Transcript Scraper into your stack?

It works with what you already use: a REST API for any language, MCP for AI agents, and no-code tools.

#### MCP integration for AI agents

Registering the actor over MCP lets Claude, Cursor, Windsurf or any other MCP-aware agent find and run it on its own, without you writing any scraping logic into the prompt. The same `claude mcp add` command works for any MCP client that supports Streamable HTTP. This registers YouTube Transcript Scraper as a tool your agent can call directly, passing a video link and reading the transcript back in the same run.

```bash
claude mcp add --transport http apify "https://mcp.apify.com"
```

#### No-code tools (n8n, Make, LangChain)

In n8n, use the Apify node's "Run an Actor" operation, or the HTTP Request node pointed at the Apify run-sync endpoint with your token. In Make, use the Apify app's "Run an Actor" module followed by "Get Dataset Items" to pull the transcripts into your scenario. In LangChain, the `langchain-apify` package wraps any Apify Actor, including this one, as a callable tool.

***

### Is it legal to scrape YouTube transcripts?

Collecting publicly available data is generally lawful. YouTube Transcript Scraper returns only transcripts and details from public videos that any visitor can watch, nothing behind a login. Transcripts can quote or name real people, so storing and reusing them must still comply with data-protection law such as GDPR where it applies. Consult legal counsel if your use case involves bulk storage of personal data.

***

### Frequently asked questions

#### What fields does YouTube Transcript Scraper return?

Every row includes the transcript, video title, length, channel name and view count. Switch on the optional extras for video details, channel subscriber count and engagement analytics. See [the data fields section](#what-data-can-i-extract-with-youtube-transcript-scraper).

#### Does YouTube Transcript Scraper require a YouTube account or login?

No. Only public video and caption data is extracted. No credentials are needed.

#### What happens if a video has no transcript or doesn't exist?

The row still comes back with whatever basic facts could be read (title, length, channel, views when available) plus a `message` explaining why — no transcript in the requested languages, the video is unavailable, or the entry isn't a YouTube link — and that row is not charged. The run carries on with the rest of the list.

#### Can I scrape multiple YouTube videos at once?

Yes. `urls` takes an array, and one entry may hold several links separated by commas or new lines; up to 16 videos are processed at the same time.

#### Does YouTube Transcript Scraper work with Claude, ChatGPT, and other AI agent tools?

Yes — it's available as an MCP tool. Use the command above to register it in Claude Code, Cursor or Windsurf. Any agent that can call an HTTP endpoint can use the REST API directly.

#### Does YouTube Transcript Scraper return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with consistent field names. Pass it straight to an LLM, index it into a vector store, or feed it to an agent tool — no transformation step.

#### What happens when YouTube changes its layout or anti-bot system?

The actor is maintained, and the output fields stay the same even when YouTube changes how its pages or captions work. No specific update turnaround is guaranteed.

#### Can I use YouTube Transcript Scraper without managing proxies or browser infrastructure?

Yes. Proxy switching happens automatically on the actor's side when a request is refused — you send one request and get structured JSON back, with no proxy accounts or browser setup to maintain.

#### Which YouTube transcript fields work best for AI training data and RAG indexing?

For RAG: the transcript content itself, plus the video title and description for context. For training data: the numeric and boolean fields — view count, like count, duration, engagement rate — are all typed primitives with no normalization needed.

***

### Your feedback

Found a bug or a video that didn't come out right? Let us know so the actor can be kept accurate as YouTube changes. Every report is read and fixes are shipped as they're found.

# Actor input Schema

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

One or more YouTube video links: watch, youtu.be, shorts, embed or live links. An entry may also hold several links separated by commas. Each video is added to the dataset as soon as it is done; the same video listed twice is scraped once. On the free plan a run scrapes up to 20 videos.

## `includeEnglishAG` (type: `boolean`):

Add YouTube's automatic English captions when the video has them.

## `includeNonEnglish` (type: `boolean`):

Add the transcripts in every other language the video offers.

## `languageCode` (type: `string`):

Leave empty to get the transcripts chosen by the two switches above. Enter a language code such as en, es, de or pt-BR to get exactly one transcript in that language instead: the video's own captions in that language, else the automatic ones, else YouTube's machine translation when available, else the original-language transcript (the row's message says which one you got).

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

How each transcript's content is written: Plain text gives one clean string; Timestamped cues gives a list of lines with start and end times. The transcript field always holds timed lines.

## `fetchVideoMetadata` (type: `boolean`):

Adds description, publish date, category, tags, thumbnails, duration, view and like counts, live status and channel name, ID, link and verified badge.

## `includeEngagementMetrics` (type: `boolean`):

Adds engagementRate (likes ÷ views), estimatedSpeakingRateWpm (words per minute of video) and transcriptCoveragePercent (how much of the video the captions cover), calculated from the video details and the first transcript. Switches on video details automatically.

## `includeChannelInfo` (type: `boolean`):

Adds the channel's subscriber count from its About page. Switches on video details automatically. Some channels don't show it; then the count stays empty and channelInfoCoverage says why - never a guessed number.

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

Leave it off for the usual run: the first try goes direct and retries go through Apify's residential proxy. A proxy you choose here is used for every request.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=4KbrxIpQgkM"
  ],
  "includeEnglishAG": true,
  "includeNonEnglish": false,
  "languageCode": "",
  "outputFormat": "text",
  "fetchVideoMetadata": false,
  "includeEngagementMetrics": false,
  "includeChannelInfo": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped videos in the Actor's default dataset. Videos without a transcript have an uncharged row whose message says why.

# 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=4KbrxIpQgkM"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("socialdataapi/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 = {
    "urls": ["https://www.youtube.com/watch?v=4KbrxIpQgkM"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("socialdataapi/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 '{
  "urls": [
    "https://www.youtube.com/watch?v=4KbrxIpQgkM"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call socialdataapi/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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