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

Scrape YouTube comments with replies, timestamps, likes, hearts, pins, and verified badges.

- **URL**: https://apify.com/happy_b/youtube-comments-scraper.md
- **Developed by:** [Happy B](https://apify.com/happy_b) (community)
- **Categories:** Social media, Videos
- **Features:** Limited permissions
- **Stats:** 26 total users, 2 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

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

### What is YouTube Comments Extractor?

YouTube Comments Extractor scrapes comments from any public YouTube video with **complete, structured data** — ISO 8601 timestamps, exact like counts, creator hearts, pinned status, verified badges, and full reply threads with parent-child relationships.

Every comment comes with **precise, machine-readable fields** ready for analysis pipelines, databases, and spreadsheets.

#### Data points extracted per comment

| Field | Description | Example |
|-------|-------------|---------|
| `commentId` | Unique YouTube comment ID | `Ugzge340dBgB75hWBm54AaABAg` |
| `content` | Plain text comment body | `This song never gets old!` |
| `contentHtml` | HTML-formatted comment with links/formatting | `This song <b>never</b> gets old!` |
| `publishedAt` | ISO 8601 timestamp | `2025-04-22T19:05:08Z` |
| `likeCount` | Exact numeric like count | `209980` |
| `replyCount` | Number of replies to this comment | `960` |
| `isHearted` | Creator hearted this comment | `true` |
| `isPinned` | Comment is pinned by creator | `true` |
| `authorDisplayName` | Comment author's display name | `@YouTube` |
| `authorIsVerified` | Author has YouTube verification badge | `true` |
| `authorIsCreator` | Author is the video's channel owner | `false` |
| `parentCommentId` | Parent comment ID (for replies) | `Ugzge340dBgB75hWBm54AaABAg` |
| `replyLevel` | 0 = top-level comment, 1 = reply | `1` |

Plus: `updatedAt`, `isEdited`, `authorChannelId`, `authorChannelUrl`, `authorAvatarUrl`, `authorIsArtist`, `videoId`, `videoTitle`, `videoUrl`, `videoCommentCount`, `scrapeTimestamp`.

**24 fields per comment. Every field populated.**

### Why use this scraper?

#### Our Actor vs Top 3 YouTube Comment Actors

| Field | Us | Streamers | API Ninja | Deeper |
|-------|:--:|:---------:|:---------:|:------:|
| `publishedAt` ISO 8601 exact | ✅ | ❌ | ❌ | ❌ |
| `updatedAt` ISO 8601 | ✅ | ❌ | ❌ | ❌ |
| `isEdited` | ✅ | ❌ | ✅ | ❌ |
| `isPinned` | ✅ | ❌ | ✅ | ❌ |
| `isHearted` | ✅ | ✅ | ❌ | ❌ |
| `likeCount` exact integer | ✅ | ✅ | ❌ | ❌ |
| `replyLevel` (0/1) | ✅ | ❌ | ❌ | ❌ |
| Reply threading | ✅ | ✅ | ✅ | ❌ |
| `contentHtml` | ✅ | ❌ | ❌ | ❌ |
| `authorChannelId` | ✅ | ❌ | ✅ | ❌ |
| `authorChannelUrl` | ✅ | ❌ | ✅ | ❌ |
| `authorAvatarUrl` | ✅ | ❌ | ✅ | ❌ |
| `authorIsVerified` | ✅ | ❌ | ❌ | ❌ |
| `authorIsArtist` | ✅ | ❌ | ❌ | ❌ |
| `authorIsCreator` | ✅ | ✅ | ❌ | ❌ |
| `videoTitle` | ✅ | ✅ | ❌ | ❌ |
| `videoCommentCount` | ✅ | ✅ | ❌ | ❌ |

**Reply threading** — each reply has `parentCommentId` pointing to the comment it's replying to. You can rebuild the thread:

```
@YouTube: "can confirm: he never gave us up"             ← parentCommentId: ""
  └─ @Cheese: "Bro is 15 years late"                     ← parentCommentId: "Ugzge340d..."
  └─ @SleepyBear: "Only took 15 years"                   ← parentCommentId: "Ugzge340d..."
@ochkalov: "1987: normal song, 2026: national anthem"
  └─ @armin: "so true"                                   ← parentCommentId: "UgxIOV-s..."
```

- **Incremental delivery** — Results appear in your dataset within seconds. Export anytime, don't wait for the run to finish.
- **From $0.50 per 1,000 items** — Volume discounts down to $0.25 on Business plan.

### Use cases

- **Brand monitoring** — Track what people say about your brand in competitor video comments. Filter by `authorIsCreator` to find official channel responses.
- **Sentiment analysis** — Feed complete comment text with ISO timestamps into your NLP pipeline. Replies give you conversation context that top-level-only scrapers miss.
- **Research & academia** — Extract large comment corpora with exact dates and engagement metrics for reproducible studies.
- **Content strategy** — Identify what resonates by sorting through high-engagement comments (`likeCount`, `isHearted`, `isPinned`).
- **Community management** — Find creator-hearted comments, pinned comments, and verified user interactions across multiple videos.
- **ML training data** — Structured JSON with 24 fields per comment, ready for classification, fine-tuning, or embedding pipelines.

### How much does it cost?

Each comment or reply counts as one item.

| Plan | Price per 1,000 items |
|------|----------------------|
| Free | $0.50 |
| Starter | $0.45 |
| Scale | $0.40 |
| Business | $0.25 |

| Scenario | Items | Cost |
|----------|-------|------|
| 1 video, 500 comments, no replies | 500 | $0.25 |
| 1 video, 100 comments, ~30 have replies (avg 5 each) | ~250 | $0.12 |
| 10 videos, 500 comments each, no replies | 5,000 | $2.50 |
| 1 video, 5,000 comments (Newest First) | 5,000 | $2.50 |

**Replies are opt-in.** With `includeReplies` off (default), you only pay for top-level comments. When enabled, each reply is a separate item. You control the maximum replies per comment with `maxRepliesPerComment`.

Apify also charges a small compute cost (CU) for the actor's runtime — typically under $0.01 for most runs.

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `videoUrls` | string\[] | *required* | YouTube video URLs or bare video IDs. Supports youtube.com/watch, youtu.be, /shorts/, /embed/, /live/ formats. |
| `maxCommentsPerVideo` | integer | 500 | Maximum top-level comments to fetch per video (1-10,000). |
| `sortBy` | string | `relevance` | `relevance` (Top Comments) or `time` (Newest First). Top Comments is capped at ~1,200 by YouTube. Use Newest First for full extraction. |
| `includeReplies` | boolean | `false` | Fetch replies for each comment. Each reply counts as a billable item. |
| `maxRepliesPerComment` | integer | 50 | Maximum replies per comment (1-200). Only used when Include Replies is on. |

### Output example

Each item in the dataset is a single comment or reply:

```json
{
  "commentId": "Ugzge340dBgB75hWBm54AaABAg",
  "content": "Check out my channel https://youtube.com/@example",
  "contentHtml": "Check out my channel <a href=\"https://youtube.com/@example\">https://youtube.com/@example</a>",
  "publishedAt": "2025-04-22T19:05:08Z",
  "updatedAt": "2025-04-22T19:05:08Z",
  "isEdited": false,
  "likeCount": 209980,
  "replyCount": 960,
  "replyLevel": 0,
  "isPinned": true,
  "isHearted": true,
  "authorDisplayName": "@YouTube",
  "authorChannelId": "UCBR8-60-B28hp2BmDPdntcQ",
  "authorChannelUrl": "https://www.youtube.com/channel/UCBR8-60-B28hp2BmDPdntcQ",
  "authorAvatarUrl": "https://yt3.ggpht.com/...",
  "authorIsVerified": true,
  "authorIsCreator": false,
  "authorIsArtist": false,
  "videoId": "dQw4w9WgXcQ",
  "videoTitle": "Rick Astley - Never Gonna Give You Up",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "videoCommentCount": 3200000,
  "scrapeTimestamp": "2026-04-01T12:00:00Z",
  "parentCommentId": ""
}
```

A reply to this comment looks identical, except:

```json
{
  "commentId": "Ugzge340dBgB75hWBm54AaABAg.AHE8_QAWJx9AHEjU2AWVXk",
  "content": "Bro is 15 years late",
  "replyLevel": 1,
  "replyCount": 0,
  "parentCommentId": "Ugzge340dBgB75hWBm54AaABAg",
  "isPinned": false,
  "likeCount": 1810,
  "publishedAt": "2025-05-15T08:22:41Z"
}
```

Replies appear in the dataset directly after their parent comment, making thread reconstruction straightforward.

Download your results as **JSON**, **CSV**, **Excel**, **XML**, or **HTML** from the dataset tab, or access them via the [Apify API](https://docs.apify.com/api/v2#/reference/datasets).

### Good to know

**YouTube caps "Top Comments" at ~1,200 results.** This is a YouTube limitation on relevance-sorted comments for popular videos. If you need more than 1,200 comments, use `sortBy: "time"` (Newest First), which has no cap.

**Reply costs scale with discussion depth.** A video where most comments have 0-2 replies adds minimal cost. A viral video where top comments have 500+ replies each will produce many more billable items. Use `maxRepliesPerComment` to cap costs.

### Integrations

Connect this actor to your workflow with [Apify integrations](https://docs.apify.com/platform/integrations):

- **Make (Integromat)** — trigger workflows when new data is available
- **Zapier** — push comments to Google Sheets, Slack, or databases
- **GitHub** — store results in repositories
- **Google Drive** — export directly to spreadsheets
- **Webhooks** — notify your API when the run completes
- **Apify API** — programmatic access for custom pipelines

### Legal and personal data

This actor extracts publicly available data from YouTube. You should ensure your use of the extracted data complies with YouTube's [Terms of Service](https://www.youtube.com/t/terms), applicable data protection laws (GDPR, CCPA), and your jurisdiction's regulations regarding web scraping and data processing.

Comments are public content posted by users on a public platform. Author information (display names, channel URLs) is publicly visible on YouTube.

### Support

Found a bug or have a feature request? Open an issue on the [Issues tab](https://apify.com/happy_b/youtube-comments-scraper/issues/open) or contact us through Apify messaging.

# Actor input Schema

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

YouTube video URLs or video IDs to scrape comments from

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

Maximum number of comments to fetch per video

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

Comment sort order

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

Fetch replies to comments. Each reply counts as a separate item for billing.

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

Maximum number of replies per comment (only used when Include Replies is on)

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxCommentsPerVideo": 500,
  "sortBy": "relevance",
  "includeReplies": false,
  "maxRepliesPerComment": 50
}
```

# Actor output Schema

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

No description

## `metadata` (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 = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

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

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

```

## MCP server setup

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