# YouTube Transcript Scraper (`electrabot.info/youtube-transcript-scraper`) Actor

Extract full transcripts from YouTube videos with timestamps: subtitles, auto-captions, any language. Batch multiple videos per run, language preference with smart fallback, plain-text output ready for AI and LLM pipelines. No browser. Pay per result - only successful transcripts are charged.

- **URL**: https://apify.com/electrabot.info/youtube-transcript-scraper.md
- **Developed by:** [electra bot](https://apify.com/electrabot.info) (community)
- **Categories:** Videos, AI, Automation
- **Stats:** 1 total users, 0 monthly users, 4.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Transcript Scraper

Extract the **full transcript** of any YouTube video — with timestamps, in your
preferred language, as clean plain text ready for AI pipelines — and download the
results as JSON, CSV, or Excel.

Paste one video or a whole list. No code required, no browser under the hood.

**Pay per result** — you're only charged for transcripts actually delivered,
never for failed videos or empty runs.

***

### What can I use it for?

- **AI & LLM pipelines** — the `transcript` field is one clean plain-text string, ready for RAG, summarization, embeddings, or fine-tuning datasets.
- **Content research** — analyze what competitors or creators say across many videos at once.
- **Subtitles & accessibility** — timed segments with second-precision start/duration.
- **SEO & content repurposing** — turn videos into articles, quotes, and show notes.
- **Media monitoring** — track mentions of brands or topics inside video content.

***

### Input

| Field | Required | Description |
|-------|----------|-------------|
| **Video URLs** | ✅ | One or more videos: watch URLs, `youtu.be` links, `/shorts/`, `/embed/`, `/live/`, or bare 11-character video IDs. Each video = one result. |
| **Preferred language** | – | Language code (`en`, `de`, `es`, `pt-BR`…). Falls back to English, then the first available track. Manually created subtitles are preferred over auto-generated ones. |
| **Proxy configuration** | – | **Automatic by default:** starts on a cheap datacenter proxy and escalates to RESIDENTIAL only if YouTube blocks it — you get reliability without paying residential rates for every request. Pin explicit groups to override. |

`videoUrl` / `videoCode` single-video fields are also supported (backward compatible).

### Output

One dataset record per video. Example (shortened):

```json
{
  "videoId": "jNQXAC9IVRw",
  "videoUrl": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
  "title": "Me at the zoo",
  "author": "jawed",
  "channelId": "UC4QobU6STFB0P71PMvOGN5A",
  "lengthSeconds": 19,
  "viewCount": 398776873,
  "language": "English",
  "languageCode": "en",
  "isAutoGenerated": false,
  "availableLanguages": ["de", "en"],
  "transcript": "All right, so here we are, in front of the elephants ...",
  "segmentCount": 6,
  "segments": [
    { "start": 1.2, "duration": 2.16, "text": "All right, so here we are, in front of the elephants" }
  ]
}
```

| Field | Description |
|-------|-------------|
| `transcript` | Full transcript as **one plain-text string** — feed it straight to an LLM |
| `segments` | Timed segments: `start` (s), `duration` (s), `text` |
| `language` / `languageCode` | The transcript's language |
| `isAutoGenerated` | `true` for auto-generated (ASR) captions, `false` for human-created subtitles |
| `availableLanguages` | Every caption language the video offers |
| `title` / `author` / `channelId` / `lengthSeconds` / `viewCount` | Video metadata |

***

### Why this scraper is reliable

- **No browser** — pure HTTP built on a battle-tested extraction engine that tracks YouTube's changes. Fast cold starts, low cost, fewer moving parts to break.
- **Smart language fallback** — your preferred language → English → first available; human subtitles beat auto-captions at every step.
- **Honest run statuses** — a run only says *Succeeded* when every requested video delivered. Partial results are labeled `PARTIAL:` with per-video reasons in the `SUMMARY`; a run with zero transcripts is marked **Failed**, never a silent empty dataset.
- **Batch-safe** — transcripts are saved incrementally and runs are checkpointed: an interruption never loses finished work or double-charges you.
- **Block-aware with automatic escalation** — if YouTube blocks the datacenter proxy, the scraper instantly retries through a residential proxy. If even that is blocked, the run stops, reports honestly, and a resurrected run resumes from the checkpoint without re-charging.

### Tips & limits

- Works with public videos that have captions (manual or auto-generated). Private, age-restricted, or caption-less videos are reported per video in the `SUMMARY` — they don't fail the whole batch and are never charged.
- Live streams get transcripts only after the stream ends and captions are processed.
- Keep the proxy on for reliable results — YouTube blocks direct cloud connections. The default auto-tiering handles it for you.

### Use it from code

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("electrabot.info/youtube-transcript-scraper").call(
    run_input={"videoUrls": ["dQw4w9WgXcQ", "jNQXAC9IVRw"], "language": "en"}
)
docs = [item["transcript"] for item in client.dataset(run["defaultDatasetId"]).iterate_items()]
```

**LangChain / LlamaIndex:** both ship Apify loaders — point them at this actor
and map `transcript` to your document text:

```python
from langchain_community.document_loaders import ApifyDatasetLoader
from langchain_core.documents import Document

loader = ApifyDatasetLoader(
    dataset_id=run["defaultDatasetId"],
    dataset_mapping_function=lambda item: Document(
        page_content=item["transcript"],
        metadata={"title": item["title"], "url": item["videoUrl"]},
    ),
)
```

**n8n / Make / Zapier:** call the actor via one HTTP node —
`POST https://api.apify.com/v2/acts/electrabot.info~youtube-transcript-scraper/run-sync-get-dataset-items?token=...`
returns the transcripts directly as the response body.

### FAQ

**Does it translate transcripts?**
No — it fetches the original caption tracks. Pick which one via the language preference.

**Can it scrape a whole channel or playlist?**
This actor takes video URLs/IDs. Feed it a list (from any channel-scraper's output) — each video is one result.

**Why did a video fail?**
Check the run's `SUMMARY` record — every failed video is listed with a reason (no captions, unavailable, age-restricted…). You are not charged for failed videos.

**Is scraping transcripts legal?**
This actor only accesses publicly available caption data. You are responsible for complying with applicable laws and YouTube's Terms of Service.

***

### Disclaimer

**This is an unofficial tool. It is not affiliated with, endorsed by, sponsored by,
or in any way officially connected to YouTube or Google LLC.** "YouTube" and all
related names, marks, and logos are trademarks of their respective owners and are
used here for descriptive purposes only.

This actor only accesses **publicly available** information. You are responsible
for ensuring your use complies with applicable laws, YouTube's Terms of Service,
and any applicable robots and rate-limiting rules. Use it ethically and at your
own risk.

# Actor input Schema

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

One or more YouTube videos. Accepts watch URLs, youtu.be short links, /shorts/, /embed/, /live/, or bare 11-character video IDs. Each video produces one transcript result.

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

Preferred transcript language code, e.g. 'en', 'de', 'es', 'pt-BR'. If that language is not available the scraper falls back to English, then to the first available track (manually created subtitles are always preferred over auto-generated ones). Leave empty for the default track.

## `videoUrl` (type: `string`):

Single video alternative to the list above. Kept for backward compatibility.

## `videoCode` (type: `string`):

11-character YouTube video ID, e.g. dQw4w9WgXcQ. Alternative to Video URL.

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

Default (recommended): automatic tiering — cheap datacenter proxy first, auto-escalating to RESIDENTIAL only if YouTube blocks it. Pick explicit proxy groups to pin a tier, or disable entirely at your own risk (YouTube blocks direct cloud connections).

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "jNQXAC9IVRw"
  ],
  "language": "en",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "videoCode": "dQw4w9WgXcQ",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One record per video: full plain-text transcript, timed segments, language info, and video metadata.

## `runSummary` (type: `string`):

Requested/scraped/failed counts and per-video failure reasons.

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("electrabot.info/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 = { "proxyConfiguration": { "useApifyProxy": True } }

# Run the Actor and wait for it to finish
run = client.actor("electrabot.info/youtube-transcript-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call electrabot.info/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=electrabot.info/youtube-transcript-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/2sQMwAdkgGZbD0rSG/builds/na1eCefqQojplnFWM/openapi.json
