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

Scrape YouTube search results, videos, Shorts, live streams, channels with social links, playlists, community posts, comments with nested replies and transcripts. Full search filters, exact counts, fast and low cost.

- **URL**: https://apify.com/calm_builder/youtube-scraper.md
- **Developed by:** [Coder](https://apify.com/calm_builder) (community)
- **Categories:** Social media, Videos, Automation
- **Features:** Limited permissions
- **Stats:** 61 total users, 14 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

Scrape **YouTube search results, videos, Shorts, live streams, channels, playlists and community posts** into clean JSON, CSV or Excel. Get exact views, likes and comment counts, full descriptions with links, hashtags, tags, publish times, **channel details with every social link**, **comments with nested replies**, **transcripts**, chapters and YouTube's AI video summaries. **Every YouTube search filter is built in** - no YouTube account, no login and no API key needed.

Use it for **market and competitor research**, **influencer discovery and outreach**, **content and trend analysis**, **brand monitoring**, **audience and sentiment research (comments)**, **AI / LLM datasets (transcripts)** and **analytics dashboards**.

***

### What you get

| Input | You get |
| --- | --- |
| **Search term** | Videos, Shorts, live streams, channels and playlists from YouTube search, with any combination of YouTube's filters |
| **Channel link or @handle** | The channel's videos, Shorts and streams (latest, popular or oldest first), its community posts and playlists, and the full channel profile |
| **Playlist link** | The playlist's details and its videos in order |
| **Video, Short or live link** | That video with full details |
| **Community post link** | The post, with its comments |
| **YouTube search link** | The results of that search, with the filters already in the link |

Results are saved in **five tables**, so each kind of data opens as its own clean spreadsheet: **Videos** (videos, Shorts and streams), **Channels**, **Comments**, **Posts** and **Playlists**.

#### Every video includes

| Section | Fields |
| --- | --- |
| **Basics** | ID, URL, type (video / short / stream), title, full description, links found in the description, hashtags, tags, thumbnail |
| **Numbers** | **Exact** view count, like count and comment count, whether comments are turned off |
| **Time & length** | Duration, exact publish time, live start / end times, scheduled start, current viewers for live streams |
| **Details** | Category, language, made for kids, age-restricted, unlisted, license (standard / Creative Commons), HD / SD, 360°, 3D, captions available, **paid promotion**, region restrictions, topics, recording location |
| **Channel** | Channel ID, name, handle, URL |
| **Add-ons** | Chapters, YouTube's AI summary, members-only flag, collaborators, Shorts sound, transcripts (see below) |

#### Channel details (optional)

Name, handle, description, **all social and website links** (Instagram, X/Twitter, TikTok, Facebook, Discord, websites ...), country, join date, subscribers, **total views**, video count, verified and artist badges, whether a business email is listed, avatar, banner, keywords and the channel's tabs.

#### Comments with nested replies

Every comment and reply is one row with the text, author (name, channel, avatar, verified, **is the channel owner**), **exact like count**, reply count, **exact publish time**, edited, pinned and **creator heart**. Replies are collected up to **6 levels deep** (replies to replies), and each row carries `replyLevel`, `parentId` and `rootId` so you can rebuild every thread.

#### Transcripts

The video's captions as plain text, timed segments (start, duration, text) or SRT subtitles, in the languages you choose. Manual captions are preferred over auto-generated ones, and every video also lists all the caption languages it has.

***

### Input

| Field | What it does |
| --- | --- |
| **Search terms** | Keywords to search, one per row |
| **YouTube links or channel handles** | Any YouTube link or `@handle`. Add a tab to a channel link (`/videos`, `/shorts`, `/streams`, `/posts`, `/playlists`) to scrape only that tab |
| **Maximum videos / Shorts / live streams** | How many of each to collect per search term, channel or playlist. 0 skips that kind |
| **Maximum channels / playlists from search** | Also collect channels or playlists that match a search term |
| **Search filters** | Sort by (relevance, popularity), upload date (today, this week, this month, this year), duration (under 3, 3-20, over 20 minutes) and features (HD, 4K, subtitles, Creative Commons, 360°, VR180, 3D, HDR, location, purchased) - the same options as YouTube's filter panel |
| **Channel videos order** | Latest, popular or oldest first |
| **Published after** | Keep only items published after a date (`2026-09-01`) or within a period (`7 days`, `3 months`) |
| **Add channel details** | One channel row for every channel you entered and every collected video's channel, with social links (charged per channel) |
| **Maximum community posts / playlists per channel** | Collect a channel's posts and playlists |
| **Add chapters and AI summary** | Chapters, YouTube's AI summary, members-only flag and collaborators |
| **Add Shorts sound** | The sound or song a Short uses |
| **Add transcripts** | Captions, with language preference and format |
| **Comments** | Maximum comments per video or post, order (top / newest), reply depth (0-6), replies per comment and a "published after" date |
| **Country** | The country YouTube shows results for |

#### Example input

```json
{
    "searchQueries": ["ai tools for students"],
    "startUrls": ["https://www.youtube.com/@mkbhd"],
    "maxResults": 20,
    "maxResultsShorts": 10,
    "searchUploadDate": "month",
    "searchFeatures": ["hd", "subtitles"],
    "includeChannelInfo": true,
    "includeTranscripts": true,
    "transcriptLanguages": ["en"],
    "maxComments": 50,
    "maxReplyDepth": 2
}
```

***

### Example output

#### Video

```json
{
    "type": "video",
    "id": "DkUuOr21v4s",
    "url": "https://www.youtube.com/watch?v=DkUuOr21v4s",
    "title": "Xiaomi 18 Pro Max: They've Done It Again!",
    "description": "If one-upping the iPhone was a sport, Xiaomi would be Lebron James.\n\nMKBHD Merch: http://shop.MKBHD.com ...",
    "descriptionLinks": ["http://shop.MKBHD.com", "https://goo.gl/B3AWV5"],
    "hashtags": [],
    "tags": ["Xiaomi", "Xiaomi 18 Pro", "Xiaomi 18 Pro Max", "18 Pro Max"],
    "thumbnailUrl": "https://i.ytimg.com/vi/DkUuOr21v4s/uhddefault.jpg",
    "viewCount": 7607998,
    "likeCount": 90294,
    "commentCount": 5167,
    "commentsTurnedOff": false,
    "duration": "11:56",
    "durationSeconds": 716,
    "publishedAt": "2026-09-24T22:26:18Z",
    "category": "Science & Technology",
    "language": "en",
    "isLive": false,
    "madeForKids": false,
    "isAgeRestricted": false,
    "license": "standard",
    "definition": "hd",
    "hasCaptions": true,
    "hasPaidPromotion": false,
    "topics": ["Technology"],
    "channel": {
        "id": "UCBJycsmduvYEL83R_U4JriQ",
        "name": "Marques Brownlee",
        "handle": "@mkbhd",
        "url": "https://www.youtube.com/@mkbhd"
    },
    "chapters": [],
    "aiSummary": "Marques Brownlee examines the Xiaomi 18 Pro Max, exploring its hardware upgrades including a new privacy display, advanced camera system ...",
    "transcripts": [
        {
            "language": "en",
            "languageName": "English",
            "isAutoGenerated": false,
            "text": "So this is the new iPhone 18 Pro Max, and this is the new Xiaomi... 18 Pro Max. ..."
        }
    ],
    "availableTranscriptLanguages": ["en", "ja", "pt", "ru", "tr", "vi"],
    "source": { "input": "@mkbhd", "type": "channel", "tab": "videos", "position": 1 },
    "scrapedAt": "2026-09-26T13:42:31Z"
}
```

#### Channel

```json
{
    "type": "channel",
    "id": "UCBJycsmduvYEL83R_U4JriQ",
    "url": "https://www.youtube.com/@mkbhd",
    "name": "Marques Brownlee",
    "handle": "@mkbhd",
    "links": [
        { "title": "Twitter", "url": "http://twitter.com/MKBHD" },
        { "title": "Instagram", "url": "http://instagram.com/MKBHD" },
        { "title": "Reddit", "url": "http://reddit.com/r/MKBHD" },
        { "title": "Discord", "url": "http://discord.gg/MKBHD" }
    ],
    "country": "United States",
    "joinedAt": "2008-03-21",
    "subscriberCount": 21300000,
    "viewCount": 5701982926,
    "videoCount": 1853,
    "isVerified": true,
    "hasBusinessEmail": true,
    "avatarUrl": "https://yt3.googleusercontent.com/...",
    "bannerUrl": "https://yt3.googleusercontent.com/...",
    "keywords": ["MKBHD", "MarquesBrownlee", "Marques", "Brownlee"],
    "tabs": ["Home", "Videos", "Shorts", "Live", "Shows", "Playlists", "Posts", "Store"]
}
```

#### Comment (a reply)

```json
{
    "type": "comment",
    "id": "UgwbFVC25OjzrbY9iYB4AaABAg.AatakisKOuLAatdb_dHJlU",
    "text": "That is a great way of using these tools as a supportive study tool for students!",
    "author": {
        "name": "@TeachersTechHQ",
        "channelId": "UCM3mutT2jaaAIrqiMqom11g",
        "isVerified": false,
        "isChannelOwner": true,
        "url": "https://www.youtube.com/@TeachersTechHQ"
    },
    "likeCount": 1,
    "replyCount": 0,
    "replyLevel": 1,
    "parentId": "UgwbFVC25OjzrbY9iYB4AaABAg",
    "rootId": "UgwbFVC25OjzrbY9iYB4AaABAg",
    "publishedAt": "2026-09-18T09:41:02Z",
    "isEdited": false,
    "hasCreatorHeart": false,
    "isPinned": false,
    "videoId": "cIScTGWMrgg",
    "videoTitle": "AI Tools for Teachers: How Students Can Use AI to Learn, Not Just Get Answers?"
}
```

***

### Pricing

You pay only for results you receive - never for searches, filters, retries or items that turned out to be private or deleted.

| Result | Price per 1,000 |
| --- | --- |
| Video, Short or stream (full details) | **$1.50** |
| Channel (full profile with social links) | **$2.00** |
| Comment or reply (any level) | **$0.50** |
| Transcript (one video, one language) | **$2.00** |
| Community post | **$1.00** |
| Playlist details | **$1.00** |
| Chapters + AI summary add-on (per video) | **$1.00** |
| Shorts sound add-on (per Short) | **$0.50** |

Prices are for the Apify Free plan; paid Apify plans get lower prices automatically. **Search filters and date filters are free.** You can set a maximum cost per run in the run options - the Actor stops cleanly when it is reached.

### Free plan

On Apify's free plan a run uses up to 5 search terms or links and up to 20 results of each kind per search term, channel or playlist (20 comments per video). Every feature works, so you can try all of them before upgrading.

### Good to know

- **Transcripts** are returned in the languages each video actually has. YouTube does not offer machine-translated captions to automated tools, so a language the video does not have is skipped.
- **Chapters** are YouTube's own (creator or auto-generated). YouTube does not show them on every request; the Actor retries, and a video with no chapters returns an empty list.
- **Community post comments** have no exact time: YouTube only shows "3 days ago" for them, so they get `estimatedPublishedAt` (worked out from `publishedTimeText`) and an empty `publishedAt`. Video comments have exact times in `publishedAt`.
- **Community posts** have an `estimatedPublishedAt` worked out from YouTube's "3 weeks ago" (`publishedTimeText`): exact time for posts under a day old, the date only for older ones. YouTube shows no exact post time anywhere.
- **Poll results** (percentages) are only shown by YouTube after voting, so polls include the choices and total votes.
- **Channel emails** are behind YouTube's sign-in and captcha. The channel row tells you whether a business email is listed (`hasBusinessEmail`).
- **Private, removed and members-only** content is skipped and not charged.

### FAQ

**Do I need a YouTube account or API key?** No. Everything is public data, collected without logging in.

**Can I scrape a whole channel?** Yes - set Maximum videos (and Shorts / live streams) high enough. Use "Published after" to collect only recent uploads.

**How do I get only a channel's Shorts?** Paste the channel link with `/shorts` at the end, e.g. `https://www.youtube.com/@mkbhd/shorts`.

**Can I use my own YouTube search?** Yes - filter the results on youtube.com, copy the address and paste it as a link. Its filters are kept.

**How do I rebuild comment threads?** Group comment rows by `rootId`; each reply's `parentId` is the comment it answers and `replyLevel` is its depth. `replyCount` is YouTube's own number: every reply below that comment, at all levels (so a reply with 1 answer that itself has 4 answers shows 5).

**Can I export to Excel or CSV?** Yes - every table can be downloaded as JSON, CSV, Excel, XML or HTML, or read through the Apify API.

# Actor input Schema

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

Keywords to search on YouTube, one per row - exactly as you would type them in YouTube's search box. Use the search filters below to narrow the results.

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

One per row. Accepts video, Short and live links, channels (URL or @handle - add /videos, /shorts, /streams, /posts or /playlists to scrape only that tab), playlists, community posts, hashtag pages and YouTube search result links (their own filters are kept).

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

Regular videos to collect per search term, channel or playlist.

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

Shorts to collect per search term or channel.

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

Live and past live streams to collect per search term or channel.

## `maxSearchChannels` (type: `integer`):

Channels to collect for each search term (full channel details including social links).

## `maxSearchPlaylists` (type: `integer`):

Playlists to collect for each search term (playlist details only; add the playlist link above to also get its videos).

## `searchSortBy` (type: `string`):

YouTube's 'Prioritize' option.

## `searchUploadDate` (type: `string`):

Only videos uploaded within this period.

## `searchDuration` (type: `string`):

Video length (applies to regular videos).

## `searchFeatures` (type: `array`):

Only videos with all of the selected features. For live streams use 'Maximum live streams' above.

## `channelSortBy` (type: `string`):

Order of a channel's videos, Shorts and streams.

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

Only keep videos, Shorts, streams and posts published after this date - an exact date or a relative period like '7 days'. Free. Channel order is set to Latest when used.

## `includeChannelInfo` (type: `boolean`):

Extra charge per channel. Adds one row per channel: the channels you entered AND the channel of every collected video, so 100 videos from 100 different channels can add up to 100 channel rows. Each row has subscribers, total views, video count, country, join date, description, avatar, banner, verified badge and all social / website links. Each channel is collected and charged once per run.

## `maxChannelPosts` (type: `integer`):

Text, image, poll and video posts from the channel's Posts tab.

## `maxChannelPlaylists` (type: `integer`):

Playlists from the channel's Playlists tab (playlist details).

## `includeVideoExtras` (type: `boolean`):

Extra charge per video. Adds chapters (with start times), YouTube's AI-generated video summary where shown, the members-only flag and collaborating channels. Regular videos only.

## `includeShortsSound` (type: `boolean`):

Extra charge per Short. Adds the sound / music a Short uses (or 'Original sound').

## `includeTranscripts` (type: `boolean`):

Extra charge per video and language. Adds the video's captions (manual captions preferred over auto-generated). Only languages the video actually has are returned - YouTube does not offer translated captions to scrapers.

## `transcriptLanguages` (type: `array`):

Language codes in order of preference, e.g. en, es, de, hi, ar, pt, fr (up to 5; each language found is one transcript). Leave empty for the video's main language.

## `transcriptFormat` (type: `string`):

How transcripts appear in each video row.

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

Top-level comments to collect per video, Short or post. 0 = no comments.

## `commentsSortBy` (type: `string`):

YouTube's comment order.

## `maxReplyDepth` (type: `integer`):

How many levels of replies to collect: 0 = no replies, 1 = direct replies, up to 6 for replies to replies.

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

Replies to collect under each comment, at every level.

## `commentsNewerThan` (type: `string`):

Only keep comments published after this date (exact date or e.g. '7 days'). Sets the order to Newest first.

## `country` (type: `string`):

YouTube shows search results and availability for this country.

## Actor input object example

```json
{
  "searchQueries": [
    "ai tools for students"
  ],
  "startUrls": [
    "https://www.youtube.com/@MrBeast",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxResults": 10,
  "maxResultsShorts": 0,
  "maxResultStreams": 0,
  "maxSearchChannels": 0,
  "maxSearchPlaylists": 0,
  "searchSortBy": "relevance",
  "searchUploadDate": "",
  "searchDuration": "",
  "searchFeatures": [],
  "channelSortBy": "latest",
  "includeChannelInfo": false,
  "maxChannelPosts": 0,
  "maxChannelPlaylists": 0,
  "includeVideoExtras": false,
  "includeShortsSound": false,
  "includeTranscripts": false,
  "transcriptLanguages": [
    "en"
  ],
  "transcriptFormat": "text",
  "maxComments": 0,
  "commentsSortBy": "top",
  "maxReplyDepth": 1,
  "maxRepliesPerComment": 5,
  "country": "US"
}
```

# Actor output Schema

## `videos` (type: `string`):

No description

## `channels` (type: `string`):

No description

## `comments` (type: `string`):

No description

## `posts` (type: `string`):

No description

## `playlists` (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 = {
    "searchQueries": [
        "ai tools for students"
    ],
    "startUrls": [
        "https://www.youtube.com/@MrBeast",
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

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

# Run the Actor and wait for it to finish
run = client.actor("calm_builder/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 '{
  "searchQueries": [
    "ai tools for students"
  ],
  "startUrls": [
    "https://www.youtube.com/@MrBeast",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ]
}' |
apify call calm_builder/youtube-scraper --silent --output-dataset

```

## MCP server setup

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