# Youtube Transcript Scraper (`poidata/youtube-transcript-scraper`) Actor

🔥 $0.01/ 1K results 🔥 - Extract clean, timestamped YouTube transcripts in multiple languages along with video and channel metadata. Export results as JSON, CSV, or Excel, or automate extraction with the YouTube Transcript Scraper API.

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

## Pricing

from $0.01 / 1,000 results

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

Extract clean, timestamped transcripts from public YouTube videos — in the language the video already has, or translated into another language on the fly.

Paste one or more YouTube URLs or video IDs and receive structured caption data with timings, ready for research, content analysis, translation work, AI workflows, or automation. No YouTube account, YouTube API key, or coding required.

### What is YouTube Transcript Scraper?

YouTube Transcript Scraper extracts existing captions and subtitles from public YouTube videos.

For every successfully processed video, you receive:

- Full transcript text and timestamped snippets
- Ready-to-use **SRT**, **WebVTT**, and plain-text subtitles
- The video's available caption/translation languages
- Video and channel metadata
- The language choices that already exist for the video
- Structured output in JSON, CSV, or Excel

### Key features

- 🎯 Extract accurate, timestamped transcript segments
- 🌍 See the available caption and translation languages per video
- 🗣️ Pick an existing transcript in a specific language, or generate a brand-new translation
- ⚡ Process multiple YouTube videos in one run
- 📺 Include video and channel metadata
- 🔗 Accept YouTube URLs or video IDs
- 📤 Export results as JSON, CSV, or Excel
- 💻 Use through the Apify Console or API

### Two ways to get a non-default language

There are two distinct language options:

| Option | What it does | Speed |
| --- | --- | --- |
| **Transcript language** | Returns a transcript that **already exists** for the video — auto-generated captions or a human-added track. | Fast (no generation) |
| **Translate to language** | **Generates a new translation** into a language that isn't already available. | Slower (translated on the fly) |

Use **Transcript language** to grab a pre-existing transcript in the exact language a video publisher already provided. Use **Translate to language** to get a language that wasn't produced automatically.

### How does it work?

1. Add one or more YouTube video URLs or IDs.
2. Optionally pick a **Transcript language** (an existing track) or **Translate to language** (a new translation).
3. Run the Actor.
4. Download the results or access them through the Apify API.

Each successfully processed video is stored as **one record** (one row per video), containing the full transcript, timings, subtitles, and video/channel metadata.

### Input options

| Field      | Description                                                                 | Required |
| ---------- | --------------------------------------------------------------------------- | -------- |
| `videoIds` | One or more YouTube video IDs or URLs                                       | Yes      |
| `lang`     | Pick an already-existing transcript language (default/native, auto-generated, or a human-added track) | No |
| `tlang`    | Generate a new translation into this language on the fly                    | No       |

#### `videoIds`

Add a YouTube video ID:

```json
{
  "videoIds": ["dQw4w9WgXcQ"]
}
```

You can also use a complete YouTube URL:

```json
{
  "videoIds": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ]
}
```

#### `lang` — an already-existing transcript

Pick one of the transcripts that already exist for the video (auto-generated or human captions). The Actor returns that track — it is never generated on the fly, so it's fast.

```json
{
  "videoIds": ["dQw4w9WgXcQ"],
  "lang": "es"
}
```

Leave `lang` as **default** to return the video's native/default transcript.

#### `tlang` — a brand-new translation

Generate a translation into a language that isn't already available:

```json
{
  "videoIds": ["dQw4w9WgXcQ"],
  "tlang": "hi"
}
```

The Actor fetches the transcript, translates it, and returns the translated transcript with timings.

- Translation can take up to **60 seconds** per video.
- The result is clearly marked with the target and source language.
- Only ISO language codes are accepted; an unsupported code is reported and the run is aborted.
- `lang` and `tlang` are independent — you normally use one or the other.

Every result also includes the video/channel metadata and the list of available caption/translation languages (`available_translations`), so you can see what already exists for a video.

