# YouTube Scraper: Videos, Channels, Shorts & Comments (`apisamurai/youtube-scraper`) Actor

Scrape YouTube videos, Shorts, channels, playlists and comments by search, channel, playlist or video link. Views, likes, tags, publish dates, exact limits, pay per row. No login, no API key.

- **URL**: https://apify.com/apisamurai/youtube-scraper.md
- **Developed by:** [API Samurai](https://apify.com/apisamurai) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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 Scraper: Videos, Channels, Shorts & Comments

Get YouTube videos, Shorts, live streams and comments as clean rows: from search results, channel tabs, playlists or single video links. Every video row has the title, channel, subscribers, views, duration, publish date, Short and live flags, description, hashtags and thumbnail. Turn on details for exact likes, comment count, tags, category, full description and the exact publish time. Turn on comments for comment text, author, likes, replies, pinned and hearted flags.

No login, no YouTube API key and no third-party services: the Actor reads YouTube's own web API the way a logged-out visitor's browser does.

### Use cases

- **Content research:** what ranks for a keyword, sorted by date or views, filtered by upload date and length.
- **Competitor and creator tracking:** the latest videos, Shorts or streams of any channel, with a "published after" cutoff for scheduled runs.
- **Influencer discovery:** channels and subscriber counts behind the videos that rank for your niche.
- **Audience and sentiment analysis:** top or newest comments with replies, likes and creator hearts.
- **Datasets for AI and analytics:** stable field names, numbers as numbers, dates as ISO strings, unknown values as `null`.

### Fair billing

- You pay only for real rows in your dataset: one event per video, one per comment, one extra per video whose details loaded.
- Limits are exact. Ask for 10 videos per source and you get 10, never 20 because a page had 20.
- Duplicates are free and left out: a video found by two sources is saved and charged once per run, same for comments.
- No start fee. A run that finds nothing costs nothing.
- If details fail to load for a video, you still get the row and the details event is not charged.
- When your run reaches the maximum cost you set, it stops cleanly and keeps what it saved.

### Input

| Field | What it does | Default |
|---|---|---|
| `searchQueries` | Search terms, one per line. Each is its own source. | |
| `searchType` | `videos`, `shorts`, `channels` or `playlists`. Channels and playlists are opened in search order and their videos are saved. | `videos` |
| `uploadDate` | `any`, `hour`, `today`, `week`, `month`, `year` | `any` |
| `sortBy` | `relevance`, `date`, `views`, `rating` | `relevance` |
| `duration` | `any`, `short` (under 4 min), `medium` (4 to 20 min), `long` (over 20 min) | `any` |
| `channels` | Handles (`@mkbhd`), channel links or IDs (`UC...`) | |
| `channelTabs` | `videos`, `shorts`, `streams`. Each channel tab is its own source. | `videos` |
| `playlists` | Playlist links or IDs | |
| `videoUrls` | Watch, youtu.be or Shorts links, or video IDs | |
| `maxResultsPerSource` | Exact number of videos per search term, channel tab or playlist | 50 |
| `publishedAfter` | Channel tabs: stop at videos older than this date (`2026-01-31`) or age (`7 days`) | |
| `includeDetails` | Open each video for exact likes, comment count, tags, category, full description, exact publish time | `false` |
| `includeComments` | Save comments as rows with `type: "comment"` | `false` |
| `maxCommentsPerVideo` | Exact number of comment rows per video, replies included | 100 |
| `commentsSort` | `top` or `newest` | `top` |
| `includeReplies` | Also save replies, right after their comment | `false` |
| `proxyConfiguration` | Apify Proxy by default; switches to residential by itself if YouTube refuses the IPs | Apify Proxy |

### Output

Example from a test run (one video with details and comments, shortened):

```json
{
  "type": "video",
  "id": "ESABTN4VtrA",
  "url": "https://www.youtube.com/watch?v=ESABTN4VtrA",
  "title": "iPhone Duo Review: First Generation Fun!",
  "channelId": "UCBJycsmduvYEL83R_U4JriQ",
  "channelName": "Marques Brownlee",
  "channelHandle": "@mkbhd",
  "channelUrl": "https://www.youtube.com/@mkbhd",
  "channelSubscribers": 21400000,
  "viewCount": 12768259,
  "likeCount": 201158,
  "commentCount": 15000,
  "durationSeconds": 1744,
  "isShort": false,
  "isLive": false,
  "publishedAt": "2026-10-21T12:00:52.000Z",
  "publishedAtIsApproximate": false,
  "description": "What it's actually like to use the first folding iPhone - Duo ...",
  "tags": ["iPhone Duo", "iPhone duo review"],
  "category": "Science & Technology",
  "hashtags": [],
  "thumbnailUrl": "https://i.ytimg.com/vi/ESABTN4VtrA/maxresdefault.jpg",
  "source": "video",
  "input": "https://www.youtube.com/watch?v=ESABTN4VtrA",
  "scrapedAt": "2026-10-28T06:13:20.430Z"
}
```

```json
{
  "type": "comment",
  "id": "UgxT_OQYl-63j1AxErV4AaABAg",
  "videoId": "ESABTN4VtrA",
  "videoUrl": "https://www.youtube.com/watch?v=ESABTN4VtrA",
  "text": "I work in an apple store. ...",
  "author": "@thathandheldguy",
  "authorChannelId": "UCsA3bY1G_77C_XToiBAC7-g",
  "likeCount": 36000,
  "replyCount": 736,
  "isReply": false,
  "parentId": null,
  "publishedAt": "2026-10-22T00:00:00.000Z",
  "publishedAtIsApproximate": true,
  "isPinned": false,
  "isHearted": false,
  "scrapedAt": "2026-10-28T06:13:20.757Z"
}
```

Without details, list pages show rounded numbers ("12M views") and ages ("6 days ago"). The Actor turns ages into a date and sets `publishedAtIsApproximate: true`. Comment likes and the video comment count are rounded by YouTube too ("36K", "15K"). `likeCount`, `commentCount`, `tags` and `category` are `null` unless details are on.

The `SUMMARY` record in the key-value store lists every source with its delivered videos, comments and the reason it stopped (limit reached, no more results, reached publishedAfter, three empty pages, repeated continuation token, cost limit reached, or the error).

### Pricing

$1 per 1,000 videos; $1 per 1,000 videos with details turned on (on top of the video price); $0.50 per 1,000 comments. Same price on every Apify plan. No start fee: a run that finds nothing costs nothing. Set a maximum cost per run and the Actor stops cleanly when it is reached.

### FAQ

**Do I need a YouTube API key or account?**
No. The Actor uses YouTube's public web API as a logged-out visitor. There is no Google quota to manage.

**How do the limits work?**
`maxResultsPerSource` counts saved videos per search term, channel tab or playlist, and the last page is trimmed to it. `maxCommentsPerVideo` counts comment rows per video, replies included. There are no hidden caps on top of your limits.

**Why did I get fewer results than my limit?**
The source ran out: the search, channel tab or playlist had no more videos, the `publishedAfter` date was reached, or the videos were already saved by another source in the same run (duplicates are left out). The `SUMMARY` record shows the stop reason per source. Removed or private videos are skipped and not charged.

**Can I run it on a schedule?**
Yes. Create a task with your channels and `publishedAfter` set to a relative age such as `7 days`, then schedule it weekly in Apify Console. Each run only pages until it reaches older videos.

**Is scraping YouTube legal?**
The Actor collects only public data that any logged-out visitor can see. How you store and use it, especially personal data such as commenter names, is your responsibility under laws like the GDPR and YouTube's terms. This is not legal advice; ask a lawyer for your case.

**What happens if YouTube blocks the proxy?**
Requests are retried with backoff on network errors and server errors. If YouTube answers with rate limits, a consent or bot check page, or empty data twice, the run moves to residential proxies by itself. One failing source never stops the others, and the run fails only if every source failed.

### Integrations

- **Apify API:** start runs and read the dataset over HTTP, in JSON, CSV or Excel.
- **Python and JavaScript clients:** `apify-client` for Python and Node.js.
- **Make, Zapier and n8n:** run the Actor and pass rows to Google Sheets, Airtable, Slack or your CRM.
- **MCP:** use the Actor from AI agents through the Apify MCP server.
- **Webhooks:** get notified when a run finishes.

# Actor input Schema

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

Words to search on YouTube, one per line. Each term is its own source with its own limit.

## `searchType` (type: `string`):

Videos or Shorts: the results themselves. Channels or Playlists: the matching channels or playlists are opened in search order and their videos are saved until the limit.

## `uploadDate` (type: `string`):

Search filter: only videos uploaded in this period.

## `sortBy` (type: `string`):

Order of search results.

## `duration` (type: `string`):

Search filter for videos: short (under 4 minutes), medium (4 to 20 minutes) or long (over 20 minutes).

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

Handles (@mkbhd), channel links (https://www.youtube.com/@mkbhd, /channel/UC...) or channel IDs (UC...). One per line.

## `channelTabs` (type: `array`):

Which tabs of each channel to scrape. Each channel tab is its own source with its own limit.

## `playlists` (type: `array`):

Playlist links (https://www.youtube.com/playlist?list=PL...) or playlist IDs. One per line.

## `videoUrls` (type: `array`):

Single videos or Shorts: watch links, youtu.be links, /shorts/ links or 11-character video IDs. One per line.

## `maxResultsPerSource` (type: `integer`):

Exact number of videos to save per search term, channel tab or playlist. The last page is trimmed, so you never get or pay for more.

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

Channel tabs only: stop once videos are older than this date (2026-01-31) or this long ago (7 days, 2 weeks). Channel pages show rounded ages such as "3 weeks ago", so videos near the boundary are judged on that rounded age unless details are on.

## `includeDetails` (type: `boolean`):

Adds the full description, exact like count, comment count, tags, category and exact publish time. Two extra requests per video, charged as an extra event only when they load.

## `includeComments` (type: `boolean`):

Save comments of every video in the results as separate rows (type "comment").

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

Exact number of comment rows per video, replies included.

## `commentsSort` (type: `string`):

Top comments (YouTube's ranking) or newest first.

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

Also save replies to comments. They count toward the comment limit.

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

Apify Proxy is the default. If YouTube starts refusing these IPs, the run switches to residential proxies by itself.

## Actor input object example

```json
{
  "searchQueries": [
    "lofi"
  ],
  "searchType": "videos",
  "uploadDate": "any",
  "sortBy": "relevance",
  "duration": "any",
  "channelTabs": [
    "videos"
  ],
  "maxResultsPerSource": 10,
  "includeDetails": false,
  "includeComments": false,
  "maxCommentsPerVideo": 100,
  "commentsSort": "top",
  "includeReplies": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `comments` (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 = {
    "searchQueries": [
        "lofi"
    ],
    "maxResultsPerSource": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("apisamurai/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": ["lofi"],
    "maxResultsPerSource": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("apisamurai/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": [
    "lofi"
  ],
  "maxResultsPerSource": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call apisamurai/youtube-scraper --silent --output-dataset

```

## MCP server setup

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