# YouTube Scraper - Search, Videos, Channels & Comments (`trysmartapi/youtube-scraper`) Actor

Search, videos, channels & comments in one Actor. No Google API key, no daily quota - just $0.25 per 1,000 results.

- **URL**: https://apify.com/trysmartapi/youtube-scraper.md
- **Developed by:** [Smart API](https://apify.com/trysmartapi) (community)
- **Categories:** Videos, Social media
- **Stats:** 49 total users, 49 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

$0.25 / 1,000 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Scraper — Search, Videos, Channels & Comments

> **Search, videos, channels & comments in one Actor. No Google API key, no daily quota —
> just $0.25 per 1,000 results.**

Scrape **YouTube search results, video details, channel stats and comments** as clean,
structured data. Paste YouTube links or keywords — no Google API key, no daily quota.
One Actor covers seven common tasks: pick a task, fill one box, hit **Start**.

- ✅ **$0.25 per 1,000 results** — pay only for rows you actually get
- ✅ **No Google API key, no daily quota** — nothing to set up
- ✅ **Paste links, not IDs** — full `watch?v=`, `youtu.be/`, `/shorts/`, `@handle` and `/channel/UC…` URLs all work
- ✅ **Pagination handled for you** — just say how many results you want
- ✅ **Flat rows** that export straight to CSV, Excel, Google Sheets or JSON
- ✅ **Works from the UI and from the API** — same input either way

***

### What can it do?

| Task | What you give it | What you get back |
|---|---|---|
| 🔍 **Search videos** | Keywords | Matching videos with title, channel, publish date, thumbnail |
| 🔍 **Search channels** | Keywords | Matching channels with title, description, thumbnail |
| 🎬 **Video details** | Video URLs or IDs | Views, likes, comment count, duration, tags, category, captions |
| 📺 **Channel details** | Channel URLs, `@handles` or IDs | Subscribers, total views, video count, country, handle |
| 📺 **Channel videos** | Channel URLs, `@handles` or IDs | The channel's uploads, newest first |
| 💬 **Video comments** | Video URLs or IDs | Top-level comments + author, likes, date (replies optional) |
| 💬 **Comment replies** | Comment IDs | All replies to those comments |

***

### Quick start (UI)

1. Choose a task in **“What do you want to get?”**.
2. Fill in **only** the box that belongs to it — each box says which task it is for:
   - *Search keywords* → for the two search tasks
   - *Videos (URLs or IDs)* → for video details and video comments
   - *Channels (URLs, handles or IDs)* → for channel details and channel videos
   - *Comment IDs* → for comment replies
3. Optionally set **Max results per input**, a country, a date range or a sort order.
4. Click **Start**. Results appear on the **Storage → Dataset** tab, ready to export.

Every box comes pre-filled with a working example, so you can switch the task dropdown
and hit **Start** straight away to see what each one returns.

***

### Examples

#### Search for videos

```json
{
  "operation": "search_videos",
  "queries": ["coke studio", "lofi hip hop"],
  "order": "viewCount",
  "regionCode": "IN",
  "maxItems": 100
}
```

#### Get details for a few videos

```json
{
  "operation": "video_details",
  "videos": [
    "https://www.youtube.com/watch?v=4zTFzMPWGLs",
    "https://youtu.be/dQw4w9WgXcQ",
    "https://www.youtube.com/shorts/-2Wqk2ncV7c"
  ]
}
```

#### Get channel stats from a handle

```json
{
  "operation": "channel_details",
  "channels": ["https://www.youtube.com/@MrBeast", "@mkbhd"]
}
```

#### List a channel's newest uploads

```json
{
  "operation": "channel_videos",
  "channels": ["UCu59yAFE8fM0sVNTipR4edw"],
  "order": "date",
  "publishedAfter": "2025-01-01",
  "maxItems": 200
}
```

#### Scrape comments (with replies)

```json
{
  "operation": "comment_threads",
  "videos": ["https://www.youtube.com/watch?v=32mJgqhnbGY"],
  "commentOrder": "relevance",
  "includeReplies": true,
  "maxRepliesPerComment": 50,
  "maxItems": 500
}
```

***

### Output

Rows are flat and consistent, so CSV and Sheets exports just work.

**Videos (search / channel videos)**

```json
{
  "videoId": "5Eqb_-j3FDA",
  "title": "Pasoori | Coke Studio Season 14",
  "url": "https://www.youtube.com/watch?v=5Eqb_-j3FDA",
  "publishedAt": "2022-02-07T13:30:11Z",
  "channelTitle": "Coke Studio Pakistan",
  "channelId": "UCM1VesJtJ9vTXcMLLr_FfdQ",
  "channelUrl": "https://www.youtube.com/channel/UCM1VesJtJ9vTXcMLLr_FfdQ",
  "description": "Let's transcend boundaries…",
  "thumbnailUrl": "https://i.ytimg.com/vi/5Eqb_-j3FDA/hqdefault.jpg",
  "liveBroadcastContent": "none",
  "searchQuery": "coke studio"
}
```

**Video details** adds `viewCount`, `likeCount`, `commentCount`, `duration`,
`durationSeconds`, `tags`, `categoryId`, `topicCategories`, `definition`,
`hasCaptions`, `privacyStatus`, `madeForKids`, `defaultAudioLanguage`.

**Channel details**

```json
{
  "channelId": "UCFFbwnve3yF62-tVXkTyHqg",
  "title": "Zee Music Company",
  "handle": "@zeemusiccompany",
  "url": "https://www.youtube.com/@zeemusiccompany",
  "subscriberCount": 122000000,
  "viewCount": 89211450788,
  "videoCount": 16576,
  "publishedAt": "2014-03-12T11:59:25Z",
  "country": "IN",
  "uploadsPlaylistId": "UUFFbwnve3yF62-tVXkTyHqg"
}
```

**Comments**

```json
{
  "commentId": "UgwOSGaPuVONHxyrtxV4AaABAg",
  "text": "does he speak Kannada ?",
  "authorDisplayName": "@prashanthalex7702",
  "likeCount": 12,
  "publishedAt": "2025-03-18T23:26:33Z",
  "isReply": false,
  "parentId": null,
  "totalReplyCount": 1,
  "videoId": "32mJgqhnbGY",
  "videoUrl": "https://www.youtube.com/watch?v=32mJgqhnbGY",
  "authorChannelId": "UCWS904BG8MIrnbCMj8qiNfQ"
}
```

Replies come as extra rows with `isReply: true` and `parentId` set to the comment
they belong to.

Counts are real numbers (not strings), so you can sort and total them right away.
Need the untouched nested objects instead? Turn on **Raw output (advanced)**.

***

### Using it from the API

Run the Actor and get results in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/trysmartapi~youtube-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "operation": "search_videos",
    "queries": ["coke studio"],
    "maxItems": 50
  }'
