# YouTube Comments Scraper: Comments, Replies & Likes (`santiagomv/youtube-comments`) Actor

Scrape comments and replies from YouTube videos, Shorts, playlists and channels: text, author, likes, reply count, creator hearts and date. Sort by top or newest, set a limit per video. No API key or login. $0.50 per 1,000 comments.

- **URL**: https://apify.com/santiagomv/youtube-comments.md
- **Developed by:** [Santiago Marcos](https://apify.com/santiagomv) (community)
- **Categories:** Social media, Videos, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 comments

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 Comments Scraper: comments, replies and likes

Scrape the comments of any **YouTube video, Short or live replay**, or of the videos in a **playlist or channel**. Paste links and get one row per comment with:

- the **comment text**, its **link** and its **ID**,
- the **author**: name, channel ID and URL, avatar, verified badge, and whether it's the video's own creator,
- **likes**, **reply count** and whether the **creator hearted** it,
- when it was posted (YouTube's "3 weeks ago" plus an approximate date) and whether it was **edited**,
- optionally the **replies**, as their own rows linked to the parent comment.

No YouTube API key, no Google account, no browser, no quota. The actor's event fee applies only to comments you get.

### Why this one

- **$0.50 per 1,000 comments**, proxies included.
- **Top or newest.** Take YouTube's top comments, or sort newest first to track what people are saying right now.
- **Replies when you want them.** Off by default to keep runs cheap; turn them on and set a cap per comment.
- **A limit per video**, so 50 videos × 200 comments is one run with a predictable cost.
- **No charge for failures.** Videos with comments turned off, private or removed videos and invalid links are listed in `FAILURES` and aren't charged a comment fee.
- **Every link format.** `watch?v=`, `youtu.be/`, `/shorts/`, `/embed/`, `/live/`, `music.youtube.com`, or the bare 11-character ID.
- **Playlists and channels.** Paste a playlist or channel link (`@handle` or `/channel/UC…`) and get comments from its videos, with hard caps on videos and pages so a big channel can't run away with your budget.

### What you can use it for

- **Sentiment and feedback analysis**: what viewers think of a product launch, a trailer, a review or an ad.
- **Audience research**: questions, pain points and language your audience uses, ready for an LLM or a spreadsheet.
- **Content ideas**: find the questions commenters keep asking under your or your competitors' videos.
- **Brand and community monitoring**: sort by newest and run on a schedule to catch new comments.
- **Giveaways**: export every comment on a video to pick a winner.
- **AI datasets**: comment threads for classification, toxicity or topic models.

### Input

| Field | Example | Notes |
|---|---|---|
| Videos | `https://www.youtube.com/watch?v=aircAruvnKk` | URLs or IDs, one per line. Duplicates are removed. |
| Playlists and channels | `https://www.youtube.com/playlist?list=UU_x5XG1OV2P6uZZ5FSM9Ttw` | Playlist, `@handle` or `/channel/UC…` URLs. See below. |
| Max videos per run | `100` | Unique videos in total, from both fields. Up to 10,000. |
| Max playlist/channel pages | `10` | YouTube listing pages read in total. Up to 100. |
| Max comments per video | `100` | Top-level comments. `0` = all. |
| Sort by | `top` / `newest` | Same as the YouTube menu. |
| Include replies | off | Replies become extra rows with `isReply: true`. |
| Max replies per comment | `10` | `0` = all. |
| Videos in parallel | `3` | Up to 10. |

Fill in Videos, Playlists and channels, or both. If you paste more than 100 video links, raise **Max videos per run**.

#### Playlists and channels

- **Playlists**: `youtube.com/playlist?list=…` links. A `watch?v=…&list=…` link in **Videos** is just that one video; put it in **Playlists and channels** to get the whole playlist.
- **Channels**: `youtube.com/@handle` (or `/@handle/videos`) and `youtube.com/channel/UC…` links, using the channel's **Videos** tab only (no Shorts, live or podcast tabs). Example: `https://www.youtube.com/@GoogleDevelopers`. A handle is looked up once per run, with up to 4 tries; looking it up is free and doesn't use up **Max playlist/channel pages**. If YouTube won't resolve a handle, it shows up in `FAILURES` and the rest of the run carries on; paste the `/channel/UC…` link instead. Old `/c/` and `/user/` links aren't supported.
- **Order and duplicates**: videos you pasted come first, then each playlist or channel in the order you listed them. A video found twice is scraped once.
- **Caps**: expansion stops at **Max videos per run** or **Max playlist/channel pages**, whichever comes first. A playlist page holds up to about 100 videos and a channel page about 30, so with the defaults you get up to 100 videos. It reads what YouTube lists; it doesn't promise every video of a large channel or a particular order.
- **Report**: `SOURCE_EXPANSION` in the key-value store shows, for each playlist or channel, the pages read, videos added, whether a cap stopped it, and any error or notice from YouTube. Playlists or channels that fail are also listed in `FAILURES`.

### Output

```json
{
  "videoId": "aircAruvnKk",
  "videoUrl": "https://www.youtube.com/watch?v=aircAruvnKk",
  "videoTitle": "But what is a neural network? | Deep learning chapter 1",
  "commentId": "Ugwedfi--9yZVC0eefl4AaABAg",
  "commentUrl": "https://www.youtube.com/watch?v=aircAruvnKk&lc=Ugwedfi--9yZVC0eefl4AaABAg",
  "text": "I study mathematics, physics and architecture. By definition this man is an ORACLE ...",
  "authorName": "@kummer45",
  "authorChannelId": "UCqArZkt3NAOU0tcgIi6xmFQ",
  "authorChannelUrl": "https://www.youtube.com/channel/UCqArZkt3NAOU0tcgIi6xmFQ",
  "authorAvatar": "https://yt3.ggpht.com/ytc/...=s88-c-k-c0x00ffffff-no-rj",
  "authorIsVerified": false,
  "authorIsChannelOwner": false,
  "likeCount": 13000,
  "replyCount": 173,
  "isHeartedByCreator": false,
  "isEdited": true,
  "publishedTimeText": "7 years ago",
  "publishedAtApprox": "2019-10-22T17:05:39.085Z",
  "isReply": false,
  "parentCommentId": null,
  "scrapedAt": "2026-10-22T11:05:39.085Z"
}
```

`likeCount` is what YouTube shows, so large numbers are rounded (`13K` → `13000`). `publishedAtApprox` is worked out from the relative time, so it's only as precise as that text: roughly the right day for recent comments, and only the month or year for old ones.

### Use it from code

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("santiagomv/youtube-comments").call(run_input={
    "videos": ["https://www.youtube.com/watch?v=aircAruvnKk"],
    "maxComments": 200,
    "sortBy": "newest",
})
for c in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(c["likeCount"], c["authorName"], c["text"][:80])
```

For a playlist or channel, pass `"sources": ["https://www.youtube.com/@GoogleDevelopers"]` plus `"maxVideos"` and a low `"maxComments"` to keep the run small.

More examples (Python, Node.js, cURL, n8n) are in the [code examples repository](https://github.com/SantiagoMV42/linkedin-jobs-scraper), including a [playlist and channel tutorial](https://github.com/SantiagoMV42/linkedin-jobs-scraper/tree/main/youtube).

### Which YouTube actor do I need?

- **Comments and replies**: this actor.
- **Just the video list** (URLs, titles, views, durations, approximate upload dates): [YouTube Channel Videos](https://apify.com/santiagomv/youtube-channel-videos). It reads the channel's Videos tab only, and views and dates are rounded or approximate as YouTube lists them.
- **What's said in the videos**: [YouTube Transcripts](https://apify.com/santiagomv/youtube-transcripts), for videos that have captions available.

All three accept channel and playlist links directly.

### Pricing

**$0.50 per 1,000 comments** ($0.0005 each), charged as an actor event for each comment returned; replies cost the same. Listing the videos of a playlist or channel and looking up `@handles` aren't charged as events, and neither are failed videos, failed playlists or channels and invalid links. Your run's maximum cost limit is always respected: the run stops when it's reached.

### FAQ

**Can it get every comment on a huge video?** Set Max comments to `0` and it pages through everything YouTube serves. Very large videos can have millions of comments, so set a run cost limit.

**Why is the comment count lower than the number YouTube shows?** YouTube's counter includes replies and comments it hides (held for review, removed spam). Turn on replies to get closer.

**Why is an old comment first when sorting by newest?** That is the pinned comment; YouTube always shows it first.

**Exact timestamps?** YouTube shows only relative times to logged-out visitors, so you get that text and an approximate date.

**Channels and playlists?** Yes, with limits: playlist links and channel links (`@handle` or `/channel/UC…`, Videos tab only), capped by Max videos per run and Max playlist/channel pages. Comments add up fast across a channel: 100 videos × 100 comments is 10,000 comments, or $5. `/c/` and `/user/` links aren't supported; open an issue if you need them.

**Do I need a YouTube API key or proxies?** No.

**Is this allowed?** Read this before using it. This actor collects publicly visible comments without logging in. Automated access may be against YouTube's Terms of Service, and YouTube may block or rate-limit the IP addresses or accounts involved. Comments are personal data of their authors: you are responsible for how you use this actor and the data, including privacy laws (such as GDPR), copyright and YouTube's terms.

This actor is not affiliated with, endorsed by or sponsored by YouTube or Google LLC. YouTube is a trademark of Google LLC.

# Actor input Schema

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

YouTube video URLs or 11-character video IDs, one per line. Watch, youtu.be, Shorts, embed, live and music.youtube.com links all work. A watch link that also has a list= parameter counts as that one video; put the playlist in Playlists and channels to get all of it.

## `sources` (type: `array`):

Playlist URLs (youtube.com/playlist?list=…) or channel URLs (youtube.com/@handle or youtube.com/channel/UC…), one per line. Channels use their Videos tab only (no Shorts or live tabs). /c/ and /user/ URLs aren't supported. Videos from here come after the Videos above, duplicates removed. Listing videos is free; you pay only for comments saved.

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

Total unique videos to scrape in this run, counting Videos first and then videos found in Playlists and channels. Raise it if you paste more than 100 video links.

## `maxSourcePages` (type: `integer`):

Total YouTube listing pages to read across all playlists and channels in this run. A playlist page holds up to about 100 videos, a channel page about 30. Expansion stops at this limit or at Max videos, whichever comes first.

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

Top-level comments to save per video. 0 = all of them (big videos can have millions). Replies don't count toward this limit.

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

Top comments (YouTube's default ranking) or newest first. Use newest to monitor fresh comments.

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

Also save replies to each comment, as separate rows with isReply = true and parentCommentId. Replies are charged like comments.

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

Only used with Include replies. 0 = all replies.

## `maxConcurrency` (type: `integer`):

How many videos to scrape at the same time.

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

Apify Proxy is used by default and included in the price. Change it only if you know you need to.

## Actor input object example

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=aircAruvnKk"
  ],
  "maxVideos": 100,
  "maxSourcePages": 10,
  "maxComments": 100,
  "sortBy": "top",
  "includeReplies": false,
  "maxRepliesPerComment": 10,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All comments and replies saved in this run, as a table.

## `failures` (type: `string`):

Videos with comments turned off, private or removed videos, and invalid inputs. These are not charged.

# 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 = {
    "videos": [
        "https://www.youtube.com/watch?v=aircAruvnKk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("santiagomv/youtube-comments").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 = { "videos": ["https://www.youtube.com/watch?v=aircAruvnKk"] }

# Run the Actor and wait for it to finish
run = client.actor("santiagomv/youtube-comments").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 '{
  "videos": [
    "https://www.youtube.com/watch?v=aircAruvnKk"
  ]
}' |
apify call santiagomv/youtube-comments --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,santiagomv/youtube-comments"
        }
    }
}
```

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/JwPA5o0CJAHxPoBGA/builds/ukWhmbIxv7UxC4QI4/openapi.json
