# YouTube Comments Scraper Pro: Replies & Threads (`smart_albatross/youtube-comments-scraper-pro`) Actor

Scrape YouTube comments and replies without an API key. Exact caps, thread IDs, author data, filters, and free status rows.

- **URL**: https://apify.com/smart\_albatross/youtube-comments-scraper-pro.md
- **Developed by:** [Dev](https://apify.com/smart_albatross) (community)
- **Categories:** Videos, Social media
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.22 / 1,000 delivered comment or replies

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 Pro

Collect public YouTube comments and replies from videos, Shorts, and live-video URLs without a YouTube Data API key or browser. Each comment or reply is a separate, thread-linked dataset row ready for CSV export, analysis, and automation.

### Why use this Actor?

| Need | What you get |
| --- | --- |
| Predictable spend | Exact per-video and run-wide comment caps plus Apify's maximum charge per run. Only delivered comments and replies are billed; starts, empty videos, notices, and errors have no event charge. |
| Reconstructable conversations | Every reply carries `parentCommentId`; every row has stable `commentId`, `videoId`, and a direct comment URL. |
| Useful research data | Text, author/channel identifiers, numeric likes, reply count, relative posting text, pinned/hearted badges, and optional video title/count. |
| Focused filters | Newest or top order, optional text substring and minimum likes. Filtered-out comments are not billed. |
| Bulk resilience | Multiple video URLs or IDs, duplicate-input suppression, per-video failure isolation, bounded pagination/requests, HTTP timeouts/retries, and restart-safe checkpoints. |

The Actor uses direct HTTP by default. A proxy is optional; YouTube may rate-limit or withhold comments depending on the video, region, and request volume.

In a paid cloud test at 256 MB, it delivered 1,000 unique comments with 1,000 matching billed events in 33.3 seconds. A separate 1,500-comment run survived a forced container reboot and still finished with 1,500 unique rows and 1,500 billed events. These are single-run measurements, not speed guarantees; replies, filters, source availability, and proxies change runtime.

### Pricing

One `comment` event is charged for each successfully delivered top-level comment or reply. Both cost the same. There is no start fee, video fee, query fee, or charge for `notice`/`error` rows.

| Apify plan | Price per 1,000 comments or replies |
| --- | ---: |
| Free | $0.30 |
| Bronze | $0.27 |
| Silver | $0.25 |
| Gold | $0.22 |
| Platinum | $0.22 |
| Diamond | $0.22 |

For example, 1,000 delivered comments and 200 delivered replies cost $0.36 on Free. Setting a maximum charge when starting the run provides another hard billing ceiling.

### Quick start

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }],
  "maxCommentsPerVideo": 100,
  "maxTotalComments": 100,
  "sortBy": "newest",
  "includeReplies": true,
  "maxRepliesPerComment": 10
}
```

You can also supply `videoIds` containing 11-character IDs, combine IDs and URLs, and import a list of URLs from a CSV or Google Sheet through Apify's URL editor. The Actor processes duplicate video IDs once.

### Output

Each delivered comment or reply is a separate dataset item. Replies use `recordType: "reply"` and point to a delivered top-level comment with `parentCommentId`.

```json
{
  "recordType": "reply",
  "videoId": "dQw4w9WgXcQ",
  "commentId": "reply-id",
  "parentCommentId": "parent-comment-id",
  "text": "A public reply",
  "authorName": "@viewer",
  "authorChannelId": "UC...",
  "likeCount": 12,
  "publishedText": "2 days ago",
  "commentUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=reply-id",
  "inputSource": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "scrapedAt": "2026-09-27T12:00:00.000Z"
}
```

Other fields, when YouTube provides them, include `replyCount`, `likeCountText`, `authorUrl`, `authorIsVerified`, `authorIsChannelOwner`, `isMember`, `isPinned`, `isHearted`, `videoTitle`, and `videoCommentCount`. Missing values are omitted rather than guessed.

`notice` and `error` rows explain empty comments, invalid video inputs, limits, repeated continuation pages, unavailable videos, or reply-fetch failures. They are not billable. Read the `OUTPUT` key in the default key-value store for exact counts, HTTP telemetry, and `chargeLimitReached`/`resultLimitReached` flags.

### Limits and behavior

- `maxCommentsPerVideo` and `maxTotalComments` count delivered comments and replies together. Top-level comments are prioritized before their replies on each page.
- `maxRepliesPerComment` limits delivered replies under each parent. Replies are fetched only when their parent comment passes the filters and is delivered.
- `textContains` is a case-insensitive substring filter; `minLikes` treats unavailable like counts as zero.
- `maxPagesPerVideo`, `maxRequestsPerVideo`, `maxTotalRequests`, and `requestTimeoutMs` bound work even when YouTube repeats pages or filters match nothing.
- The request ceilings apply to per-video work; YouTube session initialization can make one request before a video is processed.
- After an abrupt container restart, HTTP attempts since the latest checkpoint may be retried; comment and billing caps remain exact because committed dataset rows are recovered and deduplicated.
- `publishedText` is YouTube's relative wording, such as “2 days ago.” This Actor does not invent an exact timestamp from it.
- Only public video comments are supported. Channel, playlist, community-post, live-chat, private, deleted, and members-only content are not supported inputs.
- YouTube can change its internal responses. A run may return partial data, which is signaled by status records and the run summary. A requested limit is a maximum, not a guaranteed number of available comments.

Public comments can contain personal data. Use the output responsibly and follow applicable platform terms and privacy law.

# Actor input Schema

## `startUrls` (type: `array`):

YouTube watch, youtu.be, Shorts, live, or embed URLs. Import a CSV or Google Sheet through the URL editor.

## `videoIds` (type: `array`):

Optional 11-character video IDs; can be combined with URLs. Duplicate videos are processed once.

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

Exact cap on delivered comment and reply rows per video.

## `maxTotalComments` (type: `integer`):

Exact run-wide cap on delivered, billable rows across all videos.

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

Use top comments for popular discussion or newest first for monitoring.

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

Deliver replies as separate rows linked to their parent comment ID. Replies count toward the limits and price.

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

Only used when replies are enabled. Zero disables reply fetching.

## `textContains` (type: `string`):

Optional case-insensitive substring filter. Filtered comments are not charged; replies are fetched only for delivered parent comments.

## `minLikes` (type: `integer`):

Optional minimum like count; unavailable counts are treated as zero. Filtered comments are not charged.

## `includeVideoMetadata` (type: `boolean`):

Fetch video metadata for context. If metadata is unavailable, comment extraction continues.

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

Safety limit across URLs and IDs supplied to one run.

## `maxPagesPerVideo` (type: `integer`):

Bounds comment and reply continuation pages together. A notice reports partial output when reached.

## `maxRequestsPerVideo` (type: `integer`):

Includes retries, comments, replies, and metadata requests. A notice reports partial output when reached.

## `maxTotalRequests` (type: `integer`):

Run-wide safety ceiling for video scraping requests, including retries. One initial session request may occur before this limit applies.

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

Number of video sources processed at once.

## `maxRequestRetries` (type: `integer`):

Retries transient request failures and 429/5xx responses with backoff.

## `requestTimeoutMs` (type: `integer`):

Maximum duration of one YouTube HTTP attempt.

## `language` (type: `string`):

Language used for YouTube requests and relative date text.

## `country` (type: `string`):

Two-letter country code used for YouTube requests.

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

Optional Apify Proxy or custom proxy. Direct HTTP is used by default.

## `debug` (type: `boolean`):

Enable verbose diagnostic logs for troubleshooting.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "videoIds": [],
  "maxCommentsPerVideo": 100,
  "maxTotalComments": 1000,
  "sortBy": "newest",
  "includeReplies": false,
  "maxRepliesPerComment": 20,
  "textContains": "",
  "minLikes": 0,
  "includeVideoMetadata": true,
  "maxVideos": 200,
  "maxPagesPerVideo": 100,
  "maxRequestsPerVideo": 500,
  "maxTotalRequests": 1000,
  "maxConcurrency": 4,
  "maxRequestRetries": 2,
  "requestTimeoutMs": 20000,
  "language": "en",
  "country": "US",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "debug": false
}
```

# Actor output Schema

## `results` (type: `string`):

Public comments, replies, and free status records in the default dataset.

## `summary` (type: `string`):

Exact row counts, video outcomes, retries, request limits, and billing-limit status.

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

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

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

```

## MCP server setup

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

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/WPhNHhZiYhgHaigXD/builds/6Lsf9v0RfjgBdCP2V/openapi.json
