# YouTube Transcript & Video-Context Extractor (`argivaris/youtube-transcript-extractor`) Actor

LLM-ready YouTube transcripts, metadata and chapters for AI agents. Batch by video, playlist or channel. No login, no API key.

- **URL**: https://apify.com/argivaris/youtube-transcript-extractor.md
- **Developed by:** [Zeeshan Faizal](https://apify.com/argivaris) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 video transcribeds

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/actors/running/actors-in-store.md#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 & Video-Context Extractor — LLM-Ready Transcripts for AI Agents

**Extract clean, structured YouTube transcripts, video metadata, and chapters — batch by video, playlist, or channel. Built for AI agents, RAG pipelines, and LLM apps. No login, no YouTube API key, no cookies.**

Give it YouTube video URLs (or bare IDs), a playlist, or a channel, and get back **agent-ready transcripts** as structured JSON, Markdown, SRT subtitles, or plain text — with timestamps, auto-detected chapters, caption language handling, and full video metadata. Pay only for what you extract (pay-per-event), and default to Apify's automatic proxy so you never need to buy your own.

Keywords: youtube transcript, youtube transcript api, video transcript scraper, youtube captions, youtube subtitles, transcript extractor, LLM, RAG, AI agent, video to text, youtube summary input, timestamps, chapters, SRT, playlist transcript, channel transcript.

***

### Why this Actor

- **LLM-ready output.** Every record includes a joined `text` field and an agent-ready `markdown` document (H1 title, metadata block, chapters, timestamped or paragraph-segmented body) — drop it straight into a prompt or a vector store.
- **Batch anything.** One video, a list of videos, a whole playlist, or a channel's recent uploads — capped by `maxVideos` so you never over-scrape.
- **Language + translation aware.** Prefer a specific caption language, prefer human (manual) captions over auto-generated, and optionally translate via YouTube's own translation tracks.
- **Chapters + metadata.** Title, channel, duration, publish date, view count, description, thumbnails, available caption languages, and video chapters.
- **Robust by design.** Two extraction paths (watch-page parse + innertube), per-video error isolation, retries with backoff, and graceful handling of no-caption / private / removed / live videos — one bad video never aborts the run.
- **No paid proxy required.** Defaults to Apify's automatic datacenter proxy. Switch on residential only if you hit blocks at scale.

### Input

Provide **at least one** source. Everything is optional beyond that.

| Field | Type | Default | Description |
|---|---|---|---|
| `videoUrls` | string\[] | – | Video URLs (watch, `youtu.be`, shorts, embed) or bare 11-char IDs |
| `playlistUrl` | string | – | Playlist URL or ID → expanded to its videos |
| `channelUrl` | string | – | Channel URL (`/channel/UC…`, `/@handle`, `/c/`, `/user/`) or bare `@handle` → recent uploads |
| `startUrls` | request\[] | – | Advanced: list of `{ "url": … }`; video/playlist/channel auto-detected |
| `language` | string | auto | Preferred caption language code, e.g. `en`, `es`, `de` |
| `translateTo` | string | – | Translate captions into this language (best-effort, uses YouTube translation tracks) |
| `preferManualCaptions` | boolean | `true` | Prefer human captions over auto-generated |
| `includeTimestamps` | boolean | `true` | Keep per-segment timestamps (off = paragraph prose) |
| `includeChapters` | boolean | `true` | Extract chapters when present |
| `outputFormat` | enum | `json` | `json` · `markdown` · `srt` · `text` |
| `maxVideos` | integer | `50` | Cap after playlist/channel expansion |
| `maxConcurrency` | integer | `5` | Parallel videos (raise only with residential proxies) |
| `proxyConfiguration` | proxy | Apify auto | Defaults to Apify datacenter proxy; enable RESIDENTIAL if blocked |

#### Example input

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=arj7oStGLkU",
    "PHDbWvnkDL0"
  ],
  "playlistUrl": "https://www.youtube.com/playlist?list=PLUCPc-R61w-s",
  "language": "en",
  "preferManualCaptions": true,
  "includeTimestamps": true,
  "includeChapters": true,
  "outputFormat": "json",
  "maxVideos": 25
}
```

### Output

One dataset record per video. Metadata and flags are always present; the transcript representation follows `outputFormat`.

#### `json` (default) — abridged real record

```json
{
  "videoId": "arj7oStGLkU",
  "url": "https://www.youtube.com/watch?v=arj7oStGLkU",
  "title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED",
  "channel": "TED",
  "channelUrl": "https://www.youtube.com/channel/UCAuUUnT6oDeKwE6v1NGQxug",
  "durationSeconds": 844,
  "publishDate": "2016-04-06T09:59:35-07:00",
  "viewCount": 61765891,
  "availableCaptions": [
    { "language": "en", "kind": "manual", "name": "English" },
    { "language": "es", "kind": "manual", "name": "Spanish" }
  ],
  "chapters": [],
  "transcriptAvailable": true,
  "isAutoGenerated": false,
  "language": "en",
  "translatedTo": null,
  "transcript": [
    { "start": 12.645, "dur": 1.37, "text": "So in college," },
    { "start": 15.349, "dur": 1.564, "text": "I was a government major," }
  ],
  "text": "So in college, I was a government major, which means I had to write a lot of papers. ...",
  "markdown": "# Inside the Mind of a Master Procrastinator ..."
}
```

#### `markdown` — agent-ready document

```markdown
## Inside the Mind of a Master Procrastinator | Tim Urban | TED

