# YouTube Transcript Scraper - Subtitles, Captions & SRT (`nourishing_courier/youtube-transcript-scraper`) Actor

Extract YouTube transcripts in bulk from videos, Shorts, playlists and whole channels. Plain text, timestamped segments, clean paragraphs, SRT and VTT. 100+ languages, auto-generated captions included. No API key, no quota. You only pay for transcripts actually delivered.

- **URL**: https://apify.com/nourishing\_courier/youtube-transcript-scraper.md
- **Developed by:** [Ani Björkström](https://apify.com/nourishing_courier) (community)
- **Categories:** Videos, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.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/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 Scraper — Subtitles, Captions & SRT in Bulk

Get the **transcript of any YouTube video** — one video, a playlist, or an entire channel — as plain text, timestamped JSON, clean paragraphs, SRT or VTT.

No API key. No YouTube Data API quota. No browser. And **you are only charged for transcripts that are actually delivered** — videos without captions cost you nothing.

***

### What you get

| | |
|---|---|
| **Sources** | Video URLs, Shorts URLs, playlist URLs, channel URLs (`@handle`, `/channel/UC...`), or bare video IDs |
| **Formats** | Plain text · timestamped segments (JSON) · `[mm:ss]` readable text · clean paragraphs · SRT · VTT |
| **Languages** | 100+ — English, Spanish, German, French, Portuguese, Hindi, Arabic, Swedish, Japanese, Korean and more |
| **Captions** | Human-written subtitles preferred automatically, with auto-generated (ASR) fallback |
| **Metadata** | Title, channel, duration, view count, description, keywords, thumbnail |
| **Speed** | Direct API access, no headless browser — typically under a second per video |

***

### Why this scraper

Most YouTube transcript tools fail on a chunk of videos and still bill you for the attempt. This one is built around the two things people actually complain about:

**1. It finds transcripts other scrapers miss.** YouTube throttles caption access differently per client, so this actor tries the Android, Web and iOS endpoints in turn before giving up. A video that returns nothing on one client usually returns a full transcript on another.

**2. You only pay for results.** If a video genuinely has no captions, you get a clear reason in the `error` field and **no charge**. Compare that with per-run or per-attempt pricing elsewhere.

Plus the practical things: playlists and channels expand on their own, five output formats come free in the same run, and every failure explains itself in plain English instead of returning an empty row.

***

### How to use it

1. Click **Try for free**.
2. Paste one or more YouTube URLs into **YouTube URLs**. A playlist or channel URL works just as well as a single video.
3. Pick your **transcript language** (default `en`) and tick any extra output formats you want.
4. Click **Start**, then download results as JSON, CSV, Excel or XML — or pull them from the API.

#### Input example

```json
{
  "startUrls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
    { "url": "https://www.youtube.com/playlist?list=PLxxxxxxxxxxxxxxxx" },
    { "url": "https://www.youtube.com/@veritasium" }
  ],
  "language": "en",
  "maxVideos": 50,
  "includeSegments": true,
  "includeParagraphs": true,
  "includeSrt": true
}
```

#### Output example

```json
{
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Never Gonna Give You Up",
  "channelName": "Rick Astley",
  "durationSeconds": 213,
  "viewCount": 1543829104,
  "language": "en",
  "languageName": "English",
  "isAutoGenerated": false,
  "availableLanguages": ["en", "es", "de", "fr", "pt"],
  "transcript": "We're no strangers to love, you know the rules and so do I...",
  "wordCount": 412,
  "segments": [
    { "start": 18.64, "duration": 3.12, "end": 21.76, "text": "We're no strangers to love" }
  ],
  "transcriptFound": true,
  "error": null
}
```

***

### What people use it for

- **AI and RAG pipelines** — feed video knowledge into ChatGPT, Claude, LangChain, LlamaIndex or a vector database. The *clean paragraphs* output is built for chunking.
- **Summarising videos at scale** — turn a 2-hour podcast or conference talk into text an LLM can digest.
- **Repurposing content** — turn videos into blog posts, newsletters, LinkedIn posts and social clips.
- **SEO and keyword research** — mine what competitors actually say on camera, not just their titles and tags.
- **Subtitles and translation** — export SRT or VTT to edit, translate, or re-upload.
- **Research and analysis** — build a searchable corpus from a channel, course or lecture series.
- **Accessibility** — produce readable text versions of video content.

***

### Pricing

Pay per transcript delivered. Platform usage is included — there are no separate compute charges to work out, and no monthly rental.

A video with no captions available returns a clear error and **is not charged**.

***

### Integrations

Runs anywhere Apify runs: **API**, **JavaScript SDK**, **Python SDK**, **MCP server**, **n8n**, **Make**, **Zapier**, **LangChain**, or on a schedule. Every run's output is available as JSON, CSV, Excel, XML and RSS.

***

### FAQ

**Do I need a YouTube API key?**
No. This actor does not use the YouTube Data API, so there is no key to manage and no daily quota to run out of.

**Can it transcribe a whole channel or playlist?**
Yes. Paste the playlist or channel URL and it expands automatically, up to your **Maximum videos** limit.

**What if a video has no subtitles?**
You get a row with `transcriptFound: false` and a plain-English reason in `error` — and you are not charged for it. This actor reads existing captions; it does not run speech-to-text on audio that has none.

**Does it work with auto-generated captions?**
Yes. Human-written captions are preferred when both exist; auto-generated ones are used otherwise. Set **Prefer auto-generated captions** to flip that.

**Which languages are supported?**
Any language the video has captions in — over 100. Set the `language` code and the actor falls back to the closest available match.

**Can I get SRT files for a video editor?**
Yes. Tick **SRT subtitle file** (or **WebVTT**) and the subtitle content is included in each result, ready to save as `.srt` or `.vtt`.

**Does it work with YouTube Shorts?**
Yes — Shorts URLs are handled exactly like normal video URLs.

**Is scraping YouTube transcripts legal?**
This actor accesses publicly available caption data. You are responsible for how you use the output, including copyright and YouTube's Terms of Service. Use it for research, analysis and content you have the right to work with.

***

### Support

Found a video that should work but doesn't? Open an issue on the actor's **Issues** tab with the URL and it will be looked at. Feature requests are welcome — most of this actor's options started as user requests.

If this saved you time, a ⭐ review genuinely helps other people find it.

# Actor input Schema

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

Video, Shorts, playlist or channel URLs. Playlists and channels are expanded automatically up to the video limit below.

## `videoIds` (type: `array`):

Bare 11-character YouTube video IDs, if you already have them. Combined with the URLs above.

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

Safety cap on how many videos to process, mainly for playlists and channels.

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

Preferred language code, e.g. en, es, de, fr, sv, hi, pt. Falls back to the closest match, then to whatever the video has.

## `preferAutoGenerated` (type: `boolean`):

Off by default, so human-written captions win when a video has both. Turn on if you specifically want YouTube's ASR output.

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

Array of { start, duration, end, text } - use this to jump to a moment in the video.

## `includeTimestampedText` (type: `boolean`):

One line per cue, prefixed with its timestamp. The format people paste straight into ChatGPT or Claude.

## `includeParagraphs` (type: `boolean`):

Caption cues merged into readable paragraphs. Best format for summarising or RAG chunking.

## `includeSrt` (type: `boolean`):

Standard .srt content, ready for video editors and players.

## `includeVtt` (type: `boolean`):

Standard .vtt content for HTML5 video.

## `includeVideoDetails` (type: `boolean`):

Title, channel, duration, views, description, keywords and thumbnail alongside the transcript.

## `concurrency` (type: `integer`):

How many videos to fetch at once. Lower it if you hit rate limits on very large runs.

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

Keep this on. YouTube rate-limits datacenter IPs, so residential proxies give a much higher success rate on bigger runs. Blocked videos are retried automatically on a fresh IP.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "videoIds": [],
  "maxVideos": 100,
  "language": "en",
  "preferAutoGenerated": false,
  "includeSegments": true,
  "includeTimestampedText": false,
  "includeParagraphs": false,
  "includeSrt": false,
  "includeVtt": false,
  "includeVideoDetails": true,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Every scraped video with its transcript text, language, word count and metadata.

## `transcriptsCsv` (type: `string`):

The same records as a spreadsheet-ready CSV file.

## `consoleView` (type: `string`):

Open the run's dataset in Apify Console.

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

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

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

```

## MCP server setup

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