# YouTube Scraper (`brilliant_gum/youtube-scraper`) Actor

Extract videos, comments & transcripts from any YouTube channel, playlist or search. Supports @handles, Shorts filter, date range & min views. Full transcripts with timestamps — perfect for AI/LLM datasets. No API key needed.

- **URL**: https://apify.com/brilliant\_gum/youtube-scraper.md
- **Developed by:** [Yuliia Kulakova](https://apify.com/brilliant_gum) (community)
- **Categories:** Social media, Videos, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 video scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Scraper — Videos, Comments & Transcripts

![YouTube Scraper](https://i.postimg.cc/CxMNX7M0/yt-banner-clean.png)

Extract videos, comments, and full transcripts from YouTube — no API key required. Works with channels, playlists, search queries, and direct video URLs. Built for AI/LLM datasets, market research, competitor analysis, and content intelligence.

---

### 💰 Pricing

Pay only for what you extract — three separate billing events:

| What               | Cost                    |
|--------------------|-------------------------|
| 📹 Videos          | **$15 per 1,000**       |
| 💬 Comments        | **$8 per 1,000**        |
| 📝 Transcripts     | **$5 per transcript**   |

A small one-time actor-start fee applies per run. You are never charged for videos that are filtered out or skipped.

---

### ✨ Key Features

#### 📝 Full Transcripts with Timestamps
Extracts complete captions — both manual and auto-generated — broken into timestamped segments. Each segment has a `start` time (seconds), `duration`, and `text`. The `fullText` field provides the entire transcript as a single string. Perfect for building AI training datasets, video summarization pipelines, search indexing, and subtitle analysis.

#### 🔄 Four Input Types
- **Channel URLs** including `@handle` format — scrapes the full video library from a channel
- **Playlist URLs** — both user-created playlists (`PL...`) and YouTube Mix/Radio playlists (`RD...`)
- **Search queries** — finds videos matching one or more keyword queries
- **Direct video URLs** — pinpoint specific videos by URL or video ID

#### 📊 Rich Video Metadata
Every video record includes: title, description, channel info, view count, like count, tags, category, duration in both human-readable and seconds format, publish date, thumbnail URL, and whether the video is a YouTube Short.

#### 💬 Comments with Replies
Captures top-level comments and their replies in a single flat dataset. Each comment record includes the author name, channel ID, like count, reply count, pin status, and whether it is a reply (with `parentCommentId` for threading).

#### 🔍 Powerful Filters
Filter videos before scraping details to save cost and time:
- **Minimum views** — skip low-traffic videos
- **Date range** — only videos published after a specific date
- **Video type** — regular videos only, Shorts only, or all

---

### 🚀 Quick Start

#### Option 1 — Channel URL
Paste a channel URL to scrape all videos from that channel.
````

https://www.youtube.com/@MrBeast
https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA

```

#### Option 2 — Playlist
Paste a playlist URL. Works with standard playlists and YouTube Radio/Mix playlists.
```

https://www.youtube.com/playlist?list=PLxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
https://www.youtube.com/watch?v=dQw4w9WgXcQ\&list=RDdQw4w9WgXcQ

````

#### Option 3 — Search Queries
Provide one or more search terms as a list. The scraper returns the top results for each query.
```json
["python tutorial", "machine learning 2024", "startup advice"]
````

#### Option 4 — Direct Video URL

Provide one or more video URLs to scrape specific videos.

```
https://www.youtube.com/watch?v=dQw4w9WgXcQ
https://youtu.be/dQw4w9WgXcQ
```

***

### ⚙️ Input Parameters

| Parameter              | Type    | Default | Description |
|------------------------|---------|---------|-------------|
| `startUrls`            | array   | —       | YouTube URLs: video, channel, playlist, or search results page |
| `searchQueries`        | array   | —       | Keywords to search for (each query runs independently) |
| `maxVideos`            | integer | 50      | Maximum number of videos to process per run |
| `scrapeComments`       | boolean | false   | Extract comments for each video |
| `maxCommentsPerVideo`  | integer | 100     | Maximum comments to extract per video |
| `scrapeTranscripts`    | boolean | false   | Extract full transcripts (captions) with timestamps |
| `filterVideoType`      | string  | all     | Filter by type: `all`, `videos` (excludes Shorts), or `shorts` |
| `filterByMinViews`     | integer | 0       | Skip videos with fewer than this many views |
| `filterByDateFrom`     | string  | —       | Only include videos published on or after this date (`YYYY-MM-DD`) |
| `filterByLanguage`     | string  | `en`    | Preferred transcript language code (e.g. `en`, `es`, `de`) |

***

### 📦 Output Format

All results are saved to the Apify dataset. Three record types are mixed in a single dataset and can be filtered by the `type` field.

***

#### Video Record (`type: "video"`)

One record per video with full metadata.

```json
{
  "type": "video",
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "description": "The official video for \"Never Gonna Give You Up\" by Rick Astley...",
  "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "channelName": "Rick Astley",
  "channelUrl": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
  "publishedAt": "2009-10-25",
  "duration": "3:33",
  "durationSeconds": 213,
  "viewCount": 1760000000,
  "likeCount": 18000000,
  "commentCount": 0,
  "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
  "tags": ["rick astley", "never gonna give you up", "80s music", "rickroll"],
  "category": "Music",
  "isShort": false,
  "scrapedAt": "2026-04-09T07:32:21.574Z"
}
```

**Field reference:**

| Field | Type | Description |
|-------|------|-------------|
| `videoId` | string | YouTube video ID |
| `url` | string | Full watch URL |
| `title` | string | Video title |
| `description` | string | Full video description |
| `channelId` | string | YouTube channel ID (`UC...`) |
| `channelName` | string | Channel display name |
| `channelUrl` | string | Channel URL |
| `publishedAt` | string | Publish date (ISO format when available, human-readable otherwise) |
| `duration` | string | Duration in `H:MM:SS` or `M:SS` format |
| `durationSeconds` | integer | Duration in seconds |
| `viewCount` | integer | Total view count |
| `likeCount` | integer | Total like count |
| `commentCount` | integer | Comment count (may be 0 if not returned by the API) |
| `thumbnailUrl` | string | Max-resolution thumbnail URL |
| `tags` | array | Video tags set by the uploader |
| `category` | string | YouTube category (Music, Education, etc.) |
| `isShort` | boolean | True if video duration is 60 seconds or less |
| `scrapedAt` | string | ISO timestamp of when the record was created |

***

#### Comment Record (`type: "comment"`)

One record per comment or reply. Top-level comments and replies are saved as flat records — use `isReply` and `parentCommentId` to reconstruct threads.

```json
{
  "type": "comment",
  "commentId": "UgxHPK_QyTdcuyvuX7B4AaABAg",
  "videoId": "dQw4w9WgXcQ",
  "videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "text": "I came here voluntarily. Nobody rickrolled me.",
  "authorName": "@username",
  "authorChannelId": "UCxxxxxxxxxxxxxxxxxxxxxxxxx",
  "likeCount": 134000,
  "replyCount": 463,
  "isReply": false,
  "parentCommentId": null,
  "publishedAt": "6 years ago",
  "isPinned": false,
  "scrapedAt": "2026-04-09T07:32:24.880Z"
}
```

**Field reference:**

| Field | Type | Description |
|-------|------|-------------|
| `commentId` | string | Unique YouTube comment ID |
| `videoId` | string | Parent video ID |
| `videoTitle` | string | Parent video title |
| `text` | string | Full comment text |
| `authorName` | string | Author's @handle |
| `authorChannelId` | string | Author's channel ID |
| `likeCount` | integer | Number of likes on the comment |
| `replyCount` | integer | Number of replies (top-level comments only) |
| `isReply` | boolean | True if this is a reply to another comment |
| `parentCommentId` | string | ID of the parent comment if `isReply` is true |
| `publishedAt` | string | Relative publish time as shown on YouTube |
| `isPinned` | boolean | True if the comment is pinned by the channel |

***

#### Transcript Record (`type: "transcript"`)

One record per video. Contains the full transcript broken into timed segments plus a concatenated `fullText` field.

```json
{
  "type": "transcript",
  "videoId": "dQw4w9WgXcQ",
  "videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "language": "en",
  "languageName": "English (auto-generated)",
  "isAutoGenerated": true,
  "segments": [
    { "start": 18.8,  "duration": 7.16, "text": "We're no strangers to love." },
    { "start": 25.96, "duration": 4.32, "text": "You know the rules and so do I." },
    { "start": 30.28, "duration": 9.28, "text": "You wouldn't get this from any other guy." }
  ],
  "fullText": "We're no strangers to love. You know the rules and so do I...",
  "wordCount": 291,
  "scrapedAt": "2026-04-09T07:32:26.316Z"
}
```

**Field reference:**

| Field | Type | Description |
|-------|------|-------------|
| `language` | string | ISO 639-1 language code (e.g. `en`) |
| `languageName` | string | Human-readable language name |
| `isAutoGenerated` | boolean | True if auto-generated captions, false if manually created |
| `segments` | array | Array of timed segments with `start`, `duration`, and `text` |
| `fullText` | string | All segment text concatenated into one string |
| `wordCount` | integer | Total word count of the transcript |

***

### 🔍 Use Case Examples

#### Build an LLM training dataset from a podcast channel

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/@lexfridman" }],
  "maxVideos": 200,
  "scrapeTranscripts": true,
  "filterByLanguage": "en",
  "filterVideoType": "videos"
}
```

#### Competitor sentiment analysis via comments

```json
{
  "searchQueries": ["notion app review", "notion vs obsidian 2024"],
  "maxVideos": 50,
  "scrapeComments": true,
  "maxCommentsPerVideo": 300,
  "filterByMinViews": 10000
}
```

#### Scrape only YouTube Shorts from a channel

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/@MrBeast" }],
  "maxVideos": 200,
  "filterVideoType": "shorts"
}
```

#### Monitor new uploads (weekly incremental run)

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/@ycombinator" }],
  "maxVideos": 20,
  "filterByDateFrom": "2026-04-01"
}
```

#### Research trending videos with minimum reach

```json
{
  "searchQueries": ["AI tools 2026", "ChatGPT tutorial"],
  "maxVideos": 30,
  "filterByMinViews": 500000,
  "filterByDateFrom": "2026-01-01",
  "scrapeComments": true,
  "maxCommentsPerVideo": 100
}
```

#### Scrape a specific playlist with transcripts

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&list=RDdQw4w9WgXcQ" }],
  "maxVideos": 20,
  "scrapeTranscripts": true
}
```

***

### 📊 Who Uses This

| Use Case | Who | What They Get |
|----------|-----|---------------|
| **LLM / AI training data** | AI & ML teams | Timestamped transcripts from thousands of videos in structured JSON |
| **Competitive research** | Product teams | What real users say about competitor products in comments |
| **SEO & content strategy** | Marketers | Top-performing titles, tags, view/engagement metrics |
| **Influencer analytics** | Agencies | Channel video performance, engagement trends over time |
| **Shorts trend analysis** | Creators | Trending Shorts topics, view/engagement ratios |
| **Academic research** | Researchers | Comment corpora for NLP, sentiment analysis, discourse studies |
| **Market research** | Analysts | Consumer opinions from product reviews and unboxing videos |
| **Podcast transcription** | Journalists & writers | Full text of long-form interviews and podcast episodes |
| **Education data** | EdTech companies | Course content from educational channels in structured format |

***

### 💡 Pro Tips

**1. Transcripts for AI training**
Use `scrapeTranscripts: true` with a focused channel. Set `filterVideoType: "videos"` to skip Shorts, which rarely have quality transcripts. Prefer channels that publish manual (not auto-generated) subtitles for higher accuracy.

**2. Trending Shorts discovery**
Combine `filterVideoType: "shorts"` + `filterByDateFrom` (last 7–14 days) + `filterByMinViews: 50000` to surface only breakout Shorts from the past week.

**3. Comment sentiment at scale**
Run with `scrapeComments: true` and `maxCommentsPerVideo: 500` on product review videos. Filter by `filterByMinViews: 5000` to ensure the comments represent real audience volume.

**4. Incremental monitoring**
Schedule this actor weekly. Set `filterByDateFrom` to the previous Monday. This way you only process newly published videos and never duplicate data.

**5. Multi-query keyword research**
Pass 5–10 related search queries in `searchQueries`. Analyze the `tags` and `title` fields across results to discover the vocabulary your target audience uses.

**6. Combining sources**
You can mix `startUrls` and `searchQueries` in a single run. Results from all sources are deduplicated — each video is processed only once even if it appears in multiple sources.

***

### ⚠️ Limits & Notes

- **No API key required** — the scraper uses YouTube's internal API, the same one used by the YouTube website and mobile apps.
- **Transcripts availability** — not all videos have captions. If no transcript is found, the video record is still saved, but no transcript record is created.
- **Tags and category** — some videos, particularly older ones or those on music label channels, do not return tags or category via the API. These fields will be empty arrays or empty strings in that case.
- **`publishedAt` format** — for most videos this is an ISO date. For some videos the YouTube API returns a relative string like `"3 years ago"` or `"Premiered Dec 27, 2022"` — these are preserved as-is.
- **Comments** — the scraper fetches comments sorted by Top Comments. Replies are included when paginating through comment threads.
- **Rate limiting** — the scraper includes automatic retry logic and pacing to handle YouTube's rate limits gracefully.

***

### ❓ FAQ

**Q: Do I need a YouTube API key?**
No. The scraper uses YouTube's internal Innertube API — the same one used by the YouTube website and mobile apps — so no API key or developer account is required.

**Q: How many videos can I scrape per run?**
There is no hard limit beyond `maxVideos`. You can set it to 1,000 or more. Keep in mind that each video requires a few API calls, so large runs take time. For channels or playlists with thousands of videos, consider running multiple incremental jobs with `filterByDateFrom`.

**Q: Why is `commentCount` always 0 in the video record?**
YouTube's Innertube API does not reliably return the comment count in the metadata response. The actual comments are fetched separately when `scrapeComments: true`. The `commentCount` field is kept in the schema for compatibility but will typically be 0.

**Q: Why does some videos have an empty description or missing `publishedAt`?**
Certain videos — especially on music label or VEVO channels — are restricted by YouTube's internal API and return limited metadata. The scraper makes a best-effort attempt to fill all fields using multiple API endpoints, but some fields may remain empty for these videos.

**Q: What happens if a video has no captions?**
If `scrapeTranscripts: true` and no captions are available, no transcript record is created for that video. The video record is still saved. The `scrapeTranscripts` billing event only fires when a transcript is successfully retrieved.

**Q: Can I scrape private or age-restricted videos?**
No. The scraper only accesses publicly available content — the same content visible to any logged-out user. Private, unlisted, or age-restricted videos are not accessible.

**Q: How does billing work exactly?**
You are charged three separate per-event fees:

- **$15 per 1,000 videos** processed (billed per video, after filters pass)
- **$8 per 1,000 comments** extracted
- **$5 per transcript** successfully retrieved

A small one-time actor-start fee also applies. Videos filtered out by `filterByMinViews`, `filterByDateFrom`, or `filterVideoType` are **not** billed.

**Q: Can I run this on a schedule?**
Yes. Use the Apify scheduler to run the actor weekly or daily. Set `filterByDateFrom` to the start of the period you want to capture. This avoids re-processing already-scraped videos and minimizes cost.

**Q: How do I get transcripts in a specific language?**
Set `filterByLanguage` to the ISO 639-1 code (e.g. `"en"`, `"es"`, `"de"`). If a transcript in that language is not available, the scraper will fall back to any available language. To strictly require a language, filter the output by the `language` field in the transcript record.

**Q: Are YouTube Shorts supported?**
Yes. Use `filterVideoType: "shorts"` to scrape only Shorts, `filterVideoType: "videos"` to exclude them, or `filterVideoType: "all"` (default) to include both.

***

### ⚖️ Legal & Ethical Use

This scraper accesses publicly available data on YouTube — the same data visible to any user without logging in. Use it for legitimate research, content analysis, and data science purposes.

Always comply with:

- [YouTube Terms of Service](https://www.youtube.com/t/terms)
- Applicable data protection regulations (GDPR, CCPA, etc.)

Do not use scraped data to build spam systems, harass individuals, or circumvent YouTube's monetization systems.

***

### 🛠️ Technical Notes

- Built on the **Apify SDK** with pay-per-event billing (`Actor.charge()`)
- Uses YouTube's **Innertube API** (the same internal API used by youtube.com) — no official Data API quota required
- Transcript fetching uses the **Android Innertube client** to access caption tracks without authentication tokens
- Comment pagination follows the **2024–2026 YouTube comment format** using `commentEntityPayload` from `frameworkUpdates.entityBatchUpdate.mutations`
- Residential proxy is used automatically for all requests to ensure reliable access

# Actor input Schema

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

YouTube URLs to scrape. Supports: video URLs (watch?v=...), channel URLs (/channel/UC... or /@handle), playlist URLs (list=...), search result URLs.

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

Search terms to find videos on YouTube. Each query returns up to maxVideos results.

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

Maximum number of videos to scrape per run. Default: 50. Max: 10,000.

## `scrapeComments` (type: `boolean`):

If enabled, scrapes comments for each video. Charged separately at $8 per 1,000 comments.

## `maxCommentsPerVideo` (type: `integer`):

Maximum number of comments to extract per video. Default: 100. Max: 10,000.

## `scrapeTranscripts` (type: `boolean`):

If enabled, extracts the full transcript (subtitles/captions) for each video. Includes auto-generated captions. Charged separately at $5 per transcript.

## `filterVideoType` (type: `string`):

Filter by video type.

## `filterByMinViews` (type: `integer`):

Only include videos with at least this many views. Leave 0 for no minimum.

## `filterByDateFrom` (type: `string`):

Only include videos published on or after this date. Format: YYYY-MM-DD.

## `filterByLanguage` (type: `string`):

ISO 639-1 language code for transcript preference (e.g. en, fr, de, es). Falls back to English, then first available.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/@MrBeast"
    }
  ],
  "searchQueries": [],
  "maxVideos": 50,
  "scrapeComments": false,
  "maxCommentsPerVideo": 100,
  "scrapeTranscripts": false,
  "filterVideoType": "all",
  "filterByMinViews": 0,
  "filterByLanguage": "en"
}
```