- **Channel:** TED (https://www.youtube.com/channel/UCAuUUnT6oDeKwE6v1NGQxug)
- **URL:** https://www.youtube.com/watch?v=arj7oStGLkU
- **Duration:** 14:04
- **Published:** 2016-04-06
- **Views:** 61,765,891
- **Transcript:** manual captions (en)

### Transcript

**[00:12]** So in college,
**[00:15]** I was a government major,
...
```

`srt` returns a standard subtitle string; `text` returns the full joined transcript. Videos with **no captions** return a record with `transcriptAvailable: false` (still with metadata); private/removed/unavailable videos return a row with `error` and `errorMessage`.

### Pricing (pay-per-event)

You pay per unit of value delivered — nothing for videos that fail:

| Event | Price | When |
|---|---|---|
| Actor start | $0.00005 | Once per run (covers startup) |
| **Video transcribed** | **$0.005** | Per video with a delivered transcript |
| Video metadata (no captions) | $0.002 | Per valid video that has no captions |

Private, removed, age-restricted, or otherwise unavailable videos are **never charged**. A 1,000-video run of transcribable videos costs about **$5**. Set a **max charge per run** in the Console to cap spend — the Actor stops gracefully when it's reached.

### Languages, limits & behavior

- **Languages:** any language YouTube has captions for. `language` picks the track; `preferManualCaptions` prefers human captions; falls back to auto-generated. `translateTo` uses YouTube's translation tracks (best-effort — YouTube rate-limits translation, and the Actor returns the original captions if a translation is unavailable).
- **Playlists** expand up to ~100 videos per page (then capped by `maxVideos`). **Channels** expand to the most recent uploads. Use `maxVideos` to control cost.
- **No captions** is not an error — you get metadata and `transcriptAvailable: false`.
- **Live / private / age-restricted / removed** videos are handled gracefully as error rows; the run continues.
- **Blocks:** YouTube rate-limits aggressive extraction from shared IPs. The default Apify proxy works for typical volumes; for large runs or if you see empty transcripts, enable **RESIDENTIAL** proxy groups and/or lower `maxConcurrency`.

### Use with AI agents / MCP

This Actor is designed as a tool for LLM agents: point it at a video and feed the `markdown` or `text` straight into a prompt, or push `transcript` segments into a vector database for RAG. It runs headless (plain HTTP, no browser), so it's fast and cheap to call at scale.

### Legal & fair use

This Actor reads **publicly available** caption data and public video metadata for videos you supply. It does not log in, does not bypass access controls, does not download video/audio, and does not access members-only or private content. It respects rate limits with backoff. You are responsible for using extracted transcripts in accordance with YouTube's Terms of Service and applicable copyright law. See `LEGAL.md`.

# Actor input Schema

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

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

## `startUrls` (type: `array`):

Alternative to Video URLs — accepts a list of request objects ({ "url": ... }). Video, playlist, and channel URLs are auto-detected.

## `playlistUrl` (type: `string`):

A YouTube playlist URL or ID. Expanded to its videos (up to Max videos).

## `channelUrl` (type: `string`):

A YouTube channel URL (/channel/UC..., /@handle, /c/, /user/) or a bare @handle / UC id. Expands to the channel's most recent videos (up to Max videos).

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

ISO language code of the caption track to prefer, e.g. "en", "es", "de". Leave empty to auto-pick the video's default track.

## `translateTo` (type: `string`):

ISO code to translate the transcript into using YouTube's translation tracks, e.g. "en". Best-effort: translation is only available for some tracks and may be rate-limited.

## `preferManualCaptions` (type: `boolean`):

Prefer human-written captions over auto-generated ones when both exist. Falls back to auto-generated if no manual track is available.

## `includeTimestamps` (type: `boolean`):

Keep per-segment start times. When off, the transcript is paragraph-segmented prose (nicer for LLM context).

## `includeChapters` (type: `boolean`):

Extract video chapters (from YouTube's chapter markers or the description) when present.

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

Shape of each dataset record. json = structured (segments + text + markdown); markdown = agent-ready doc; srt = subtitles; text = plain transcript. Metadata is always included.

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

Cap on the number of videos processed after expanding playlists / channels. Protects you from accidentally scraping an entire channel.

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

How many videos to process in parallel. Higher is faster but more likely to hit YouTube rate limits; use residential proxies if you raise it.

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

Proxy for all requests. Defaults to Apify RESIDENTIAL — REQUIRED: YouTube blocks datacenter IPs and returns empty transcripts, so residential is the only reliable path on the platform (~0.9 MB/video). You can switch groups, but datacenter will yield mostly 'no transcript'.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=arj7oStGLkU"
  ],
  "preferManualCaptions": true,
  "includeTimestamps": true,
  "includeChapters": true,
  "outputFormat": "json",
  "maxVideos": 50,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

All transcribed videos from this run.

# 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=arj7oStGLkU"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("argivaris/youtube-transcript-extractor").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=arj7oStGLkU"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("argivaris/youtube-transcript-extractor").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=arj7oStGLkU"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call argivaris/youtube-transcript-extractor --silent --output-dataset

```

## MCP server setup

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

```

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/4eoTIcXRY7hdKk41a/builds/32gw6PySCrNXIgPr6/openapi.json