```

Same thing in JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('trysmartapi/youtube-scraper').call({
    operation: 'comment_threads',
    videos: ['https://www.youtube.com/watch?v=32mJgqhnbGY'],
    maxItems: 200,
    includeReplies: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

And in Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("trysmartapi/youtube-scraper").call(run_input={
    "operation": "channel_details",
    "channels": ["@MrBeast", "@mkbhd"],
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

***

### Input reference

| Field | Type | Used by | Notes |
|---|---|---|---|
| `operation` | string | all | `search_videos`, `search_channels`, `video_details`, `channel_details`, `channel_videos`, `comment_threads`, `comment_replies` |
| `queries` | string\[] | search tasks | One keyword per entry; each is searched separately |
| `videos` | string\[] | `video_details`, `comment_threads` | Video URLs or 11-char IDs |
| `channels` | string\[] | `channel_details`, `channel_videos` | Channel URLs, `@handles` or `UC…` IDs |
| `commentIds` | string\[] | `comment_replies` | Comment IDs from a comments run |
| `maxItems` | integer | listing tasks | Cap **per keyword / video / channel**. Default `100` |
| `includeReplies` | boolean | `comment_threads` | Adds reply rows. Default `false` |
| `maxRepliesPerComment` | integer | `comment_threads` | Default `50` |
| `commentOrder` | string | `comment_threads` | `time` (newest) or `relevance` |
| `order` | string | search / channel videos | `relevance`, `date`, `viewCount`, `rating`, `title`. Use `date` on channels for full history |
| `videoDuration` | string | video listings | `any`, `short` (<4 m), `medium` (4–20 m), `long` (>20 m) |
| `regionCode` | string | listings | ISO country code, e.g. `US`, `IN`, `GB` |
| `videoCategoryId` | string | video listings | e.g. `10` Music, `20` Gaming, `24` Entertainment |
| `publishedAfter` / `publishedBefore` | string | listings | `YYYY-MM-DD` or full ISO date-time |
| `eventType` | string | `search_videos` | `any`, `live`, `upcoming`, `completed` |
| `rawOutput` | boolean | all | Return nested API objects instead of flat rows |
| `startToken` | string | listings | Resume a previous run (single input item only) |

***

### Notes & tips

- **`maxItems` is per input.** Three keywords with `maxItems: 100` returns up to 300 rows.
- **Resuming a run:** each run stores a `nextToken` per input in its **key-value store**
  under `OUTPUT`. Paste one into `startToken` to continue from the next page.
- **Video and channel details are batched** — asking for 200 videos costs a handful of
  requests, not 200.
- **Channel videos walks the full upload history.** YouTube's channel listing only exposes
  the newest ~15 uploads, so the Actor slices the request into one-year windows and pages
  through each, newest year first. Set `maxItems` as high as you need. Sorting by anything
  other than "Newest first" uses the plain listing instead and returns far fewer videos —
  use "Newest first" when you want depth.
- **Private, deleted or region-blocked** items are skipped and reported as run-log warnings.
- **`@handles` are resolved automatically** to channel IDs, which costs one extra lookup.
  Pass `UC…` IDs directly if you already have them.
- **Comment counts** on a video can be larger than what is fetchable — YouTube hides
  some comments and disables them entirely on some videos.

***

### Pricing

**$0.25 per 1,000 results** — charged per row written to the dataset, nothing else.
No monthly fee, no minimum, no charge for rows you don't receive.

| You scrape | You pay |
|---|---|
| 100 results | $0.03 |
| 1,000 results | $0.25 |
| 10,000 results | $2.50 |
| 100,000 results | $25.00 |

Both a comment and a video row count as one result. Use **Max results per input** to keep
any run inside a budget you choose.

***

### Legal

This Actor retrieves publicly available YouTube data only. It does not access private
data or bypass any login. You are responsible for using the collected data in line with
YouTube's terms and applicable law (including GDPR when handling personal data such as
comment author names).

# Actor input Schema

## `operation` (type: `string`):

Pick one task. Then fill in **only** the input box that belongs to it (each box below says which task it is for).

## `queries` (type: `array`):

Used by **Search videos** and **Search channels**. One keyword or phrase per line. Each line is searched separately.

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

Used by **Video details** and **Video comments**. Paste full YouTube links (`watch?v=`, `youtu.be/`, `/shorts/`, `/live/`) or plain 11-character video IDs — one per line.

## `channels` (type: `array`):

Used by **Channel details** and **Channel videos**. Accepts `https://www.youtube.com/@MrBeast`, `@MrBeast`, `https://www.youtube.com/channel/UC...` or a plain `UC...` ID — one per line. Handles are resolved automatically.

