# YouTube Comments Scraper: With Replies (`luzivanlt/youtube-comments-scraper`) Actor

YouTube video comments with their replies, threaded, plus the video's title, views and likes. $0.50 per 1,000 comments. Channel on every row. Pinned, hearted and creator replies.

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

## Pricing

from $0.35 / 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

## YouTube Comments Scraper: With Replies

Get the comments of YouTube videos with their replies, threaded: each reply
names the comment it answers. Every row also carries the video's title,
views, likes, date and channel, so one file holds the comments and what they
are about. See which comments the channel pinned, hearted or replied to. No
YouTube account, login or cookies needed.

Tested daily. Latest checks: 132 comments and replies from two videos in 13
seconds; 654 from three videos, each read to its end, in about 3.5 minutes.

### What does this Actor do?

You give it links to YouTube videos (or just video ids). For each video it
reads the comments, and the replies under each comment, and saves one row per
comment or reply until it reaches your limit or the end of the comments.

Each row comes with:

- the comment's text, when it was posted (as YouTube shows it, such as
  "3 weeks ago"), whether it was edited, its likes and its number of replies
- for a reply: the comment it answers
- whether the channel pinned it, hearted it or replied to it
- the links in the comment, with YouTube's redirect removed
- the commenter's channel id, name, handle and picture, and whether they are
  verified, the video's own channel, or an official artist
- the video's title, description, views, likes, date, comment count and
  whether it is live
- the channel's id, name, handle, subscriber count and verified mark

### Why use it?

- **Replies included, threaded.** Replies are read by default, and each one
  links back to its comment, so you can rebuild every conversation.
- **Comments with their context.** Each row names its video and channel, with
  views and likes, so comments from many videos can be compared in one sheet.
- **Find what the channel noticed.** See which comments it pinned, hearted or
  answered.
- **Top or newest.** Read comments in YouTube's top order or newest first.
- **Use the data anywhere.** Download as JSON, CSV or Excel, or send it to
  your own tools through Apify's API and integrations.

### How to use it

1. Paste one or more video links into **Video links**.
2. Optionally, set **Max comments per video**, choose **Order**, and turn
   **Include replies** off.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   comments or download them.

Run it with no input to see a sample: up to 100 comments each from two videos,
charged as usual.

#### Links that work

A video link as in your browser's address bar
(`https://www.youtube.com/watch?v=IdPutKgWVCE`), a `youtu.be/…` share link, a
Shorts, live or embed link, or the 11-character video id on its own
(`IdPutKgWVCE`). Channel, playlist and search pages are not supported: this
Actor reads the comments of the videos you name.

### Use it with YouTube Scraper's results