### Input examples

#### Extract the default transcript

```json
{
  "videoIds": ["dQw4w9WgXcQ"]
}
```

#### Pick an existing Spanish transcript

```json
{
  "videoIds": ["dQw4w9WgXcQ"],
  "lang": "es"
}
```

#### Generate a Hindi translation on the fly

```json
{
  "videoIds": ["dQw4w9WgXcQ"],
  "tlang": "hi"
}
```

#### Process several videos

```json
{
  "videoIds": [
    "dQw4w9WgXcQ",
    "https://www.youtube.com/watch?v=9bZkp7q19f0"
  ]
}
```

### How to find what languages a video already has

To know whether a language already exists as a track (before deciding whether to translate), run the Actor and read **`available_translations`** in each record — it lists the caption/translation languages the video already has. If the language you want is in that list, use **Transcript language**; otherwise use **Translate to language** so the Actor generates it.

### Output example

Each successfully processed video is stored as **one record** (one row per video). It contains the full transcript and video/channel details:

```json
{
  "video_id": "UMIMKzstuik",
  "url": "https://www.youtube.com/watch?v=UMIMKzstuik",
  "title": "Example YouTube Video",
  "description": "Example video description.",
  "thumbnail_url": "https://i.ytimg.com/vi/.../maxresdefault.jpg",
  "channel_id": "UCr6JcgG9eskEzL-k6TtL9EQ",
  "channel_name": "Example Channel",
  "channel_url": "https://www.youtube.com/channel/UCr6JcgG9eskEzL-k6TtL9EQ",
  "channel_handle": "@examplechannel",
  "channel_avatar_url": "https://yt3.ggpht.com/.../avatar.jpg",
  "channel_subscribers": "1.2M subscribers",
  "channel_videos": "345 videos",
  "channel_verified": true,
  "upload_date": "2026-08-30",
  "view_count": 49981,
  "duration_human": "9m 0s",
  "video_length_seconds": 547,
  "transcript_seconds": 540.68,
  "category": "Science & Technology",
  "visibility": "public",
  "is_live": false,
  "keywords": ["mac", "apple"],
  "language_name": "English",
  "language_code": "es",
  "requested_language": "es",
  "source_type": "Manual",
  "auto_generated": false,
  "translatable": true,
  "translated": false,
  "translated_to": "",
  "available_translations": ["de-DE", "ja", "pt-BR", "es-419"],
  "snippet_count": 239,
  "full_text": "Apple's most powerful chip, the M5 Ultra, is finally here...",
  "srt": "1\n00:00:00,320 --> 00:00:04,400\nWelcome to today's video.\n\n...",
  "webvtt": "WEBVTT\n\n00:00:00.320 --> 00:00:04.400\nWelcome to today's video.\n\n...",
  "segments": [
    { "segment_index": 0, "start": 0.32, "duration": 4.08, "end": 4.4, "text": "Apple's most powerful chip, the M5 Ultra" }
  ],
  "success": true,
  "fetched_at": "2026-08-31T20:18:02Z"
}
```

> `visibility`, `keywords` and `is_live` are derived from the data available. A few fields (e.g. `view_count`, `upload_date`) may be empty when the source doesn't provide them.

#### Subtitle formats included

Fields in each record can be used directly as subtitles:

- **`srt`** — the transcript formatted as **SRT** subtitles.
- **`webvtt`** — the transcript formatted as **WebVTT** subtitles.
- **`full_text`** — the transcript as **plain text**.

#### Output views

The Output tab shows views of the same data:

| View | Rows | Columns |
| --- | --- | --- |
| **Overview** | one per video | Thumbnail · Title · Channel · Views · Language · Source · Duration · Snippets · YouTube URL · OK · Available translations |
| **Video details** | one per video | Every video-level field, including the requested language, plain text, SRT/WebVTT and the full segments array |
| **Channel details** | one per video's channel | Video · Avatar · Channel · Handle · Subscribers · Videos · Verified · Channel URL · Channel ID |

