# YouTube Comments Scraper (`tidyharvest/youtube-comments-scraper`) Actor

Export comments and replies from any public YouTube video or Short: text, author, likes, dates, pinned and hearted flags, date and keyword filters. Built to beat Apify's YouTube Comments Scraper: same data, $0.22 per 1,000 vs $2.00 ($0.16 vs $0.90 on higher plans).

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

## Pricing

from $0.16 / 1,000 comment scrapeds

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 Comments Scraper

Export **YouTube comments** from any public video or Short: comment text, author, channel link, likes, reply counts,
dates, pinned and creator-hearted flags, plus optional **replies**. Paste video links and get a clean table back,
**$0.22 per 1,000 comments** (less on paid plans), no start fee. No YouTube API key, no account, no quota.

### What you can do with it

- **Audience research:** read what viewers actually say about a product, a launch, a competitor or a creator.
- **Sentiment analysis and AI training data:** clean comment text with likes and dates, ready for NLP pipelines.
- **Influencer and brand monitoring:** track reactions on sponsored videos, spot pinned and creator-hearted comments.
- **Lead and community discovery:** find the most engaged commenters and their channel links.
- **Content ideas:** mine questions and requests from the comments on top videos in your niche.

### Input

| Field | What it does |
|---|---|
| `videos` | Video ids, watch URLs, `youtu.be` links or Shorts URLs, one per line. |
| `sort` | `top` (YouTube's Top comments) or `newest`. |
| `maxCommentsPerVideo` | Stop each video after this many comments (default 100). |
| `includeReplies` | Also expand reply threads (off by default). |
| `maxRepliesPerComment` | Replies per thread when replies are on (default 10). |
| `oldestCommentDate` | Only comments newer than a date (`2026-09-01`) or an age (`2 weeks`, `3 months`). Older ones are skipped and free. Returns newest first. |
| `keywords` | Keep only comments containing one of these words. Filtered-out comments are free. |
| `maxItems` | Hard cap for the whole run (default 100), which also caps your cost. |

Example:

```json
{
  "videos": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ", "https://youtu.be/jNQXAC9IVRw"],
  "sort": "newest",
  "maxCommentsPerVideo": 500,
  "includeReplies": true,
  "maxRepliesPerComment": 5,
  "oldestCommentDate": "30 days",
  "maxItems": 1000
}
```

### Output

One item per comment (replies follow their parent comment):

```json
{
  "commentId": "UgyEnXfdC-umwvTt8JF4AaABAg",
  "videoId": "dQw4w9WgXcQ",
  "videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "videoChannelName": "Rick Astley",
  "videoChannelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "text": "Gonna flag this for nudity so I can rick roll the YouTube staff",
  "authorName": "@Oatman69",
  "authorChannelId": "UCWf34D_s8K_m2vwBISIDWtg",
  "authorChannelUrl": "https://www.youtube.com/channel/UCWf34D_s8K_m2vwBISIDWtg",
  "authorHandle": "@Oatman69",
  "authorAvatarUrl": "https://yt3.ggpht.com/...",
  "authorIsVerified": false,
  "authorIsChannelOwner": false,
  "authorIsArtist": false,
  "likeCount": 568000,
  "replyCount": 714,
  "publishedTimeText": "6 years ago",
  "publishedDateApprox": "2020-10-12",
  "isEdited": false,
  "isPinned": false,
  "isHearted": false,
  "isReply": false,
  "parentCommentId": null,
  "commentUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=UgyEnXfdC-umwvTt8JF4AaABAg"
}
```

| Field | Meaning |
|---|---|
| `text` | Full comment text. |
| `authorName`, `authorHandle`, `authorChannelId`, `authorChannelUrl` | Who wrote it. |
| `authorIsVerified`, `authorIsChannelOwner`, `authorIsArtist` | Badges. `authorIsChannelOwner` = the video's creator. |
| `likeCount` | Likes as a number (YouTube's "1.2K" becomes 1200, so large counts are rounded). |
| `replyCount` | Replies on a top-level comment (0 for replies). |
| `publishedTimeText`, `publishedDateApprox` | YouTube's relative time ("3 weeks ago") and the approximate date it implies. |
| `isPinned`, `isHearted`, `isEdited` | Pinned by the creator, hearted by the creator, edited. |
| `isReply`, `parentCommentId` | Reply flag and the top-level comment it answers. |
| `commentUrl` | Direct link that opens the video at this comment. |

Video details (title, channel, views, length, subscriber count, total comment count, whether comments are off) for
every video are saved once in the run's `SUMMARY` record in the key-value store, free of charge.

### How to use

1. Paste one or more YouTube video links into **Videos**.
2. Pick **Top** or **Newest**, set how many comments you want, and turn on **Include replies** if you need them.
3. Run it and download the results as JSON, CSV, Excel or via the API.

### Pricing

Pay per result: **$0.22 per 1,000 comments** on the Free plan, down to $0.16 on higher plans (`comment-scraped`), replies included, no start fee. The keyword filter and your caps
apply before you are charged, and the run stops when your spending limit is reached.

| Apify plan tier | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|
| per 1,000 comments | $0.22 | $0.18 | $0.17 | $0.16 | $0.16 | $0.16 |

### Compared with Apify's YouTube Comments Scraper (`streamers/youtube-comments-scraper`)

Measured 2026-10-19 on 12 videos from 12 niches (music, tech, news, gaming, Shorts, live replays, several languages), 300 top comments each:

| | This actor | streamers/youtube-comments-scraper |
|---|---|---|
| Price per 1,000 comments (Free / Gold plan) | **$0.22 / $0.16** | $2.00 / $0.90 |
| Cost of the 12-video run (Free plan prices) | **about $0.58** | about $5.46 |
| Comments returned on the 12 videos | 2,659 | 2,729 (it returns replies by default, 63% of its rows) |
| Run time, 12 videos | **about 2 min** | about 2.8 min |
| Pinned flag, channel link, avatar, badges, approximate date, direct comment link | **yes** | no |
| Date filter, keyword filter | yes, yes (free for filtered-out comments) | date filter only |
| Replies | opt-in (`includeReplies`, up to N per comment) | always on |

Where they still win: replies come with every run without a setting, and the total comment count sits on every row.
Our `SUMMARY` record has the total count per video.

### Limits and notes

- Public comments only, as a logged-out visitor sees them. Members-only, private, age-restricted or removed videos
  are not supported.
- Videos with comments turned off are listed in the run's `SUMMARY` and skipped; the run still succeeds if other
  videos returned comments. A run where no video returns any comment fails with a clear message.
- YouTube gives relative dates ("2 months ago"), so `publishedDateApprox` is an estimate: precise to the day for
  recent comments, to about a month for older ones.
- Like counts above 1,000 are rounded the way YouTube shows them ("1.2K").
- The `top` order is YouTube's own ranking and can differ slightly between runs.
- Measured 2026-10-19: 12 videos x 300 top comments (2,659 comments) in about 2 minutes. Replies need extra requests.
  Very large videos take longer; use `maxCommentsPerVideo` to bound runs.
- With several videos, rows from different videos arrive interleaved; every row carries its `videoId`.
- The actor never signs in. If YouTube refuses public access, the run stops and reports it.

This actor is not affiliated with, endorsed by, or sponsored by YouTube or Google.

# Actor input Schema

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

One per line: a video id (`dQw4w9WgXcQ`), a watch URL, a `youtu.be` link or a Shorts URL.

## `sort` (type: `string`):

`top` = YouTube's Top comments (most engaged first). `newest` = most recent first.

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

Stop each video after this many comments (replies count too).

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

Also expand reply threads. Replies are returned right after their parent with `isReply: true` and `parentCommentId`.

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

Only used with Include replies. 0 = none.

## `oldestCommentDate` (type: `string`):

A date (`2026-09-01`) or an age (`2 weeks`, `30 days`, `3 months`). Older comments are skipped and not charged. Switches the order to newest first. YouTube only shows relative times, so the cut is exact to the day for recent comments and within about a month for old ones.

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

Keep a comment only if its text contains one of these (case-insensitive). Empty = all comments. Filtered-out comments are not charged.

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

Hard cap on results for the whole run (also caps your cost).

## Actor input object example

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "sort": "top",
  "maxCommentsPerVideo": 100,
  "includeReplies": false,
  "maxRepliesPerComment": 10,
  "maxItems": 100
}
```

# Actor output Schema

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

One item per comment.

# 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=dQw4w9WgXcQ"
    ]
};

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tidyharvest/youtube-comments-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/9TMc0r67DfESl6Vza/builds/bjiLPTIWZZfqSezEg/openapi.json
