# YouTube Transcript Scraper — $0.002 per video (`devsef/youtube-transcript-scraper`) Actor

Extract YouTube video transcripts and subtitles as clean structured JSON with timestamps, language info and video title. Manual and auto-generated captions, any language. Only $0.002 per transcript — the cheapest on Apify; failed videos are never charged.

- **URL**: https://apify.com/devsef/youtube-transcript-scraper.md
- **Developed by:** [Steffano van Hoven](https://apify.com/devsef) (community)
- **Categories:** Videos, AI, Social media
- **Features:** Limited permissions
- **Stats:** 72 total users, 44 monthly users, 93.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 transcript  scrapeds

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

### What does YouTube Transcript Scraper do?

**YouTube Transcript Scraper extracts the full transcript (subtitles/captions) of any YouTube video as clean, structured JSON — for just $0.002 per transcript, the cheapest on Apify.** Paste video URLs or IDs, run the Actor, and get the complete spoken text with timestamps, language info, and video title. It supports both manual captions and auto-generated captions in any language YouTube offers.

Because it runs on the [Apify platform](https://apify.com), you get API access, scheduling, webhooks, integrations (Make, Zapier, n8n, LangChain, MCP), and monitoring out of the box.

### Why use YouTube Transcript Scraper?

- **Cheapest per-transcript price on Apify: $0.002.** Comparable actors charge $0.005-$0.01 per transcript — 2.5× to 5× more.
- **You only pay for delivered transcripts.** Videos without captions, unavailable videos, or blocked requests are never charged.
- **Built for AI workflows.** Feed transcripts into RAG pipelines, summarizers, content repurposing tools, or LLM agents. The plain-text field is ready for embedding; the segments array keeps timestamps for citation and clipping.
- **Any language.** Request your preferred language (e.g. `en`, `es`, `de`, `pt-BR`); the Actor falls back to the best available track and always tells you which language you got.
- **Honest output.** Every video gets a result row with an explicit `status` (`ok`, `no_transcript`, `unavailable`, `blocked`, `error`) so your automation can handle each case.

### How to use YouTube Transcript Scraper

1. Click **Try for free** — you'll need an Apify account (free plan works).
2. Paste one or more YouTube video URLs (or bare 11-character video IDs) into **YouTube videos**.
3. Optionally set your **Preferred language** (default: English) and toggle **Include timestamped segments**.
4. Click **Start**. Results appear in the **Output** tab within seconds per video.
5. Export the dataset as JSON, CSV, Excel, or HTML — or fetch it via the API.

### Input

| Field | Type | Description |
|---|---|---|
| `videoUrls` | array | YouTube video URLs or 11-character video IDs. Supports `watch?v=`, `youtu.be/`, `shorts/`, `embed/`, `live/`. Max 200 per run. |
| `language` | string | Preferred transcript language (ISO code, default `en`). Falls back to the best available track. |
| `includeSegments` | boolean | Include the timestamped `segments` array (default `true`). Disable for smaller, plain-text-only output. |
| `proxyConfiguration` | object | Proxy settings. **Keep the default (Apify residential proxy)** — YouTube blocks most datacenter IPs. |

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

### Output

Each video produces one dataset item. You can download the dataset in various formats such as JSON, CSV, Excel, or HTML.

```json
{
    "videoId": "dQw4w9WgXcQ",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
    "status": "ok",
    "language": "en",
    "isAutoGenerated": false,
    "segmentCount": 61,
    "charCount": 2089,
    "text": "We're no strangers to love You know the rules and so do I ...",
    "segments": [
        { "start": 18.64, "duration": 3.24, "text": "We're no strangers to love" }
    ],
    "error": null
}
```

| Field | Description |
|---|---|
| `videoId` / `url` / `title` | Video identification. |
| `status` | `ok`, `no_transcript`, `unavailable`, `blocked`, or `error`. Only `ok` is charged. |
| `language` | Language of the returned track (may differ from your preference if unavailable). |
| `isAutoGenerated` | `true` for YouTube auto-captions, `false` for manual subtitles. |
| `text` | The full transcript as plain text. |
| `segments` | Array of `{ start, duration, text }` in seconds (when enabled). |
| `charCount` / `segmentCount` | Size indicators for quick filtering. |

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

**$0.002 per successfully extracted transcript** — that's 500 transcripts per $1. You are never charged for videos without captions, unavailable/private videos, or blocked requests. Apify platform usage (compute, residential proxy traffic) is billed separately by Apify at standard platform rates; a typical transcript costs well under a cent in total.

### Tips

- **Keep the residential proxy enabled** (the default). YouTube aggressively blocks datacenter IPs with a "confirm you're not a bot" wall; residential proxies avoid this.
- Batch up to 200 videos per run — sequential processing with automatic retry on blocked videos.
- Set `includeSegments` to `false` if you only need plain text and want a smaller dataset.
- If a run reports many `blocked` results, re-run it — the Actor automatically rotates to fresh proxy sessions.

### FAQ and disclaimers

**Does this Actor download videos or audio?** No. It only retrieves the caption/subtitle text that YouTube already publishes for the video.

**Can it transcribe videos that have no captions at all?** No — it extracts existing captions (manual or auto-generated). Videos without any captions return `status: "no_transcript"` and are not charged.

**Is scraping YouTube transcripts legal?** This Actor only accesses publicly available caption data and does not collect personal data. You are responsible for how you use the extracted content — respect copyright and YouTube's Terms of Service for your use case.

Found a bug or missing feature? Open an issue in the **Issues** tab — issues are answered within a few days.

# Actor input Schema

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

YouTube video URLs or plain 11-character video IDs. Supported URL forms: watch?v=..., youtu.be/..., shorts/..., embed/..., live/... Maximum 200 videos per run.

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

Preferred transcript language as an ISO code (e.g. "en", "es", "de", "pt-BR"). If the video has no track in this language, the first available track is used instead — check the "language" field in the output.

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

When enabled, each result contains a "segments" array with start time, duration and text per caption line, next to the full plain-text transcript. Disable to keep the output small (plain text only).

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

Residential proxies are strongly recommended: YouTube blocks most datacenter IP addresses with a "confirm you're not a bot" wall. The default (Apify residential proxy) works out of the box.

## Actor input object example

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

# Actor output Schema

## `results` (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 = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("devsef/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 = { "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"] }

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

```

## MCP server setup

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