Use the view selector at the top of the table to switch. Every view can be downloaded (Export) or fetched through the API with its `?view=` parameter.

> The full timestamped snippet list lives in each record's `segments` array (see the **Video details** view or the JSON export) — one element per transcript line.

### YouTube Transcript Scraper API

Use the **YouTube Transcript Scraper API** to automate transcript extraction from your applications, scripts, AI agents, or data pipelines.

Send the same JSON input through the Apify API and retrieve the resulting dataset programmatically. An Apify API token is required for API access, but a YouTube account or YouTube Data API key is not required.

The API is suitable for:

- AI and LLM data pipelines
- Video summarization workflows
- RAG knowledge bases
- Content and keyword research
- Academic or market research
- Subtitle analysis
- Workflow automation

### Common use cases

#### AI and LLM applications

Collect structured YouTube transcripts for summarization, topic extraction, question answering, and other language-processing workflows.

#### Content research

Study videos without manually copying captions from YouTube.

#### SEO research

Analyze topics, phrases, questions, and terminology used in video content.

#### Video monitoring

Process transcripts from selected videos and integrate the results into automated monitoring systems.

#### Translation research

Discover which manual, auto-generated, and translated caption tracks are already available.

### Frequently asked questions

#### Do I need a YouTube account?

No. You do not need to sign in to YouTube.

#### Do I need a YouTube API key?

No. The Actor does not require a YouTube Data API key.

#### Can I use it as a YouTube Transcript Scraper API?

Yes. You can run the Actor programmatically through the Apify API and retrieve the results from its dataset.

#### Can it extract auto-generated captions?

Yes. The Actor can return auto-generated captions when they are available for the video.

#### Can it extract transcripts in different languages?

Yes, two ways:

- **Transcript language** — return a transcript that already exists for the video (e.g. a human-added track or an auto-generated one). Fast, no generation.
- **Translate to language** — generate a new translation on the fly into a language that isn't already available. Slower.

Every result also lists the available caption/translation languages in `available_translations`, so you can see what exists before deciding whether to translate.

#### Does it translate transcripts automatically?

Not automatically. If you want a translation, pass a target language in **Translate to language** — the Actor translates it on the fly. If the language already exists as a track, use **Transcript language** instead for a faster result.

#### What happens if a video has no captions?

The video is skipped because no transcript can be extracted. It is not added to the dataset.

#### Can I process multiple videos in one run?

Yes. Add several URLs or video IDs to `videoIds`. The Actor stores one record per successful video (each record contains the full transcript, timings, and metadata).

#### What formats can I download?

Results can be exported as JSON, CSV, or Excel.

#### What happens when one video fails?

The failed video is skipped while the remaining videos continue processing.

### License

Free to use. See the Apify Store terms for monetized Actors.

# Actor input Schema

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

One or more YouTube video IDs (e.g. dQw4w9WgXcQ) or full video URLs. Each becomes one result in the dataset.

## `lang` (type: `string`):

Pick one of the transcripts that already exist for the video (auto-generated or human captions). Leave 'Default (native language)' to return the video's native/default transcript. This never generates a new translation — it only selects an already-available track.

## `tlang` (type: `string`):

Generate a brand-new translation of the transcript into this language on the fly — for languages that are NOT already auto-generated. Leave 'Default (no translation)' to use an existing/requested transcript instead. Translation can take up to 60 seconds per video and is charged once per video as a 'tlang-translated' event.

## Actor input object example

```json
{
  "videoIds": [
    "dQw4w9WgXcQ"
  ],
  "lang": "default",
  "tlang": "default"
}
```

# Actor output Schema

## `results` (type: `string`):

One row per video with the Overview / Video details / Channel details views.

# 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 = {
    "videoIds": [
        "dQw4w9WgXcQ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("poidata/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 = { "videoIds": ["dQw4w9WgXcQ"] }

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

```

## MCP server setup

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