Already have video links in a [YouTube Scraper](https://apify.com/streamers/youtube-scraper) run? Skip the copying:

1. Run the YouTube Scraper, then open its run and copy the **dataset id** from the
   Storage tab (or paste the dataset's link).
2. Paste it into **Dataset id from a scraper run** (`datasetId`) here. Or schedule
   this Actor after the other one and pass the id each time. If your account
   cannot read that dataset, paste its rows into **Rows from a scraper run**
   (`datasetRows`) instead.
3. Click **Start**. The Actor reads each row's `url` as a link, adds it to
   **Video links** and reads its comments. Our YouTube Search and YouTube Channel Videos Actors write the same `url` field, so their datasets work too.

Rows with no usable link, such as channel or playlist rows, are skipped, and so are
rows whose own comment count is 0. The status line says how many rows were read
and how many were skipped. A link in both **Video links** and the dataset is read
once. If **Video links** still holds the form's example links when you give a dataset, they are left out, and the status says so. At most 10,000 rows are read from one dataset. Comments are priced as
usual: each comment saved is one row, whichever way the links reached us.

### Input

| Field                                              | What it does                                          | Default |
| -------------------------------------------------- | ----------------------------------------------------- | ------- |
| **Video links** (`startUrls`)                      | The videos to read. Required.                         | —       |
| **Max comments per video** (`maxCommentsPerVideo`) | Stop after this many rows per video, replies included | `100`   |
| **Include replies** (`includeReplies`)             | Also save the replies to each comment                 | `true`  |
| **Order** (`sortBy`)                               | `top` (YouTube's default) or `newest`                 | `top`   |

Example input:

```json
{
  "startUrls": [{ "url": "https://www.youtube.com/watch?v=IdPutKgWVCE" }],
  "maxCommentsPerVideo": 1000,
  "includeReplies": true,
  "sortBy": "newest"
}
```

### Output

One row per comment or reply. An example, with made-up values:

```json
{
  "comment_id": "UgzAbCdEfGhIjKlMnOp4AaABAg",
  "video_id": "IdPutKgWVCE",
  "source_url": "https://www.youtube.com/watch?v=IdPutKgWVCE",
  "text": "Great video, thanks!",
  "published_time_text": "3 weeks ago",
  "is_edited": false,
  "like_count": 38,
  "reply_count": 2,
  "is_reply": false,
  "parent_comment_id": null,
  "reply_level": 0,
  "pinned": false,
  "hearted_by_creator": true,
  "creator_replied": false,
  "links": [],
  "comment_url": "https://www.youtube.com/watch?v=IdPutKgWVCE&lc=UgzAbCdEfGhIjKlMnOp4AaABAg",
  "author_channel_id": "UC0000000000000000000000",
  "author_name": "@janedoe",
  "author_handle": "@janedoe",
  "author_avatar_url": "https://yt3.ggpht.com/…",
  "author_is_verified": false,
  "author_is_channel_owner": false,
  "author_is_artist": false,
  "author_badge": null,
  "video_title": "A video title",
  "video_description": "The video's description…",
  "video_view_count": 136219,
  "video_is_live": false,
  "video_like_count": 3546,
  "video_date_text": "Nov 29, 2024",
  "video_published_date": "2024-11-29",
  "video_comment_count": 260,
  "channel_id": "UC1111111111111111111111",
  "channel_name": "A Channel",
  "channel_handle": "@achannel",
  "channel_subscribers_text": "266K subscribers",
  "channel_verified": true
}
```

| Field                      | What it holds                                                        |
| -------------------------- | -------------------------------------------------------------------- |
| `comment_id`               | YouTube's id for the comment or reply                                |
| `video_id`                 | The video's id                                                       |
| `source_url`               | The video link or id you gave                                        |
| `text`                     | The text                                                             |
| `published_time_text`      | When it was posted, as YouTube shows it ("3 weeks ago")              |
| `is_edited`                | Whether it was edited                                                |
| `like_count`               | Likes (YouTube rounds counts above 1,000, such as 1.2K → 1200)       |
| `reply_count`              | Replies to the comment (empty on a reply)                            |
| `is_reply`                 | Whether the row is a reply                                           |
| `parent_comment_id`        | For a reply: the comment it sits under                               |
| `reply_level`              | 0 for a comment, 1 for a reply                                       |
| `pinned`                   | Whether the channel pinned it (empty on a reply)                     |
| `hearted_by_creator`       | Whether the channel hearted it                                       |
| `creator_replied`          | Whether the channel replied to it (empty on a reply)                 |
| `links`                    | Links in the text: outside links, hashtags, mentions and timestamps  |
| `comment_url`              | A link to the comment                                                |
| `author_channel_id`        | The commenter's channel id                                           |
| `author_name`              | The commenter's name as shown (usually the `@` handle)               |
| `author_handle`            | The commenter's `@` handle                                           |
| `author_avatar_url`        | The commenter's picture                                              |
| `author_is_verified`       | Whether the commenter is verified                                    |
| `author_is_channel_owner`  | Whether the commenter is the video's own channel                     |
| `author_is_artist`         | Whether the commenter is an official artist channel                  |
| `author_badge`             | The commenter's badge text, if any                                   |
| `video_title`              | The video's title                                                    |
| `video_description`        | The video's description                                              |
| `video_view_count`         | The video's views (empty while it is live)                           |
| `video_is_live`            | Whether the video is a live stream right now                         |
| `video_like_count`         | The video's likes                                                    |
| `video_date_text`          | The video's date as YouTube shows it ("Premiered Nov 29, 2024")      |
| `video_published_date`     | The same date as `YYYY-MM-DD`                                        |
| `video_comment_count`      | The comment count shown above the comments                           |
| `channel_id`               | The video's channel id                                               |
| `channel_name`             | The channel's name                                                   |
| `channel_handle`           | The channel's `@` handle                                             |
| `channel_subscribers_text` | The channel's subscribers as YouTube shows them ("266K subscribers") |
| `channel_verified`         | Whether the channel is verified                                      |

Not included: an exact date and time for each comment (YouTube shows only
"3 weeks ago"), the video's transcript, and the commenters' own channels.

### How much does it cost?

No surcharges and no paid options; an item that fails is not charged.

You pay for what you get:

- **$0.50 per 1,000 comments** ($0.0005 a comment). A reply counts as a comment. Each is charged once per run.
- No start fee, and nothing per video.

So 2,000 comments and replies from one video cost $1. If you set a maximum cost for a run, the Actor stops when it reaches it and keeps every comment saved so far.

### How long does a run take?

Expect about 200 comments and replies a minute. In testing, 654 from three
videos, each read to its end, took about 3.5 minutes.

### Good to know

- **You may get fewer comments than the video's count.** YouTube's count
  includes comments it no longer shows (held for review or removed), so a
  whole video usually reads a little below `video_comment_count`.
- **Dates are relative.** YouTube shows when a comment was posted only as
  "3 weeks ago" or "1 year ago"; the row keeps it as shown.
- **Check your links first.** A link that is not a YouTube video link stops the
  run before anything is read, and the message names it.
- **One video that cannot be read does not stop the run.** The other videos
  carry on, and the run's status lists the videos that could not be read. The
  run fails only when no video could be read.
- **No comments is not an error.** A video with comments turned off saves
  nothing.

### More Actors from us

- [YouTube Channel Scraper: Every Video & Short](https://apify.com/luzivanlt/youtube-channel-videos-scraper): Every upload of a YouTube channel, newest first: videos, Shorts and live streams in one list.
- [YouTube Search Scraper: Videos, Shorts & Channels](https://apify.com/luzivanlt/youtube-search-scraper): YouTube search results in YouTube's own order: videos, Shorts, channels, playlists, movies.
- [YouTube Transcript Scraper: Channels, Playlists & SRT](https://apify.com/luzivanlt/youtube-transcripts-scraper): YouTube transcripts with timestamps from videos, whole channels or playlists, in the languages you pick.
- [AliExpress Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/aliexpress-products-scraper): Every product of an AliExpress search to its last page, with exact sold counts and ratings.
- [Amazon Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/amazon-products-scraper): Every product on Amazon's search pages to the last page, sponsored marked, with monthly sales.
- [App Store Reviews Scraper: All Reviews, Not 500](https://apify.com/luzivanlt/app-store-reviews-scraper): Every written App Store review of an app, not just the newest 500.
- [Woolworths Coles ALDI Scraper: AU Grocery Prices](https://apify.com/luzivanlt/au-supermarkets-scraper): Woolworths, Coles and ALDI products for any search in one run, every results page to the end.
- [Bilibili Video Scraper: Search & Channel Videos](https://apify.com/luzivanlt/bilibili-videos-scraper): Bilibili videos from searches or whole channels, each with its full detail page's data.
- [Career Site Jobs Scraper: Workday, Greenhouse, Lever](https://apify.com/luzivanlt/career-site-jobs-scraper): Every job on Greenhouse, Lever, Ashby, SmartRecruiters and Workday boards, checked against each board's count.

### Use it from an AI agent or the API

One call starts a run and returns its items (Apify waits up to 300 seconds; for a
longer run, start it with `POST /v2/acts/…/runs` and read its dataset):

```text
POST https://api.apify.com/v2/acts/luzivanlt~youtube-comments-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
```

With the sample input as its JSON body:

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=IdPutKgWVCE"
    },
    {
      "url": "https://www.youtube.com/watch?v=lFn5dqNy7uU"
    }
  ],
  "maxCommentsPerVideo": 100,
  "includeReplies": true,
  "sortBy": "top"
}
```

Its inputs, in the order of the input form:

| Input                                          | What it takes                                                                                                                                                                                                     | Default |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `startUrls` (Video links)                      | Links to YouTube videos (https://www.youtube.com/watch?v=…, youtu.be/…, Shorts, live and embed links, on www., m. or music.youtube.com, with or without https://), or 11-character video ids such as IdPutKgWVCE. | —       |
| `datasetId` (Dataset id from a scraper run)    | The id of a run's dataset from YouTube Scraper (streamers/youtube-scraper), so you do not copy video links by hand.                                                                                               | —       |
| `datasetRows` (Rows from a scraper run)        | Rows pasted from YouTube Scraper (streamers/youtube-scraper) results, as a JSON list, when its dataset id is not readable by your account.                                                                        | —       |
| `maxCommentsPerVideo` (Max comments per video) | Stop reading a video after this many comments, replies included.                                                                                                                                                  | `100`   |
| `includeReplies` (Include replies)             | Also save the replies to each comment, each marked with the comment it answers.                                                                                                                                   | `true`  |
| `sortBy` (Order)                               | Top comments first (YouTube's default), or newest first.                                                                                                                                                          | `"top"` |

Apify's MCP server, `https://mcp.apify.com`, lists it as `luzivanlt/youtube-comments-scraper`. To give an
AI agent this Actor as a tool, add the server to the agent's MCP config:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=luzivanlt/youtube-comments-scraper"
    }
  }
}
```

The client signs in with OAuth, or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }`.

Charged per comment delivered; the sample input above costs at most $0.10.

### FAQ

**Do I need a YouTube account or cookies?**
No. The Actor reads the comments anyone can see under the video.

**Can I get the videos of a channel?**
Not with this Actor: it reads the comments of the videos you give it.

**Can I run it from my own code, on a schedule, or with other apps?**
Yes. Like any Apify Actor, you can start it through the Apify API, run it on a
schedule, and connect it to other apps with Apify's integrations and webhooks.

### Is it legal to scrape YouTube?

This Actor reads only comments that anyone can see without logging in. The
results include commenters' names, handles, channel ids and pictures, which
are personal data protected by laws such as the GDPR. Only collect personal
data when you have a legitimate reason to, and check YouTube's terms and the
laws that apply to you. If you are unsure, ask a lawyer.

### Support

Found a problem or missing a feature? Open an issue on the **Issues** tab and
include the run's link.

***

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

# Changelog

This Actor's version history is a separate document: https://apify.com/luzivanlt/youtube-comments-scraper/changelog.md

# Actor input Schema

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

Links to YouTube videos (https://www.youtube.com/watch?v=…, youtu.be/…, Shorts, live and embed links, on www., m. or music.youtube.com, with or without https://), or 11-character video ids such as IdPutKgWVCE. Channel, playlist and search pages are not accepted. Required unless you give a dataset id or rows below. Example: https://www.youtube.com/watch?v=IdPutKgWVCE

## `datasetId` (type: `string`):

The id of a run's dataset from YouTube Scraper (streamers/youtube-scraper), so you do not copy video links by hand. Every row's url is read as a video link; rows without one, or whose own comment count is 0, are skipped and counted in the status. Reads up to 10,000 rows. Our YouTube Search and YouTube Channel Videos Actors also work. Example: your leader run's dataset id, e.g. from its Storage tab (a username~name or a dataset link works too).

## `datasetRows` (type: `array`):

Rows pasted from YouTube Scraper (streamers/youtube-scraper) results, as a JSON list, when its dataset id is not readable by your account. Each row's url is read as a video link; rows without one, or whose comment count is 0, are skipped. Reads up to 10,000 rows. Example: \[{"url": "https://www.youtube.com/watch?v=IdPutKgWVCE"}]

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

Stop reading a video after this many comments, replies included. Default 100, from 1 to 100,000. It caps what you pay: each comment or reply saved costs $0.0005 ($0.50 per 1,000), so 100 per video costs at most $0.05 a video. A whole video usually reads a little below YouTube's comment count.

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

Also save the replies to each comment, each marked with the comment it answers. On by default. Each reply is a row charged like a comment ($0.0005) and counts toward Max comments per video; turn it off to save and pay for top-level comments only.

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

Top comments first (YouTube's default), or newest first. Default top. With Max comments per video set, it decides which comments you get: the top ones or the newest ones. Example: "newest" to read the latest comments first.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=IdPutKgWVCE"
    },
    {
      "url": "https://www.youtube.com/watch?v=lFn5dqNy7uU"
    }
  ],
  "maxCommentsPerVideo": 100,
  "includeReplies": true,
  "sortBy": "top"
}
```

# Actor output Schema

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

Every comment and reply the run saved, one row each.

## `allFields` (type: `string`):

The same rows with every field.

# 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=IdPutKgWVCE"
        },
        {
            "url": "https://www.youtube.com/watch?v=lFn5dqNy7uU"
        }
    ],
    "maxCommentsPerVideo": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/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=IdPutKgWVCE" },
        { "url": "https://www.youtube.com/watch?v=lFn5dqNy7uU" },
    ],
    "maxCommentsPerVideo": 100,
}

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

```

## MCP server setup

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