# YouTube Scraper + AI Transcript & Summary (`apigeek/youtube-scraper`) Actor

Fast, low-cost YouTube scraper for videos, search results, channels, Shorts, live streams, playlists, comments, replies, subtitles, and transcripts. Extract structured data, engagement metrics, and filtered search results at scale.

- **URL**: https://apify.com/apigeek/youtube-scraper.md
- **Developed by:** [API Geek](https://apify.com/apigeek) (community)
- **Categories:** Social media, Videos, Developer tools
- **Features:** Limited permissions
- **Stats:** 65 total users, 7 monthly users, 100.0% runs succeeded, 4 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $2.50 / 1,000 video 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?

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

## YouTube Scraper + Subtitles & AI Summary

A fast, reliable, and cost-effective YouTube data extraction API for Apify. Scrape YouTube Videos, Shorts, Live Streams, Channels, Playlists, Comments, Replies, and Filtered Search with native Subtitle Downloads, AI Transcripts, and AI Video Summaries.

***

### ⚡ Key Features

- ⚡ **Fast & Lightweight**: High-performance YouTube data collection optimized for speed and reliability.
- 💬 **Native Subtitles & Captions**: Download video subtitles/closed captions in multiple formats (`text`, `json`, `srt`, `vtt`) directly to Apify Key-Value Store. Supports auto-generated and manual caption tracks.
- 📝 **AI Video Summary**: Generate concise factual summaries and key topics for videos. Automatically uses native subtitles as the primary text source for faster and more cost-effective processing.
- 🎙️ **Optional AI Transcript**: Optional speech-to-text transcription. Uses native subtitles when present (with zero STT audio charges) or audio transcription fallback when explicitly enabled.
- 🔍 **Full YouTube Search**: Search by keywords with YouTube filters (sorting, date posted, video duration, HD, 4K, live streams, and captions).
- 📹 **Rich Video Metadata**: Extract detailed video records including views, likes, comments count, subscriber count, duration, hashtags, keywords, and live stream status.
- 📱 **Shorts & Live Streams**: First-class support for YouTube Shorts and Live Streams across channels and search queries.
- 📺 **Channels & Playlists**: Scrape entire channels and playlists with positional index tracking.
- 💬 **Comments & Replies**: Scrape top-level comments and nested reply threads sorted by Top or Newest.
- 🏷️ **Hashtag Discovery**: Discover and extract videos matching any `#hashtag`.

***

### 💳 Simple & Transparent Pricing (Pay-Per-Event)

This Actor uses predictable Pay-Per-Event (PPE) pricing. Platform usage costs are included in the event pricing so you never get surprise compute bills.

| Event Type | Event Code | Unit Price | Price / 1,000 Units | Description |
| :--- | :--- | :--- | :--- | :--- |
| **Actor Start** | `apify-actor-start` | $0.00005 / run | $0.05 / 1,000 runs | Base run initialization |
| **Video Result** | `video-result` | $0.0025 / item | **$2.50 / 1,000 videos** | Video, Short, or Stream item |
| **Subtitle Download** | `subtitle-result` | $0.001 / item | **$1.00 / 1,000 subtitles** | Downloaded subtitle file saved to KVS |
| **Comment / Reply** | `comment-result` | $0.0015 / item | **$1.50 / 1,000 comments** | Top-level comment or reply item |
| **AI Summary** | `ai-summary` | $0.005 / summary | **$5.00 / 1,000 summaries** | AI summary & key topics |
| **AI Transcript** | `ai-transcript` | $0.007 / started audio-min | **$7.00 / 1,000 audio-mins** | Charged **only** when audio STT is executed. 0 STT charge when native subtitles are used. |

#### Pricing Examples

- **100 Video Results**: `$0.00005 (start) + 100 × $0.0025 = $0.25005`
- **100 Videos with Subtitle Downloads**: `$0.00005 (start) + 100 × $0.0025 (video) + 100 × $0.001 (subtitle) = $0.35005`
- **1 Video with AI Summary (using native subtitles)**: `$0.00005 (start) + $0.0025 (video) + $0.005 (summary) = $0.00755` *(No audio minute fees)*
- **1 Video with AI Summary & Audio STT Fallback (3 min video)**: `$0.00005 (start) + $0.0025 (video) + 3 × $0.007 (transcript) + $0.005 (summary) = $0.02855`

***

### 🛠️ Input Parameters

#### General & Search Settings

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array of Objects | `[]` | YouTube URLs to scrape (Video, Short, Channel, Playlist, Search, or Hashtag). |
| `searchQueries` | Array of Strings | `[]` | Search keywords or phrases to scrape. |
| `maxResults` | Integer | `20` | Maximum number of results to return per query, URL, or channel. |
| `sortingOrder` | String Enum | `"relevance"` | Sort search results: `relevance`, `date`, `viewCount`, `rating`. |
| `dateFilter` | String Enum | `null` | Filter search by upload date: `hour`, `today`, `week`, `month`, `year`. |
| `videoType` | String Enum | `"video"` | Filter search by type: `video`, `channel`, `playlist`, `movie`. |
| `lengthFilter` | String Enum | `null` | Filter search by duration: `short` (<4 min), `medium` (4–20 min), `long` (>20 min). |
| `isHD` | Boolean | `false` | Filter search results for high-definition (HD) videos. |
| `is4K` | Boolean | `false` | Filter search results for 4K resolution videos. |
| `isLive` | Boolean | `false` | Filter search results for active live streams. |
| `hasSubtitles` | Boolean | `false` | **Search Filter**: Restrict search results to videos that have subtitles/closed captions. |

#### Subtitle Options

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `downloadSubtitles` | Boolean | `false` | Download native YouTube subtitle/caption files to the Key-Value Store for each scraped video. |
| `subtitlesLanguage` | String | `"en"` | Preferred subtitle language code (e.g. `"en"`, `"es"`, `"id"`, `"fr"`). |
| `subtitlesFormat` | String Enum | `"text"` | Subtitle output format: `text` (plain text), `json` (timestamped cues), `srt` (SubRip `.srt`), or `vtt` (WebVTT `.vtt`). |

#### Comments & Enrichment

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `maxComments` | Integer | `0` | Maximum top-level comments to scrape per video (`0` = disabled). |
| `maxRepliesPerComment`| Integer | `0` | Maximum nested replies per top-level comment. |
| `commentSort` | String Enum | `"TOP"` | Sort comments by `TOP` or `NEWEST`. |
| `enrichVideoMetadata` | Boolean | `false` | Fetch additional engagement metadata (likes, comments count, views, subscriber count). |

#### AI Features & Decision Logic

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `aiSummary` | Boolean | `false` | Generate an AI summary and key topics. Uses available native subtitle text directly for fast, efficient processing. |
| `aiTranscript` | Boolean | `false` | **Explicit opt-in**: Generate transcript text. If native subtitles exist, uses native subtitles with 0 STT fees. If subtitles are unavailable, enables audio transcription fallback. |
| `aiLanguage` | String | `null` | Target language code for AI processing (e.g. `"en"`, `"es"`, `"de"`). |
| `maxAiVideos` | Integer | `10` | Maximum number of videos to process with AI per run (max: 100). |
| `maxAiDurationMinutes` | Integer | `60` | Maximum duration (in minutes) of an individual video eligible for AI processing. |
| `maxAiMinutesPerRun` | Integer | `60` | Maximum combined duration limit across all AI-processed videos in a run. |

> **AI Decision Logic & Optionality:**
>
> - **Native Subtitles as Primary Text Source**: When `aiSummary: true` is requested and native subtitles exist, the summary is generated directly from native subtitles without downloading audio or charging speech-to-text fees.
> - **STT Fallback Requires Explicit Opt-In**: Audio transcription fallback is **strictly disabled** unless `aiTranscript: true` is explicitly configured. If native subtitles are unavailable and `aiTranscript: false`, AI Summary is skipped gracefully with zero audio extraction or unexpected fees.

***

### 📋 Sample Input

```json
{
  "startUrls": [
    { "url": "https://www.youtube.com/watch?v=BV4ab2l0Re4" }
  ],
  "downloadSubtitles": true,
  "subtitlesLanguage": "en",
  "subtitlesFormat": "srt",
  "aiSummary": true,
  "aiTranscript": false,
  "maxResults": 1
}
```

***

### 📄 Sample Output (Public Dataset Item)

```json
{
  "type": "VIDEO",
  "id": "BV4ab2l0Re4",
  "url": "https://www.youtube.com/watch?v=BV4ab2l0Re4",
  "title": "How to Add Subtitles to YouTube Videos for FREE (+ Closed Captions)",
  "description": "Learn how to add subtitles and closed captions to your YouTube videos easily...",
  "thumbnailUrl": "https://i.ytimg.com/vi/BV4ab2l0Re4/hqdefault.jpg",
  "channelId": "UC4QobU6STFB0P71PMvOGN5A",
  "channelName": "Content Creator",
  "channelUrl": "https://www.youtube.com/channel/UC4QobU6STFB0P71PMvOGN5A",
  "subscriberCount": 150000,
  "viewCount": 163503,
  "likesCount": 4200,
  "publishedAt": "2024-03-15T12:00:00.000Z",
  "duration": "08:42",
  "durationSeconds": 522,
  "isShort": false,
  "isLive": false,
  "liveStatus": "NONE",
  "commentsCount": 350,
  "subtitlesAvailable": true,
  "subtitleTracks": [
    {
      "languageCode": "en",
      "languageName": "English",
      "isAutoGenerated": false
    }
  ],
  "subtitle": {
    "languageCode": "en",
    "languageName": "English",
    "isAutoGenerated": false,
    "format": "srt",
    "storageKey": "SUBTITLE_BV4ab2l0Re4_en_srt"
  },
  "aiSummary": {
    "status": "SUCCESS",
    "source": "native-subtitle",
    "summary": "This tutorial explains the complete step-by-step process of adding subtitles and closed captions to YouTube videos using free tools.",
    "keyTopics": [
      "Subtitles & Captions",
      "YouTube Studio Upload",
      "SRT and VTT formatting"
    ],
    "storageKey": "AI_SUMMARY_BV4ab2l0Re4"
  },
  "scrapedAt": "2026-08-21T08:38:06.126Z"
}
```

***

### 💾 Accessing Subtitles & AI Content from Key-Value Store

Downloaded subtitles, full AI transcripts, and AI summaries are saved in the Actor run's default Key-Value Store:

- **Subtitles**: Stored under `SUBTITLE_{videoId}_{languageCode}_{format}` (e.g. `SUBTITLE_BV4ab2l0Re4_en_srt`).
- **AI Transcripts**: Stored under `AI_TRANSCRIPT_{videoId}` containing full timestamped segments and metadata.
- **AI Summaries**: Stored under `AI_SUMMARY_{videoId}` containing executive summary text and key topic tags.

You can retrieve these records directly via the Apify Console Key-Value Store tab or via the Apify API client.

# Actor input Schema

## `searchQueries` (type: `array`):

List of YouTube search keywords or phrases to scrape.

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

YouTube URLs to scrape (Video, Short, Channel, Playlist, Search, or Hashtag).

## `maxResults` (type: `integer`):

Maximum number of video/playlist results to collect per query or channel feed.

## `sortingOrder` (type: `string`):

Sorting order for YouTube search queries.

## `dateFilter` (type: `string`):

Filter search results by upload date window.

## `lengthFilter` (type: `string`):

Filter search results by video duration.

## `videoType` (type: `string`):

Filter search results by content category.

## `isHD` (type: `boolean`):

Filter search results to high-definition (HD) videos.

## `hasSubtitles` (type: `boolean`):

Filter search results to videos with subtitles/CC.

## `isLive` (type: `boolean`):

Filter search results to active live streams.

## `is4K` (type: `boolean`):

Filter search results to 4K resolution videos.

## `oldestPostDate` (type: `string`):

Stop crawling search results when videos become older than this ISO date (e.g. '2026-01-01').

## `maxResultsShorts` (type: `integer`):

Maximum number of Shorts items to collect when scraping a channel.

## `maxResultStreams` (type: `integer`):

Maximum number of Live / Stream items to collect when scraping a channel.

## `sortVideosBy` (type: `string`):

Sorting order for channel videos tab.

## `downloadSubtitles` (type: `boolean`):

Download native YouTube subtitle/caption files to the Key-Value Store for each applicable video.

## `subtitlesLanguage` (type: `string`):

Language code for downloaded subtitles (e.g. 'en', 'en-US', 'es', 'id').

## `subtitlesFormat` (type: `string`):

File format used for downloaded subtitle content in Key-Value Store.

## `maxComments` (type: `integer`):

Maximum top-level comments to scrape per video (0 = disabled).

## `maxRepliesPerComment` (type: `integer`):

Maximum reply comments to scrape per top-level comment.

## `commentSort` (type: `string`):

Sort order for comments (Top comments vs Newest first).

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

Optional network settings for advanced users.

## `enrichVideoMetadata` (type: `boolean`):

Fetch additional video engagement metadata such as likes, comment count, views, and channel subscriber count when available.

## `maxEnrichedVideos` (type: `integer`):

Maximum number of videos to enrich with additional engagement metadata in this run (default: 20, max: 100).

## `aiTranscript` (type: `boolean`):

Generate an AI transcript from the video's audio. Optional paid feature. AI Transcript is charged per started audio minute.

## `aiSummary` (type: `boolean`):

Generate an AI-powered summary for the video. Optional paid feature. AI Summary is charged per generated summary.

## `aiLanguage` (type: `string`):

Target language ISO code for AI transcription/summary (e.g. 'en', 'es', 'de').

## `maxAiVideos` (type: `integer`):

Maximum number of videos to process with AI in this run (default: 10, max: 100).

## `maxAiDurationMinutes` (type: `integer`):

Maximum duration of an individual video eligible for AI processing (default: 60, max: 120).

## `maxAiMinutesPerRun` (type: `integer`):

Maximum total combined duration of videos processed by AI during this run (default: 60, max: 600).

## Actor input object example

```json
{
  "searchQueries": [
    "bitcoin news",
    "apify tutorial"
  ],
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    },
    {
      "url": "https://www.youtube.com/@Google"
    },
    {
      "url": "https://www.youtube.com/playlist?list=PLBCF2DAC6FFB574DE"
    },
    {
      "url": "https://www.youtube.com/results?search_query=bitcoin"
    },
    {
      "url": "https://www.youtube.com/hashtag/bitcoin"
    }
  ],
  "maxResults": 20,
  "sortingOrder": "relevance",
  "videoType": "video",
  "isHD": false,
  "hasSubtitles": false,
  "isLive": false,
  "is4K": false,
  "oldestPostDate": "2026-01-01",
  "maxResultsShorts": 0,
  "maxResultStreams": 0,
  "sortVideosBy": "NEWEST",
  "downloadSubtitles": false,
  "subtitlesLanguage": "en",
  "subtitlesFormat": "text",
  "maxComments": 0,
  "maxRepliesPerComment": 0,
  "commentSort": "TOP",
  "enrichVideoMetadata": false,
  "maxEnrichedVideos": 20,
  "aiTranscript": false,
  "aiSummary": false,
  "maxAiVideos": 10,
  "maxAiDurationMinutes": 60,
  "maxAiMinutesPerRun": 60
}
```

# Actor output Schema

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

Successful video and comment results produced by the Actor.

## `storage` (type: `string`):

Channel metadata, playlist metadata, subtitle files, and related output records.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("apigeek/youtube-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 = {}

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

```

## MCP server setup

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