# Actor output Schema

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

All scraped records stored in the default dataset. Each record has a 'type' field: 'video', 'comment', or 'transcript'. Video records include videoId, url, title, channelName, viewCount, likeCount, publishedAt, duration, durationSeconds, commentCount, thumbnailUrl, tags, category, and isShort. Comment records include commentId, videoId, videoTitle, text, authorName, likeCount, replyCount, and publishedAt. Transcript records include videoId, videoTitle, language, languageName, isAutoGenerated, fullText, wordCount, and segments.

# 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/@MrBeast"
        }
    ],
    "searchQueries": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("brilliant_gum/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 = {
    "startUrls": [{ "url": "https://www.youtube.com/@MrBeast" }],
    "searchQueries": [],
}

# Run the Actor and wait for it to finish
run = client.actor("brilliant_gum/youtube-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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/@MrBeast"
    }
  ],
  "searchQueries": []
}' |
apify call brilliant_gum/youtube-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=brilliant_gum/youtube-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Scraper",
        "description": "Extract videos, comments & transcripts from any YouTube channel, playlist or search. Supports @handles, Shorts filter, date range & min views. Full transcripts with timestamps — perfect for AI/LLM datasets. No API key needed.",
        "version": "0.1",
        "x-build-id": "mQuqtLwavgAC5ghdT"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/brilliant_gum~youtube-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-brilliant_gum-youtube-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/brilliant_gum~youtube-scraper/runs": {
            "post": {
                "operationId": "runs-sync-brilliant_gum-youtube-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/brilliant_gum~youtube-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-brilliant_gum-youtube-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "YouTube URLs to scrape. Supports: video URLs (watch?v=...), channel URLs (/channel/UC... or /@handle), playlist URLs (list=...), search result URLs.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "searchQueries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "Search terms to find videos on YouTube. Each query returns up to maxVideos results.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxVideos": {
                        "title": "Max videos",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of videos to scrape per run. Default: 50. Max: 10,000.",
                        "default": 50
                    },
                    "scrapeComments": {
                        "title": "Scrape comments",
                        "type": "boolean",
                        "description": "If enabled, scrapes comments for each video. Charged separately at $8 per 1,000 comments.",
                        "default": false
                    },
                    "maxCommentsPerVideo": {
                        "title": "Max comments per video",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of comments to extract per video. Default: 100. Max: 10,000.",
                        "default": 100
                    },
                    "scrapeTranscripts": {
                        "title": "Scrape transcripts",
                        "type": "boolean",
                        "description": "If enabled, extracts the full transcript (subtitles/captions) for each video. Includes auto-generated captions. Charged separately at $5 per transcript.",
                        "default": false
                    },
                    "filterVideoType": {
                        "title": "Video type",
                        "enum": [
                            "all",
                            "videos",
                            "shorts"
                        ],
                        "type": "string",
                        "description": "Filter by video type.",
                        "default": "all"
                    },
                    "filterByMinViews": {
                        "title": "Minimum views",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include videos with at least this many views. Leave 0 for no minimum.",
                        "default": 0
                    },
                    "filterByDateFrom": {
                        "title": "Published from date",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "type": "string",
                        "description": "Only include videos published on or after this date. Format: YYYY-MM-DD."
                    },
                    "filterByLanguage": {
                        "title": "Preferred transcript language",
                        "type": "string",
                        "description": "ISO 639-1 language code for transcript preference (e.g. en, fr, de, es). Falls back to English, then first available.",
                        "default": "en"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
