# YouTube Search Scraper: Videos & Top Comments (`vncntlabs/youtube-search-scraper`) Actor

Scrape YouTube search results for any keyword, country and language: rank, title, channel, views, publish date, duration and Shorts flag. Upload-date filter, rank and views changes, only-new videos, plus the top comments of any video. Commenter names off by default. Pay per video.

- **URL**: https://apify.com/vncntlabs/youtube-search-scraper.md
- **Developed by:** [VNCNT Labs](https://apify.com/vncntlabs) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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.

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 Search Scraper: Videos & Top Comments

Scrape **YouTube search results** for any keyword in **60+ countries** and any language, and get each video's **rank, title, channel, views, publish date, duration, Shorts and live flags, badges and thumbnail**, in the order viewers see them. Narrow it to videos **uploaded in the last hour, today, this week, month or year**, leave **Shorts** out, and add the **top comments** of any video (text, likes, reply count, date). Schedule it with a monitor name and every video also gets its **previous rank, rank change and views gained**, or switch on **only-new videos** to be told about new uploads for a topic.

You pay **per video delivered** ($0.50 per 1,000) plus a small fee per page of 20 results. No YouTube API key, no quota, no browser to maintain.

Built for:

- **Creators and video SEO teams**: who ranks for your topics, how many views they have, how old they are.
- **Marketers and researchers**: what people say under the top videos of a topic.
- **Agencies**: rank and views tracking for your channels and competitors, with daily changes.
- **AI agents**: video search on demand through the Apify API or MCP.

### What you get

| Row (`type`) | What's in it | Charged |
|---|---|---|
| `video` | `keyword`, `rank` (position among the videos delivered), `absoluteRank` (position in all results incl. playlists/channels), `videoId`, `title`, `channelName`, `channelId`, `channelUrl`, `views`, `publishedAgo` ("2 weeks ago"), `publishedAt` (estimated from it), `duration`, `durationSeconds`, `isShorts`, `isLive`, `isMovie`, `badges`, `description` (snippet), `thumbnailUrl`, `url`; with a monitor: `isNew`, `previousRank`, `rankChange` (+3 = moved up 3), `previousViews`, `viewsGained` | `video` |
| `keyword` | one per keyword: `status`, `resultsReturned`, `searchPagesCharged`, `videosDelivered`, `shortsSkipped`, `outsideUploadWindow`, `alreadySeen`, `averageViews`, `topChannels`, `youtubeUrl`, `notes` | `search-page` per page of 20 results returned |
| `comment` | `videoId`, `videoTitle`, `position`, `text`, `likes`, `replyCount`, `publishedAgo`, `publishedAt`, `url`; `authorName`, `authorUrl`, `authorThumbnail` only if you turn on commenter names | `comment` |
| `video-comments` | one per video whose comments you asked for: `status` (`ok`, `no_comments`, `not_found`), `commentsCount` (on the video), `commentsDelivered`, `topCommentLikes`, `source` (`input` or `top-video`) | `video-comments` (not when the video is not found) |
| `playlist`, `channel` | only with **Include playlists and channels**: title, URL, channel, videos count | free |

### Input examples

The top 100 videos for two keywords in the United States:

```json
{ "keywords": ["canva tutorial", "figma tutorial"], "maxVideosPerKeyword": 100 }
```

New uploads this week, no Shorts, with the top 50 comments of the first 3 videos:

```json
{ "keywords": ["ai news"], "uploadedWithin": "week", "excludeShorts": true, "commentsForTopVideos": 3, "maxCommentsPerVideo": 50 }
```

Top comments of specific videos:

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

**Tips**

- **How deep YouTube goes (measured, Oct 2026):** YouTube stops a search after a few hundred results. A popular keyword ("canva tutorial") returned **385 results (346 unique videos)** when we asked for 700; niche keywords return fewer. You can ask for up to 700 videos per keyword; the keyword row says how many YouTube returned. You are charged only for the pages YouTube actually returned.
- **Comments:** up to **700 comments** per video (measured: 700 of 700 on a popular video), in YouTube's top-comments order, without replies. Videos with comments turned off return `status: no_comments`.
- **Upload date, not sort:** YouTube no longer applies sort-by-date or sort-by-views to search results, so this Actor offers YouTube's **upload-date filter** instead. YouTube sometimes mixes a few older videos into filtered results; they are dropped (`outsideUploadWindow`) and not charged as videos.
- **Countries and languages:** pick a country; its main language is used unless you set one (`en`, `de`, `pt-BR`...). Results for **mobile** can be requested too.
- **Monitor name** keeps history per keyword, country, language, device and upload window in your Apify account (key-value store `youtube-search-monitor`). **Only new videos** returns just the videos not seen in earlier runs; the first run is the baseline.
- `publishedAt` is an estimate computed from YouTube's relative date ("2 years ago"); use `publishedAgo` for the exact text YouTube showed.
- Runs usually take **under a minute** (the data provider's standard queue). Views change constantly; `scrapedAt` tells you when each row was read.

### Output example (one video, one comment)

```json
{
  "type": "video", "keyword": "canva tutorial", "rank": 1, "absoluteRank": 1, "videoId": "jzWxBuvwuwQ",
  "title": "MASTER CANVA IN 15 MINUTES! Canva Tutorial For Beginners", "channelName": "Aurelius Tjin",
  "views": 2481540, "publishedAgo": "2 years ago", "duration": "16:22", "durationSeconds": 982,
  "isShorts": false, "badges": ["4K", "CC"], "url": "https://www.youtube.com/watch?v=jzWxBuvwuwQ",
  "chargedEvents": ["video"]
}
```

```json
{
  "type": "comment", "videoId": "dQw4w9WgXcQ", "position": 1,
  "text": "Is everyone going to ignore the fact that Rick Astley looks like a twelve year old boy but has a uniquely deep voice?",
  "likes": 291000, "replyCount": 681, "publishedAgo": "6 years ago", "chargedEvents": ["comment"]
}
```

The dataset has four views: **Overview**, **Videos (all fields)**, **Comments** and **Keywords and videos**. Export to CSV, Excel or JSON, or connect it to Google Sheets, Slack, Zapier or Make through Apify integrations.

### Pricing (pay per event)

| Event | When it is charged |
|---|---|
| Actor start | once per run |
| `video` | one video delivered from a keyword search |
| `search-page` | one page of up to 20 search results YouTube returned for a keyword (100 videos = about 6 pages). Also charged when those results are already seen, Shorts you excluded or outside the upload window, because YouTube is still searched |
| `video-comments` | one video whose comments are fetched, also when it has few or none |
| `comment` | one comment delivered |

You are not charged for:

- videos already seen in only-new mode, Shorts you excluded, older videos outside the upload window (beyond their results page);
- videos that don't exist or are private (`not_found`), failed requests (the run says which inputs failed), invalid or duplicate inputs, keyword rows, playlists and channels;
- a video that is both in your list and among the top videos of a search: fetched and charged once;
- anything beyond your run's maximum charge. The run stops cleanly and lists what it didn't process.

**Apify free plan:** 3 keywords with up to 50 videos each, and comments for 5 videos (up to 100 each) per run. Any paid Apify plan unlocks up to 50 keywords, 700 videos per keyword, 200 videos with comments and 700 comments per video.

### Privacy

Commenter names, channel links and avatars are personal data. They are **left out by default**; turn on **Include commenter names** only if you have a lawful reason to process them (for example, replying to your own audience). Comment texts belong to their authors. Monitor history stores video IDs, ranks and views in your own Apify account; delete the key-value store to reset it.

### Use from AI agents (MCP)

AI assistants such as Claude, ChatGPT and Cursor can run this Actor through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp) (`https://mcp.apify.com`). The agent can look up the Actor, read its input schema, run it and read the results. Runs use your own Apify account and are charged at the prices on this page.

- **Actor name:** `vncntlabs/youtube-search-scraper`
- **Server URL with only this tool:** `https://mcp.apify.com?tools=vncntlabs/youtube-search-scraper`. The default `https://mcp.apify.com` also works.
- **Claude** (desktop app or claude.ai): Settings > Connectors > Add custom connector, paste the server URL, then sign in to Apify.
- **ChatGPT:** turn on Developer mode, then Settings > Apps & Connectors > Create, paste the server URL and choose OAuth.
- **Cursor:** add the server to `mcp.json`:

```json
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=vncntlabs/youtube-search-scraper" } } }
```

Example prompt: *"Use the Apify Actor vncntlabs/youtube-search-scraper to get the top 50 videos for "home workout" uploaded this month without Shorts, and summarise which channels dominate and their average views."*

To cap the cost of an agent's run, it can pass `maxTotalChargeUsd` in the run options.

### FAQ

**Where does the data come from?** From DataForSEO's licensed SERP API, which reads the public YouTube search results and video pages for the country and language you choose. The Actor does not log in anywhere and needs no YouTube API key.

**Why fewer videos than I asked for?** YouTube itself ends a search after a few hundred results (385 for a popular keyword in our test), and playlists, channels, duplicates, Shorts (if excluded) and videos outside the upload window are not counted as videos. The keyword row shows `resultsReturned`.

**Can I get all comments or the replies?** No: you get up to 700 top comments per video, without replies. This is a search tool with top comments, not a full comment downloader.

**Can I sort by upload date or views?** YouTube no longer honours those sort options on search results. Use **Uploaded within** to get recent videos, and sort the dataset by `views` or `publishedAt` yourself.

**Is this an official YouTube API?** No. This Actor uses DataForSEO's licensed API and is not affiliated with or endorsed by YouTube or Google. YouTube is a trademark of Google LLC.

# Actor input Schema

## `keywords` (type: `array`):

One per line, e.g. <code>canva tutorial</code>. Each keyword returns the videos in YouTube's search order (up to 50 keywords).

## `maxVideosPerKeyword` (type: `integer`):

Up to 700. YouTube itself usually stops after a few hundred results per search (about 350-400 for a popular keyword), fewer for niche keywords.

## `videos` (type: `array`):

Optional: video links (<code>youtube.com/watch?v=...</code>, <code>youtu.be/...</code>, Shorts) or 11-character IDs. Each gets its top comments (up to 200 videos).

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

Which country's YouTube results to get.

## `language` (type: `string`):

Language code like <code>en</code>, <code>de</code>, <code>pt-BR</code>. Empty = the country's main language.

## `device` (type: `string`):

Results as seen on desktop or mobile.

## `uploadedWithin` (type: `string`):

YouTube's upload-date filter. Videos YouTube mixes in from outside the window are dropped and not charged. (YouTube no longer supports sorting search results by date or views, so a filter is offered instead.)

## `excludeShorts` (type: `boolean`):

Leave out Shorts (they are not charged; the results page they came on still is).

## `includePlaylistsAndChannels` (type: `boolean`):

Also add the playlists and channels in the results as rows (free).

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

Top comments per video, up to 700 (YouTube's top-comments order). Default 100 when you add videos, else 0.

## `commentsForTopVideos` (type: `integer`):

Also get the top comments of the first N videos of every keyword search.

## `includeCommenterNames` (type: `boolean`):

Off: comments come without names, channel links or avatars (they are personal data). Turn on only if you have a lawful reason to process them.

## `onlyNewVideos` (type: `boolean`):

For scheduled runs: returns only videos not seen in earlier runs for the same keyword. The first run returns the current results as a baseline. Results pages are still charged.

## `monitorId` (type: `string`):

Optional. With a monitor name, every video also gets its previous rank and views and the change since the last run. History is kept in your Apify account (key-value store 'youtube-search-monitor').

## Actor input object example

```json
{
  "keywords": [
    "canva tutorial"
  ],
  "maxVideosPerKeyword": 50,
  "country": "United States",
  "device": "desktop",
  "uploadedWithin": "any",
  "excludeShorts": false,
  "includePlaylistsAndChannels": false,
  "commentsForTopVideos": 0,
  "includeCommenterNames": false,
  "onlyNewVideos": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

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

No description

## `keywords` (type: `string`):

No description

## `all` (type: `string`):

No description

## `summary` (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 = {
    "keywords": [
        "canva tutorial"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vncntlabs/youtube-search-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 = { "keywords": ["canva tutorial"] }

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

```

## MCP server setup

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