# YouTube Transcript Scraper - $0.001 per Video (`apidojo/youtube-transcript-scraper`) Actor

YouTube Transcript Scraper API, extract full transcripts, per-line timestamps, and all caption languages from any watch URL. $0.001 per transcript. No API key, login, or proxies. Bulk runs, language targeting, and custom output mapping for content repurposing, SEO, research, and AI pipelines.

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

## Pricing

$1.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

![](https://www.dropbox.com/scl/fi/1c7jyyodtmvgi6qdk9eej/youtube-transcript-scraper.png?rlkey=rrlsvwoaziao8kum97ibvhjbk\&dl=1)

## YouTube Transcript Scraper – Fast & Accurate Video Transcript Extraction

Extract YouTube video transcripts, subtitle timing data, and available caption languages in one structured JSON output. This **YouTube transcript scraper** pulls the full transcript straight from a video watch URL (no login, no complex setup) and works equally well as a single-video lookup or a bulk YouTube transcript downloader for large batches. Priced per successful transcript, so you only pay for the data you actually collect.

⚡ **Input:** YouTube watch URL (`youtube.com/watch?v=...` or `youtu.be/...`)
💰 **Price:** $0.001 per transcript, dataset storage included
📝 **Data Points:** Full transcript text, per-line start time and duration, selected caption language, and all available languages
🌍 **Language Control:** Optional `lang` parameter to request a specific caption language
🧩 **Custom Map Function:** Reshape or rename output fields on the fly

Looking for a reliable way to extract a YouTube transcript, download video subtitles in bulk, or convert a YouTube video to text for a content or AI pipeline? Need a lightweight YouTube Transcript API you can call from an automation without opening the "Show transcript" panel by hand? This Apify actor delivers clean, timestamped transcript data in one run, whether you're pulling a single video or batch-processing hundreds.

### 📚 Table of Contents

- [🧭 What does YouTube Transcript Scraper do?](#what-does-youtube-transcript-scraper-do)
- [🎯 Features and Functionality](#features-and-functionality)
- [🧭 Complete Your YouTube Data Stack](#complete-your-youtube-data-stack)
- [Important Note About Usage](#important-note-about-usage)
- [🆓 Demo Mode & Free Users](#-demo-mode--free-users)
- [⚡ Performance & Technical Details](#performance-and-technical-details)
- [💰 Pricing](#pricing)
- [📥 Input Parameters](#input-parameters)
- [📤 Output](#output)
- [🍳 Custom Map Function](#custom-map-function)
- [🔧 Troubleshooting & Common Issues](#troubleshooting-and-common-issues)
- [🎯 Who Needs This YouTube Transcript Scraper? (Use Cases & Industries)](#who-needs-this-youtube-transcript-scraper-use-cases-and-industries)
- [💡 How to Scrape YouTube Transcripts: Step-by-Step Guide](#how-to-scrape-youtube-transcripts-step-by-step-guide)
- [❓ Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
- [Contact](#contact)

### 🧭 What does YouTube Transcript Scraper do?

**YouTube Transcript Scraper** is a focused data extraction actor built to pull the transcript (subtitle) text of any public YouTube video, given its watch URL. Feed it one or more video links and it returns the full transcript, line by line, with precise start time and duration for each segment, along with the caption language that was selected and every other language available for that video.

There's no need to open the video, click through the "Show transcript" panel, or manually copy captions. Whether you're repurposing video content into blog posts, running it as a YouTube Transcript API inside your own app, or feeding transcripts into an AI pipeline, this scraper turns a YouTube URL into structured, timestamped text in seconds.

This actor is ideal for content repurposing, SEO content creation, video accessibility, research, and AI training data collection, helping content teams, researchers, and developers turn spoken video content into usable, structured text.

### 🎯 Features and Functionality

This actor gives you direct access to transcript data on YouTube, covering full transcript text, per-segment timing, and caption language options. It's built for anyone who needs spoken video content as clean, structured text.

#### ⚡ Extract transcript data from:

- ✅ **Any public YouTube video**: Provide a watch URL and receive the full available transcript.
- ✅ **Timed Transcript Segments**: Every line comes with `startTime` and `dur` (duration), so you can rebuild exact timing.
- ✅ **Selected Caption Language**: Know exactly which language and title (e.g. "English (auto-generated)") was returned.
- ✅ **Available Language List**: See every caption language YouTube offers for that video, even if you didn't request it.
- ✅ **Language Targeting**: Optionally pass a `lang` code (e.g. `en`, `tr`) to request a specific transcript language.

#### 🧠 Smart Functionalities

| **Capability**         | **What It Does**                                                                                            | **Why It Matters**                                                                          |
| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| Watch URL Input        | Accepts standard `youtube.com/watch?v=...` and shortened `youtu.be/...` links.                              | Works directly with links copied straight from YouTube or shared elsewhere.                 |
| Language Selection     | Optional `lang` parameter to request a specific caption language.                                           | Lets you standardize on one language across a batch, or fetch a video's native language.    |
| maxItems Control       | Cap the number of videos processed per run.                                                                 | Keeps runs predictable for both quick tests and large batches.                              |
| Custom Map Function    | Pass a JS function to reshape, rename, or filter fields in every output row.                                | Get exactly the schema your downstream tool or database expects, with zero post-processing. |
| Graceful Skipping      | Videos without a transcript, or that fail during extraction, are skipped rather than failing the whole run. | A handful of unavailable transcripts won't stop the rest of your batch from completing.     |
| Structured JSON Output | Transcript, timing, and language metadata returned per video in a consistent schema.                        | Instant integration with dashboards, databases, or NLP/AI pipelines.                        |

#### 🧭 Complete Your YouTube Data Stack

A transcript captures what's said in a video, but it's only one layer of the full picture. If you also need view counts, channel details, or the rest of a playlist's videos, pair this actor with other tools from the same developer to build a complete YouTube dataset without switching providers.

| 📺 **[YouTube Scraper API](https://apify.com/apidojo/youtube-scraper-api)** | 📋 **[YouTube Playlist Scraper](https://apify.com/apidojo/youtube-playlist-scraper)**                | 🏯 **[YouTube Channel Scraper](https://apify.com/apidojo/youtube-channel-scraper)** |
| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Videos, channels, playlists, search, and trending metadata from one actor   | Every video in a playlist, with position and metadata, ready to feed into this scraper's `startUrls` | Fast retrieval of every video published by a given channel                          |

### Important Note About Usage

This scraper is designed to fetch transcripts from real, public YouTube videos. To ensure a successful run, please follow these rules:

- **Only YouTube URLs are accepted.** The URL validator only processes links whose hostname contains `youtube` or `youtu`: links from any other domain are rejected.
- **The URL must be a watch link with a** `v` **parameter.** Only URLs whose path includes `/watch` and carry a `v` query parameter are mapped to a transcript request; anything else (channel pages, playlists, shorts links without the standard parameter, etc.) is skipped with a warning.
- **At least one start URL is required.** If `startUrls` is empty, the run fails immediately before any processing begins.
- **The video must actually have a transcript.** Videos with captions disabled or unavailable are skipped. No item is pushed for them.
- **Free users**: Limited to **5 runs per month**, each capped at **10 items**

### 🆓 Demo Mode & Free Users

If you run on Apify's Free plan, you can still use this **YouTube Transcript Scraper** in Demo Mode. **Free users can run the actor up to 5 times per month**, with each run capped at a maximum of 10 items — just enough to test it out. Free users also cannot use the actor via API. To use this actor without limitations, subscribe to a paid plan on Apify. [Subscribe here](https://apify.com/pricing?fpr=yhdrb).

### ⚡ Performance & Technical Details

This actor is engineered to deliver fast, predictable transcript extraction, whether you're pulling a single video or processing a large batch of URLs.

#### 🚀 Key Technical Highlights

| **⚡ Feature**                     | **📊 Specification**                        | **🧾 Description**                                                        |
| --------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
| 🚀 **Simple URL Input**           | `youtube.com/watch?v=...` or `youtu.be/...` | Works with links copied directly from YouTube or shared elsewhere         |
| 🌍 **Language Targeting**         | Optional `lang` code                        | Request a specific transcript language instead of the provider default    |
| 📦 **Structured Output**          | JSON with timed transcript segments         | Export-ready format for databases, dashboards, and NLP pipelines          |
| ⚙️ **Custom Configuration**       | `maxItems`, `customMapFunction`             | Fine-tune batch size and reshape output to match specific requirements    |
| 🛡️ **Fault-Tolerant Processing** | Per-video error handling (C001–C003)        | A single video without a transcript doesn't interrupt the rest of the run |
| 📊 **Rich Timing Data**           | `startTime` and `dur` per transcript line   | Precise, second-level timing for every line of spoken content             |

#### 🧭 Reliability Under Load

Each video is processed independently, so backend hiccups, missing transcripts, or rate limits on one video (see error codes C001–C019 in the troubleshooting section) don't stop the rest of the batch. This makes the actor suitable for both one-off single-video pulls and larger batch or bulk transcript jobs across many videos.

### 💰 Pricing

Pricing follows a transparent, pay-per-event model. You're only charged for transcripts that are actually extracted.

#### 📊 Pricing Overview

| **💵 Pricing Item** | **🧮 Price** | **🧭 Description**                                                                                                            |
| ------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| 📝 Video Transcript | $0.001       | Charged per successful transcript extraction (`transcript-query`)                                                             |
| 📦 Dataset Item     | $0.00        | Charged for each item pushed to the dataset, but this actor doesn't charge this event, so it costs nothing regardless of plan |

#### 💵 Understanding Your Costs

- **Single video:** One `startUrls` entry with a valid transcript costs $0.001 for the `transcript-query` charge.
- **Batch run (10 videos):** If all 10 videos return a transcript, you're charged 10 × $0.001 = $0.01. Videos that are skipped (no transcript, invalid URL, or a failed request) are not charged.
- **No extra storage fee:** This actor doesn't charge the `dataset-item` event at all, so there's no additional cost on top of the $0.001 transcript price.

#### 🧭 Why It Works So Well

- ✅ Pay per event: only successfully extracted transcripts are charged.
- 🚀 Scale from a single video lookup to large batch or bulk extraction jobs without unpredictable costs.
- 🎁 No `dataset-item` charge on top of the transcript price, since this actor doesn't bill for that event.

### 📥 Input Parameters

Configuration is minimal. Point the actor at your video links and optionally fine-tune the language and output shape.

| **🧩 Field**      | **📝 Type** | **📖 Description**                                                                                                                                 |
| ----------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| startUrls         | Array       | YouTube video URLs to extract transcripts from. Supported formats: `youtube.com/watch?v=...` and `youtu.be/...`. Required, the run fails if empty. |
| lang              | String      | Optional language code for the transcript (e.g. `en`, `tr`). If omitted, the provider default language is used.                                    |
| maxItems          | Integer     | Limits the number of videos processed in the run.                                                                                                  |
| customMapFunction | String      | A JavaScript function that transforms each output object. Receives one item and must return the modified object. Not intended for filtering.       |

#### ⚡ Supported URL Formats

- 🔗 **Standard watch URL**: `https://www.youtube.com/watch?v=dQw4w9WgXcQ`
- 🔗 **Shortened URL**: `https://youtu.be/dQw4w9WgXcQ`

📌 *Important: The URL must include a* `v` *query parameter and point to a* `/watch` *path. Other YouTube URL types (channels, playlists, etc.) are skipped with a warning.*

### 📤 Output

The actor returns **structured JSON data** for every video: full transcript text broken into timed segments, the selected caption language, and the list of all available languages.

#### 📦 Example Output Object

```json
{
    "inputSource": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "type": "transcript",
    "id": "dQw4w9WgXcQ",
    "transcript": [
        {
            "text": "Welcome back to the channel, today we're exploring something incredible.",
            "dur": "3.52",
            "startTime": "0"
        },
        {
            "text": "Let's take a closer look at how this works.",
            "dur": "2.87",
            "startTime": "3.6"
        }
    ],
    "selected": {
        "title": "English (auto-generated)",
        "languageCode": "en"
    },
    "availableLanguages": [
        {
            "title": "English (auto-generated)",
            "languageCode": "en"
        }
    ]
}
```

#### 🧭 Output Structure Highlights

| **🪄 Field**       | **📖 Description**                                                                  |
| ------------------ | ----------------------------------------------------------------------------------- |
| inputSource, id    | The original URL you provided and the extracted YouTube video ID                    |
| transcript         | Array of timed segments, each with `text`, `startTime`, and `dur` (duration)        |
| selected           | The caption language that was actually returned, with its title and language code   |
| availableLanguages | Every caption language YouTube offers for the video, whether or not it was selected |

Transcript data is returned as clean JSON, ready for immediate use in content pipelines, search indexes, subtitle files, or NLP/AI workflows, or for converting a YouTube video to text at scale.

### 🍳 Custom Map Function

Use this function to reshape the output of every row returned by this actor. It receives each transcript object as an argument, so you can rename fields, change formatting, or pick only the attributes you want in the final output.

**The return value of this function has to be an object.**

Example:

```javascript
(object) => {
    return {
        videoId: object.id,
        language: object.selected.languageCode,
        fullText: object.transcript.map(line => line.text).join(" "),
    };
}
```

This example will:

- Add a new field `videoId`
- Add a new field `language`
- Join every transcript line into a single `fullText` string

Result:

```json
{
    "videoId": "dQw4w9WgXcQ",
    "language": "en",
    "fullText": "Welcome back to the channel, today we're exploring something incredible. Let's take a closer look at how this works."
}
```

You can use the function to:

- Add new fields
- Change existing fields
- Select only the fields you want in the output

**Note:** This function is meant for reshaping, not filtering out entire items. Use it to transform each row, not to drop rows from the run.

### 🔧 Troubleshooting & Common Issues

Encountering issues with the YouTube Transcript Scraper? Below are the error codes and behaviors based on actual actor configuration.

#### ❓ Video Skipped With No Transcript in Output?

**Problem:** A video is missing from your results with no clear error.

**Solution:** This is expected behavior for videos without an available transcript, or where the request to the backend failed. The actor logs the reason and continues with the rest of the batch instead of failing the whole run.

| Error Code | Cause                                                                            | Behavior                                                                 |
| ---------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| C001       | The transcript request to the backend failed (network or unexpected error).      | The video is skipped; no item is pushed for it and processing continues. |
| C002       | The backend returned an empty or unexpected response for the transcript request. | The video is skipped; no item is pushed for it and processing continues. |
| C003       | The backend reports that no transcript exists for the given video.               | The video is skipped; no item is pushed for it and processing continues. |

#### 🚦 Getting Rate-Limit Errors?

**Problem:** A `noResults` error item appears in your dataset.

**Solution:** This corresponds to error code C019: the backend rate limit was exceeded. The actor automatically increments a rate-limit counter and retries the request after a short delay, so no action is needed on your side beyond waiting for the run to complete.

#### 🚨 Actor Run Failed or Exited Immediately?

**Problem:** The run stops entirely instead of just skipping a video.

**Solution:** Check the error code in the Log tab:

| Error Code | Cause                                                              | Behavior                                                           |
| ---------- | ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| C098       | An unhandled promise rejection occurred during the run.            | The error is logged and recorded, and the actor exits immediately. |
| C099       | An uncaught exception occurred during the run.                     | The error is logged and recorded, and the actor exits immediately. |
| C100       | The run failed to initialize with the subscription/policy service. | The actor exits immediately before any videos are processed.       |

If you see C098, C099, or C100, retry the run. If the issue persists, contact support with the run's Log tab output.

#### ⚠️ Getting No Results At All? (Zero Data Returned)

**Problem:** The actor runs but returns 0 items.

**Solution:** Confirm that:

- Each URL in `startUrls` is a `/watch` link containing a `v` query parameter. Other YouTube URL formats are skipped with a warning.
- The hostname of each URL actually contains `youtube` or `youtu`: links from other domains are rejected outright.
- `startUrls` isn't empty. An empty list fails the run before processing begins.
- The target videos actually have captions available (test manually on YouTube first).

#### 📧 Need Additional Help?

If you've tried the solutions above and still experience issues with transcript extraction, check the Log tab in the Apify Console for the specific error code, then reach out via the actor's Issues tab on Apify with the run link and error code attached.

### 🎯 Who Needs This YouTube Transcript Scraper? (Use Cases & Industries)

This video-to-text extraction tool is built for anyone who needs spoken video content as structured, timestamped text, without manually transcribing anything.

#### ✍️ Content Repurposing & Marketing Teams

**Use YouTube Transcript Scraper to turn video content into blog posts, show notes, and social copy.** Content teams pull the transcript of a YouTube video and repurpose it into written formats without re-watching or manually transcribing.

**Key capabilities:**

- Extract full transcripts to draft blog posts or newsletters from existing video content
- Pull timed segments to create accurate video chapter markers or show notes
- Batch-process a channel's back catalog to build a searchable content library
- Feed transcript text directly into SEO or content-optimization tools

**Example:** Scrape the transcript of a podcast's YouTube upload to produce a written recap and pull-quote graphics for social media, without re-listening to the episode. If the recap also needs view counts or channel context, the [YouTube Scraper API](https://apify.com/apidojo/youtube-scraper-api) can fill in that metadata for the same video.

#### 🔍 SEO & Content Marketers

This scraper unlocks the text hidden inside video content for search visibility. Transcript text can be repurposed into on-page content, meta descriptions, or FAQ sections that target the same keywords the video already ranks for.

**Key capabilities:**

- Extract keyword-rich transcript text to inform on-page SEO copy
- Identify frequently discussed topics across a set of videos in a niche
- Build FAQ or article content directly from spoken explanations in tutorial videos
- Pair transcript data with `availableLanguages` to plan multilingual content

**Example:** Scrape transcripts from the top-ranking videos on a topic to identify subtopics and phrasing worth covering in a companion article.

#### 🎓 Researchers & Academic Analysts

Researchers use this actor for discourse and content analysis at scale, extracting structured transcript text with precise timing to study how topics are discussed across many videos.

**Key capabilities:**

- Scrape transcripts across many videos for text-based discourse analysis
- Use `startTime`/`dur` data to align quotes with exact moments in the source video
- Compare `availableLanguages` across videos to study multilingual content coverage
- Build longitudinal datasets tracking how a topic is discussed over time

**Example:** Scrape transcripts from 100 educational videos on the same topic to compare how different creators explain the same concept. For a course-length playlist, the [YouTube Playlist Scraper](https://apify.com/apidojo/youtube-playlist-scraper) can pull every video URL in order first, so you can feed the full list straight into this actor.

#### 🤖 AI & NLP Teams

AI and NLP teams use this actor to source training and evaluation data for language models. Clean, timestamped transcript text is a ready-made input for summarization, classification, or fine-tuning pipelines, and the bulk-friendly input format makes it easy to source data at scale.

**Key capabilities:**

- Collect transcript text at scale to build training corpora
- Use `customMapFunction` to reshape output directly into the schema your pipeline expects
- Pair transcript timing with video metadata for multimodal dataset construction
- Filter by `lang` to build language-specific training sets

**Example:** Scrape transcripts from a curated list of videos in a specific domain to build a fine-tuning dataset for a domain-specific summarization model.

#### ♿ Accessibility & Localization Teams

Accessibility and localization teams use this actor to source raw text for captioning and translation workflows, pulling the existing transcript as a starting point for accessibility review or translation into additional languages.

**Key capabilities:**

- Extract existing transcript text as a base for accessibility audits
- Check `availableLanguages` to see which captions YouTube already offers for a video
- Pull `lang`-specific transcripts to compare translation quality across languages
- Use timed segments to resync or repurpose captions for other platforms

**Example:** Scrape the transcript and available language list for a set of training videos to plan which ones still need translated captions. If the training videos span an entire channel, the [YouTube Channel Scraper](https://apify.com/apidojo/youtube-channel-scraper) can list every video on that channel so nothing gets missed.

### 💡 How to Scrape YouTube Transcripts: Step-by-Step Guide

Getting started is simple, whether you're pulling one video's transcript or processing a batch. Follow this guide to start scraping in minutes.

#### 🚀 Quick Start: 3 Steps to Scrape a YouTube Transcript

**Step 1: Collect Your Video URLs**

The scraper accepts standard watch links:

- **Standard URL:** `https://www.youtube.com/watch?v=dQw4w9WgXcQ`
- **Shortened URL:** `https://youtu.be/dQw4w9WgXcQ`

**Step 2: Configure Your Parameters**

Set your extraction preferences:

- **lang:** Request a specific caption language (optional, defaults to the provider's default language)
- **maxItems:** Cap how many videos are processed in the run
- **customMapFunction:** Reshape output fields with custom JavaScript (optional)

**Step 3: Run & Export**

Click "Start" and let the scraper extract the transcript for each URL. Export the results straight from the Apify Console dataset, or pull them programmatically via the Apify API.

#### 📋 Method 1: Scrape a Single Video Transcript

**Best for:** One-off pulls, quick tests

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

**Output:** The full transcript for that video, with timing data and available languages.

#### 📋 Method 2: Scrape a Specific Language

**Best for:** Standardizing output language across a batch of videos

```json
{
    "startUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "lang": "tr"
}
```

**Output:** The transcript in Turkish, if available for that video; otherwise the provider's fallback behavior applies.

#### 📋 Method 3: Batch or Bulk Process Multiple Videos

**Best for:** Processing a playlist's worth of links or a content backlog in one bulk run

```json
{
    "startUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "https://youtu.be/9bZkp7q19f0"
    ],
    "maxItems": 50
}
```

#### 🧪 Advanced: Reshape Output with a Custom Map Function

**Use case:** You only need a joined transcript string and the language code, not the full segment array

```json
{
    "startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "customMapFunction": "(object) => ({ videoId: object.id, language: object.selected.languageCode, fullText: object.transcript.map(l => l.text).join(' ') })"
}
```

#### 🔧 Best Practices for YouTube Transcript Scraping

**✅ DO:**

- **Use full** `/watch?v=` **or** `youtu.be/` **links**: other YouTube URL formats are skipped
- **Set** `lang` **explicitly** when you need consistent language output across a batch
- **Use reasonable** `maxItems` when testing a new batch before scaling up
- **Use** `customMapFunction` to keep only the fields your pipeline needs, cutting downstream processing
- **Check** `availableLanguages` before assuming a transcript isn't available in the language you want

**❌ DON'T:**

- **Submit non-watch URLs** (channel pages, playlists): they're skipped with a warning, not processed
- **Assume every video has a transcript**: videos with captions disabled will be skipped (error C003)
- **Use** `customMapFunction` **to filter out fields you'll need later**: keep a superset until you're sure of your schema
- **Leave** `startUrls` **empty**: the run fails immediately if no URLs are provided

### ❓ Frequently Asked Questions (FAQ)

#### Can I scrape YouTube transcripts without an API key?

Yes, this scraper extracts transcript data directly from a video's watch URL without requiring a YouTube Data API key or login.

#### Can I use this as a YouTube Transcript API?

Yes. Every run can be triggered through the Apify API, so you can call the actor programmatically as a YouTube Transcript API from your own application, script, or automation, without touching the Apify Console UI.

#### Does this scraper support bulk or batch transcript extraction?

Yes, pass multiple watch URLs in `startUrls` to run it as a bulk YouTube transcript scraper. Use `maxItems` to cap how many videos are processed if you're batch-processing a large list.

#### Is this different from open-source "youtube-transcript" libraries?

It covers similar ground to open-source youtube-transcript packages, but runs as a managed Apify actor with built-in retries, rate-limit handling, batch support, and a hosted API, so there's no need to install or maintain a library yourself.

#### How much does it cost to scrape a YouTube transcript?

You pay $0.001 per successfully extracted transcript (`transcript-query`). There's no separate `dataset-item` charge, since this actor doesn't bill for that event, on any plan.

#### What URL formats are supported?

Both `youtube.com/watch?v=...` and shortened `youtu.be/...` links are supported, as long as the link points to a `/watch` path with a `v` query parameter.

#### What happens if I submit a non-YouTube URL?

It's rejected outright. The URL validator only accepts hostnames containing `youtube` or `youtu`.

#### What happens if a video has no transcript available?

The video is skipped (error code C003) and no item is pushed for it, but the rest of your batch continues processing normally.

#### Can I request a transcript in a specific language?

Yes, use the optional `lang` input field with a language code (e.g. `en`, `tr`). If omitted, the provider's default language is used.

#### Can I filter or reshape the output fields?

Yes, use the `customMapFunction` input to write a JavaScript function that renames, reformats, or selects only the fields you want in the final dataset. It's meant for reshaping rows, not filtering them out.

#### How many videos can I process per run?

Set any value for `maxItems` to cap the run, or leave it empty to process every URL in `startUrls`.

#### What does the transcript timing data look like?

Each transcript line includes `startTime` (seconds from the start of the video) and `dur` (duration of that line in seconds), alongside the `text` itself, everything you need to convert a YouTube video to text with accurate timing.

#### Can I see what other caption languages are available for a video?

Yes, every output item includes an `availableLanguages` array listing every caption language YouTube offers for that video, regardless of which one was selected.

#### What happens if the backend rate limit is hit?

This is error code C019. A `noResults` error item is pushed to the dataset, a rate-limit counter is incremented, and the request is automatically retried after a short delay.

#### Why did my run fail immediately with no videos processed?

This typically corresponds to error code C100 (a failure to initialize with the subscription/policy service) or an empty `startUrls` array. Check the Log tab for the specific cause.

#### Can I automate transcript scraping on a schedule?

Yes, use Apify's built-in scheduler to run the actor automatically. This is useful for pulling transcripts as new videos are published to a channel you monitor.

### Contact

If you need support, check the run's Log tab in the Apify Console for the specific error code first, then reach out via the actor's Issues tab on Apify with the run link attached.

# Actor input Schema

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

Provide YouTube video URLs to extract transcript data. Supported formats include youtube.com/watch?v=... and youtu.be/...

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

Optional language code for the transcript (e.g., 'en', 'tr'). If not provided, the provider default language will be used.

## `maxItems` (type: `integer`):

Limits the number of videos to process.

## `customMapFunction` (type: `string`):

A JavaScript function that transforms each output object. It receives one item and must return the modified object. Do not use for filtering.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.youtube.com/watch?v=_AbFXuGDRTs",
    "https://youtu.be/_AbFXuGDRTs"
  ],
  "lang": "en",
  "maxItems": 100,
  "customMapFunction": "(object) => { return { ...object } }"
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        "https://www.youtube.com/watch?v=_AbFXuGDRTs",
        "https://youtu.be/_AbFXuGDRTs"
    ],
    "lang": "en",
    "maxItems": 100,
    "customMapFunction": (object) => { return { ...object } }
};

// Run the Actor and wait for it to finish
const run = await client.actor("apidojo/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": [
        "https://www.youtube.com/watch?v=_AbFXuGDRTs",
        "https://youtu.be/_AbFXuGDRTs",
    ],
    "lang": "en",
    "maxItems": 100,
    "customMapFunction": "(object) => { return { ...object } }",
}

# Run the Actor and wait for it to finish
run = client.actor("apidojo/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": [
    "https://www.youtube.com/watch?v=_AbFXuGDRTs",
    "https://youtu.be/_AbFXuGDRTs"
  ],
  "lang": "en",
  "maxItems": 100,
  "customMapFunction": "(object) => { return { ...object } }"
}' |
apify call apidojo/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

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