# YouTube Transcript Scraper (`fullspeedtram/youtube-transcript-scraper`) Actor

Extract YouTube transcripts and subtitles from videos, playlists and whole channels. Pay only for transcripts you actually receive.

- **URL**: https://apify.com/fullspeedtram/youtube-transcript-scraper.md
- **Developed by:** [David Chicaiza](https://apify.com/fullspeedtram) (community)
- **Categories:** Videos, AI, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$50.00 / 1,000 transcript extracteds

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

A stable endpoint for YouTube captions. Built to sit inside a pipeline and keep working.

### The output contract

One dataset item per input video, always. Fields:

`videoId, url, title, channelName, channelId, durationSeconds, viewCount, availableLanguages, language, isAutoGenerated, isTranslated, transcript[], text`

`transcript` is an array of `{start, duration, text}`. `text` is the same content flattened. On success both are present.

**The schema is additive-only.** New fields may appear. Existing ones will not be renamed, retyped or removed.

### Failures are data, not exceptions

A video that cannot be read never aborts the run. You get a record for it carrying an `error` string, so you can reconcile every input by `videoId` instead of diffing counts.

**You are charged only for a transcript you actually receive.** Videos with no captions, or that are private, age-restricted or removed, cost nothing.

### Behaviour at volume

YouTube rate-limits by IP, which is what breaks naive transcript scrapers partway through a large job. Each lookup runs a three-client fallback chain (ANDROID, IOS, TVHTML5) over residential proxy, takes a **fresh exit IP on every retry**, and anything still failing goes through a slower recovery pass at reduced concurrency before it is written off.

Measured on-platform: 40/40 and 20/20 where a single-client fetch returns nothing. Datacenter proxy tested at 0/20, which is why residential is the default.

### Input

Video URLs, playlist URLs, or channel URLs and `@handles`. A channel expands to its uploads. `maxVideos` caps the job, `concurrency` (1-25) tunes throughput.

### Languages

`languages: ["en","es"]` selects a preferred track and prefers human-written captions over auto-generated ones. `translateTo` requests a translated track instead.

### Notes

Captions only: this reads YouTube's caption tracks and does not run speech-to-text, so videos with no captions cannot be transcribed.

# Actor input Schema

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

Paste any mix of video links, playlist links, channel links or @handles. Bare video IDs work too. Playlists and channels are expanded automatically.

## `languages` (type: `array`):

Language codes in order of preference, for example en, es, de. The first one with captions wins, and human-written captions are preferred over auto-generated ones.

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

Optional. Translate the captions into this language code using YouTube's own translation. Leave empty to keep the original.

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

How the transcript is returned. Segments give you timestamped chunks, which is what most AI and search pipelines want.

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

Only applies to the segments format. Turn off to strip timing information.

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

Caps how many videos are scraped in total when you pass playlists or channels.

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

How many videos to fetch in parallel. Lower this if you see rate limiting.

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

Residential proxy is on by default because YouTube blocks datacenter addresses on the endpoint this Actor needs. Measured on the same 20 videos: 20/20 on residential, 0/20 on datacenter. Turn it off only if you are supplying your own working proxy.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "https://www.youtube.com/@veritasium"
  ],
  "languages": [
    "en"
  ],
  "translateTo": "es",
  "outputFormat": "segments",
  "includeTimestamps": true,
  "maxVideos": 1000,
  "concurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Every scraped video with its transcript and metadata.

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

The same results as a spreadsheet-friendly CSV.

## `runDetails` (type: `string`):

Logs and run statistics for 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=dQw4w9WgXcQ"
    ],
    "languages": [
        "en"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fullspeedtram/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"],
    "languages": ["en"],
}

# Run the Actor and wait for it to finish
run = client.actor("fullspeedtram/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"
  ],
  "languages": [
    "en"
  ]
}' |
apify call fullspeedtram/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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