# YouTube Transcript Scraper: Captions to Text & JSON (`benuelh/youtube-transcripts`) Actor

YouTube transcript scraper for researchers, creators and developers. Get captions as clean text or timestamped JSON from any video link, in your chosen language, with auto vs manual captions flagged. $0.0019 per transcript.

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

## Pricing

from $1.58 / 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

## 🎬 YouTube Transcript Scraper: captions to text & JSON

Turn any YouTube video into clean, timestamped text. Paste video links or IDs, get the full transcript plus every caption segment with start times, ready for AI, search, notes or content repurposing.

*✅ Last verified working: 2026-10-22 (automated daily test run)*

**You only pay for transcripts you receive: $0.0019 per transcript.** Videos without captions and bad links are free.

### ✨ What you get

- 📝 **Full transcript** as one clean block of text
- ⏱️ **Timestamped segments** (start and duration in seconds) for every caption line
- 🌍 **Language choice**: pick a language; available caption languages are listed for every video
- 🏷️ **Video details**: title, channel name, channel ID, duration
- 🤖 **Manual vs. auto-generated** captions clearly flagged
- 🔗 **Any link format**: `watch?v=`, `youtu.be/`, `/shorts/`, `/embed/`, or a plain 11-character ID
- 🛡️ **Built-in residential proxies**: nothing to configure
- ✅ **One row per video, always**: problems come back as a readable `error`, never a crashed run

### Use with AI agents (MCP)

This Actor works with the [Apify MCP server](https://mcp.apify.com), so Claude, ChatGPT, Cursor and other MCP clients can find it with the `search-actors` tool and run it with `call-actor`. To load it directly as a tool, connect to `https://mcp.apify.com?tools=benuelh/youtube-transcripts`.

Smallest working input:

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "language": "en",
  "includeTimestamps": true
}
```

Each result row has: `videoId`, `title`, `channelName`, `durationSeconds`, `language`, `isAutoGenerated`, `segmentCount`, `transcript` (plus `error`, set only when an item could not be processed).

Price: $0.0019 per transcript. One video transcript delivered. Videos without captions, unavailable videos and invalid links are free. Agents using Apify agentic payments can run it without an Apify account.

### 💡 Popular uses

- **AI & RAG pipelines**: feed transcripts into LLMs, embeddings and knowledge bases
- **Content repurposing**: turn videos into blog posts, newsletters, threads and show notes
- **Research & analysis**: search, quote and analyze what was said across many videos
- **Accessibility & SEO**: publish text versions of video content
- **AI agents**: strict input/output schema and limited permissions, so agents can find and run it directly

### ⚙️ Input

| Field | What it does | Default |
|---|---|---|
| `videos` | YouTube links or video IDs (required) | |
| `language` | Preferred caption language code, e.g. `en`, `es`, `de` | `en` |
| `includeTimestamps` | Include the timestamped `segments` array | `true` |
| `proxyGroups` | Proxy groups used for YouTube requests | `RESIDENTIAL` |

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

### 📦 Output

One item per video:

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

Download results as JSON, CSV, Excel or XML, or pull them through the Apify API.

### 💰 Pricing

**$0.0019 per transcript delivered.** 1,000 transcripts cost $4. You are never charged for videos without captions, private or unavailable videos, or invalid links.

### ❓ FAQ

**What if my language isn't available?**
You get the best available track (manual captions first), and `language` tells you which one was used. `availableLanguages` lists every option for that video.

**Does it work with auto-generated captions?**
Yes. `isAutoGenerated` tells you whether captions were uploaded by the creator or generated by YouTube.

**Why did a video return an error?**
The video has no captions, is private, age-restricted, removed, or the link is invalid. The `error` field says which.

**Do I need my own proxies or a YouTube account?**
No. Residential proxies are included and no login is used. Only publicly available captions are fetched.

**Is long-form content supported?**
Yes, from Shorts to multi-hour podcasts and lectures.

# Actor input Schema

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

YouTube video URLs (watch?v=, youtu.be/, /shorts/, /embed/) or 11-character video IDs.

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

Preferred caption language code, e.g. en, de, es.

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

If disabled, the segments array is returned empty and only the full transcript text is provided.

## `proxyGroups` (type: `array`):

Proxy groups used for YouTube requests. Defaults to RESIDENTIAL, which YouTube requires (it blocks datacenter IPs). Leave as is unless you know you need something else.

## Actor input object example

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "language": "en",
  "includeTimestamps": true,
  "proxyGroups": [
    "RESIDENTIAL"
  ]
}
```

# Actor output Schema

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

All transcripts from this run (one item per video) in the default dataset.

# 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=jNQXAC9IVRw"
    ],
    "language": "en",
    "includeTimestamps": true,
    "proxyGroups": [
        "RESIDENTIAL"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("benuelh/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 = {
    "videos": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],
    "language": "en",
    "includeTimestamps": True,
    "proxyGroups": ["RESIDENTIAL"],
}

# Run the Actor and wait for it to finish
run = client.actor("benuelh/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 '{
  "videos": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "language": "en",
  "includeTimestamps": true,
  "proxyGroups": [
    "RESIDENTIAL"
  ]
}' |
apify call benuelh/youtube-transcripts --silent --output-dataset

```

## MCP server setup

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