## `commentIds` (type: `array`):

Used by **Comment replies**. Paste the `commentId` values you got from a "Video comments" run — one per line. All replies to each comment are returned.

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

Stop after this many results **per keyword / per video / per channel**. Pagination is handled for you. Ignored for "Video details" and "Channel details" (those always return everything you asked for).

## `includeReplies` (type: `boolean`):

Only for **Video comments**. When on, replies are fetched for every comment and added as extra rows (`isReply: true`).

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

Only used when "Also fetch comment replies" is on.

## `commentOrder` (type: `string`):

Only for **Video comments**.

## `order` (type: `string`):

For **Search videos**, **Search channels** and **Channel videos**.

## `videoDuration` (type: `string`):

For **Search videos** and **Channel videos**.

## `regionCode` (type: `string`):

2-letter country code, e.g. `US`, `IN`, `GB`. Leave empty for the default region.

## `videoCategoryId` (type: `string`):

YouTube category ID, e.g. `10` = Music, `20` = Gaming, `24` = Entertainment, `25` = News.

## `publishedAfter` (type: `string`):

Only results published after this date. Format `YYYY-MM-DD` or full ISO date-time.

## `publishedBefore` (type: `string`):

Only results published before this date. Format `YYYY-MM-DD` or full ISO date-time.

## `eventType` (type: `string`):

Only for **Search videos**.

## `rawOutput` (type: `boolean`):

Off (default) gives clean, flat rows that export nicely to CSV/Excel. Turn on to get the untouched nested API objects instead.

## `startToken` (type: `string`):

Continue a previous run where it stopped. Paste a `nextToken` from that run's output. Only works with a single input item.

## Actor input object example

```json
{
  "operation": "search_videos",
  "queries": [
    "coke studio"
  ],
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "channels": [
    "https://www.youtube.com/@MrBeast"
  ],
  "commentIds": [
    "Ugzge340dBgB75hWBm54AaABAg"
  ],
  "maxItems": 100,
  "includeReplies": false,
  "maxRepliesPerComment": 50,
  "commentOrder": "time",
  "order": "relevance",
  "videoDuration": "any",
  "eventType": "any",
  "rawOutput": false
}
```

# 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 = {
    "operation": "search_videos",
    "queries": [
        "coke studio"
    ],
    "videos": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "channels": [
        "https://www.youtube.com/@MrBeast"
    ],
    "commentIds": [
        "Ugzge340dBgB75hWBm54AaABAg"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("trysmartapi/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 = {
    "operation": "search_videos",
    "queries": ["coke studio"],
    "videos": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "channels": ["https://www.youtube.com/@MrBeast"],
    "commentIds": ["Ugzge340dBgB75hWBm54AaABAg"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("trysmartapi/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 '{
  "operation": "search_videos",
  "queries": [
    "coke studio"
  ],
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "channels": [
    "https://www.youtube.com/@MrBeast"
  ],
  "commentIds": [
    "Ugzge340dBgB75hWBm54AaABAg"
  ],
  "maxItems": 100
}' |
apify call trysmartapi/youtube-scraper --silent --output-dataset

```

## MCP server setup

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