# YouTube Comments Scraper — Replies, No Login · $0.4/1K (`memo23/youtube-comments-scraper`) Actor

YouTube Comments Scraper for any video, no login or API key, $0.40 per 1,000 comments. Get comment text, author, likes, reply count, full reply threads, creator-heart and channel-owner flags and the post date. Sort by top or newest and stop at a date cutoff. JSON, CSV or Excel.

- **URL**: https://apify.com/memo23/youtube-comments-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, Videos, Lead generation
- **Features:** Limited permissions
- **Stats:** 156 total users, 9 monthly users, 99.7% runs succeeded, 8 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.40 / 1,000 results

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

### Overview

Dive deep into audience engagement and sentiment analysis with our YouTube Comments Scraper! Extract valuable insights from video comments, including user reactions, discussions, and feedback. Perfect for content creators, marketers, and researchers looking to understand their audience better.

### Explore More Scrapers

If you found this YouTube Comments Scraper useful, be sure to check out our other powerful scrapers and actors at [memo23's Apify profile](https://apify.com/memo23). We offer a wide range of tools to enhance your web scraping and automation needs across various platforms and use cases.

### How it works

This actor allows you to scrape comments from YouTube videos, extracting important details such as the comment text, author information, engagement metrics, and more. It provides valuable insights into audience reactions and discussions around specific videos or channels.

### Features

- Single or Multiple Video Scraping: Supports scraping comments from one or multiple YouTube video URLs.
- Detailed Comment Information: Extracts comprehensive data about each comment, including unique identifiers, author details, and engagement metrics.
- Sort Order: Choose YouTube's own "Top comments" ranking or strict "Newest first" ordering.
- Date Filtering: Keep only comments published after a date you set — and under "Newest first" the run stops paging the moment it reaches older comments, instead of reading the whole comment section.
- Reply Tracking: Identifies and links reply comments to their parent comments.
- Engagement Metrics: Captures vote counts and reply counts for each comment.
- Author Information: Retrieves non-sensitive author details like username and channel ownership status.
- Customizable: Flexible configuration options to suit various scraping needs.

### How to Use

1. Set Up: Ensure you have an Apify account and access to the Apify platform.
2. Configure Input: Set the YouTube video URL(s) you want to scrape comments from (see Input Data section).
3. (Optional) Set Max Items to limit the number of comments to scrape per video. Note: accounts on the Apify free plan are limited to 30 comments per run; any paid Apify plan removes this limit.
4. (Optional) Set Sort comments by to "Top comments" or "Newest first". Leave it empty and the actor picks for you.
5. (Optional) Set Oldest comment date to keep only recent comments — an ISO date (`2026-01-31`) or a span (`3 days`, `6 months`).
6. (Optional) Configure proxy settings for enhanced reliability and to avoid potential IP blocks.
7. Run the Scraper: Execute the scraper on the Apify platform.
8. Data Collection: The scraper will output data in your chosen format, which can include JSON, CSV, or others as supported by Apify.

### Input Configuration

Here's an example of how to set up the input for the YouTube Comments Scraper:

```json
{
    "startUrls": [
        {
            "url": "https://www.youtube.com/watch?v=o72NpKj0nxw"
        }
    ],
    "maxItems": 1000,
    "sortCommentsBy": "newest",
    "oldestCommentDate": "3 months",
    "maxConcurrency": 10,
    "minConcurrency": 1,
    "maxRequestRetries": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
}
```

#### Sorting and date filtering

- `sortCommentsBy` — `"top"` (YouTube's relevance ranking) or `"newest"` (strictly newest to oldest). Leave it out entirely and the actor asks for no order at all: YouTube serves the comment section as it would to a visitor, which is normally its Top ranking. The one exception is `oldestCommentDate` — set that without a sort and the actor picks `"newest"`, so the crawl can stop at the cutoff.
- `oldestCommentDate` — keep only comments published on or after this point. Accepts an ISO date (`2026-01-31`, `2026-01-31T08:30:00Z`) or a relative span (`3 days`, `2 weeks`, `6 months`). An unreadable value fails the run rather than being ignored.

  The filter is **approximate on purpose**. YouTube publishes no exact comment timestamp — only a rounded age such as `"2 weeks ago"` — so a comment is only ever known to a bucket, and the filter takes the inclusive edge of that bucket so nothing that might fall inside your range is dropped. Each row carries `publishedAtApprox` (ISO) next to the original `publishedTimeText`.

  Note that the pinned comment is returned first by YouTube whatever its age, so under "newest" the first row can be older than the rest. Replies are kept or dropped with their parent comment, never on their own date, so a kept thread always arrives whole — and those replies count towards `maxItems` like any other row.

  Under `"top"` the ranking is not chronological, so there is no point at which the rest of the section is guaranteed older and the crawl has nothing to stop at. It reads on under a budget (20 comments read per item requested, at least 1,000) and, if that runs out, ends with the reason and the fix in the run's status message. `"newest"` is the input that makes a date filter cheap.

### Output Structure

The output data typically includes:

```json
{
    "comment": "0l9",
    "cid": "Ugy9D_h58HxTs5o0z1Z4AaABAg",
    "author": "@jenadkins",
    "videoId": "",
    "pageUrl": "https://www.youtube.com/watch?v=undefined",
    "commentsCount": 0,
    "replyCount": 0,
    "voteCount": 0,
    "authorIsChannelOwner": false,
    "hasCreatorHeart": false,
    "type": "comment",
    "replyToCid": null,
    "publishedTimeText": "1 year ago",
    "publishedAtApprox": "2025-09-09T12:00:00.000Z"
}
```

#### Output Fields Explanation

- `comment`: The text content of the comment.
- `cid`: Unique identifier for the comment.
- `author`: The username of the comment author.
- `videoId`: The ID of the YouTube video (if available).
- `pageUrl`: The URL of the video page.
- `commentsCount`: Total number of comments on the video (if available).
- `replyCount`: Number of replies to this comment.
- `voteCount`: Number of votes (likes) on the comment.
- `authorIsChannelOwner`: Boolean indicating if the comment author is the channel owner.
- `hasCreatorHeart`: Boolean indicating if the comment has been hearted by the creator.
- `type`: Type of the item (e.g., "comment" or "reply").
- `replyToCid`: The CID of the parent comment if this is a reply.
- `publishedTimeText`: When the comment was published, exactly as YouTube words it (`"1 year ago"`, `"3 days ago (edited)"`). This is the only date YouTube publishes.
- `publishedAtApprox`: The same value read as an ISO timestamp, or `null` when the wording could not be read. Approximate — see Sorting and date filtering above.

### Support

- For issues or feature requests, please use the [Issues](https://console.apify.com/actors/9014XA2SYS1QZcVvI/issues) section of this actor.
- If you need customization or have questions, feel free to contact the author:
  - Author's website: <https://muhamed-didovic.github.io/>
  - Email: <muhamed.didovic@gmail.com>

### Additional Services

- Request customization or whole dataset: <muhamed.didovic@gmail.com>
- If you need anything else scraped, or this actor customized, email: <muhamed.didovic@gmail.com>
- For API services of this scraper (no Apify fee, just usage fee for the API), contact: <muhamed.didovic@gmail.com>

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/youtube-comments-scraper`).

**Purpose:** extract all comments and replies from one or more YouTube videos into flat JSON rows, with author, engagement metrics, and reply-to-parent threading.

**Minimal input:**

```json
{ "startUrls": [{ "url": "https://www.youtube.com/watch?v=o72NpKj0nxw" }], "maxItems": 50 }
```

**Output:** one dataset row per comment or reply — `comment` (text), `cid` (unique comment id), `author`, `videoId`, `pageUrl`, `commentsCount`, `replyCount`, `voteCount`, `authorIsChannelOwner`, `hasCreatorHeart`, `type` (`comment` | `reply`), `replyToCid` (parent comment's `cid` for replies), `publishedTimeText` (relative, e.g. `"1 year ago"` — the only date YouTube publishes) and `publishedAtApprox` (that value as an ISO timestamp, approximate, `null` when unreadable).

**Behaviors an agent should know:**

- `startUrls` is required — each entry is a `{ "url": "…" }` object naming ONE video: a `watch?v=` URL, a `youtu.be/` link, or a `/shorts/`, `/live/` or `/embed/` link, which are normalized for you. Pass several to scrape multiple videos in one run. Channel, playlist and search URLs have no comment section of their own; they are skipped with a note in the log, and a run with nothing else fails and says so.
- Always set `maxItems` (default 100, minimum 1) — popular videos can carry hundreds of thousands of comments. It counts rows that reach the dataset, replies included, and applies to each video separately: 3 videos with `maxItems: 100` can return up to 300 rows.
- Replies come back as their own rows with `type: "reply"` and `replyToCid` pointing at the parent comment's `cid`; top-level rows have `type: "comment"`.
- `sortCommentsBy` is `"top"` or `"newest"`; omit it and the actor requests no order, leaving YouTube's own (normally Top) — except when `oldestCommentDate` is set, where it picks `"newest"`.
- `oldestCommentDate` takes an ISO date or a span (`"3 days"`, `"6 months"`) and keeps only top-level comments at least that recent. It is bucket-accurate, not exact — YouTube publishes no comment timestamp — and never drops a comment that might be in range. Combine it with `"newest"` to make the run stop at the cutoff instead of reading on under a budget. Replies follow their parent, so kept threads arrive whole whatever the age of the individual replies.
- `maxConcurrency` (default 10, 1–100), `minConcurrency` (default 1, 1–100), and `maxRequestRetries` (default 3, 0–20) tune throughput and retry resilience.
- Built-in residential proxy is on by default, on every plan. Set `proxy` only to override it — your own `proxyUrls`, or an `apifyProxyGroups`/`apifyProxyCountry` selection when you need exits in a particular place; that replaces the built-in pool for every request and is billed to your account. Choosing Apify Proxy with no group and no country is not an override. Public comment data only — no login, and no age-restricted or private content.
- Pay-per-event billing — see the Pricing tab on the actor page.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by YouTube or Google LLC. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available YouTube comment data that any visitor can view — no authenticated endpoints, no age-restricted or private content, and nothing behind the YouTube login. Users are responsible for ensuring their use complies with YouTube's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.

### SEO Keywords

YouTube comments scraper, scrape YouTube comments, YouTube comment scraper, YouTube comments API, youtube.com scraper, Apify YouTube, YouTube reply scraper, video comments scraper, comment extractor, youtube engagement data, audience sentiment analysis, comment sentiment data, youtube audience insights, social media comments scraper, youtube data export, content creator analytics, video engagement metrics, youtube comment export, social listening data, youtube marketing research

# Actor input Schema

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

One YouTube video per entry — this actor reads a single video's comment section at a time. Accepted: https://www.youtube.com/watch?v=<id>, https://youtu.be/<id>, and /shorts/, /live/ and /embed/ links, which are normalized to the watch page for you.

Channel, playlist and search URLs carry no comment section of their own and are skipped with a note in the log; a run with nothing but those fails and says so.

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

Maximum number of comments per video, counted in rows that reach the dataset — replies included. With several videos, each one gets this budget. Note: accounts on the Apify free plan are limited to 30 comments per run in total — any paid Apify plan removes this limit.

## `sortCommentsBy` (type: `string`):

Order YouTube returns the comments in. "Top comments" is YouTube's own relevance ranking; "Newest first" is strictly by date, newest to oldest.

Leave empty and the actor asks for no order at all — YouTube serves the comment section exactly as it would to a visitor, which is normally its Top ranking. The one exception is "Oldest comment date": set that without a sort and the actor picks Newest first, so the run can stop as soon as it reaches comments older than your cutoff.

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

Only return top-level comments published on or after this date. Accepts an ISO date (2026-01-31) or a relative span ("3 days", "2 weeks", "6 months").

Replies are not filtered: a comment that passes the cutoff arrives with its whole reply thread, whatever the age of the individual replies, because a thread with its middle cut out is worse than no thread. Those replies count towards Max Items like any other row.

Approximate by design: YouTube publishes no exact comment timestamp, only a rounded age such as "2 weeks ago", so the filter is accurate to that bucket and never drops a comment that could fall inside your range. Every row also carries publishedAtApprox (ISO) alongside the original publishedTimeText.

With "Newest first" the run stops paging as soon as it reaches older comments, which makes a date filter cheap. With "Top comments" the ranking is not chronological, so there is no point at which the rest is guaranteed older — the filter still applies, but the run reads on under a budget and stops with an explanation rather than running to the end of a comment section that can be hundreds of thousands long.

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

Maximum number of pages that can be processed at the same time.

## `minConcurrency` (type: `integer`):

Minimum number of pages that will be processed at the same time.

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

Number of times the crawler will retry a failed request before giving up.

## `proxy` (type: `object`):

Leave empty: the default works out of the box. Apify Proxy groups and countries chosen here are not used (the run logs a line saying so). Only your own proxy URLs, with 'Use Apify Proxy' switched off, are honoured.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=NUDV3lIGb24"
    }
  ],
  "maxItems": 100,
  "oldestCommentDate": "3 months",
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 3,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "startUrls": [
        {
            "url": "https://www.youtube.com/watch?v=NUDV3lIGb24"
        }
    ],
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/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 = {
    "startUrls": [{ "url": "https://www.youtube.com/watch?v=NUDV3lIGb24" }],
    "proxy": { "useApifyProxy": True },
}

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

```

## MCP server setup

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