# YouTube Video Comments Scraper (`xtracto/youtube-video-comments-scraper`) Actor

Paginate top-level comments on any public YouTube video. Returns author, channelId, content, publishedTime, likeCount, replyCount.

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

## Pricing

from $0.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## YouTube Video Comments Scraper

Pull top-level comments from any public YouTube video in bulk — author name, channel ID, comment text, like count, reply count, publish time, and creator-hearted flag — as a clean structured JSON dataset.

### Why use this actor

- **No account / no login required** — just give it a YouTube video ID or URL.
- **No API key needed** — no YouTube Data API quota, no OAuth, no project setup.
- **Bulk + paginated** — fetches hundreds or thousands of top-level comments per video in a single run, all the way until the comment list is exhausted or your limit is hit.
- **Flexible input** — accepts raw video IDs (`dQw4w9WgXcQ`) or any URL form (`watch?v=`, `youtu.be/`, `shorts/`, `embed/`).
- **Rich detail per comment** — author display name, channel ID, verified and creator badges, text content, publish time, like count, reply count, and the creator-hearted flag.
- **Status-aware** — comments-disabled videos, removed videos, and bad inputs return a structured `_error` row instead of a silent empty output, so you can triage failures.
- **Stable JSON output** suitable for pipelines, spreadsheets, and databases — every row carries `_input`, `_videoId`, `_source`, `_scrapedAt` envelope fields so you can join results back to your input list.

### How it works

1. You provide a list of YouTube video IDs (e.g. `dQw4w9WgXcQ`) or full URLs.
2. The actor fetches the video page, locates the comments section, then walks through every page of comments the same way YouTube's web app does.
3. Each comment is flattened into a structured row and streamed into your dataset, ready to download as JSON, CSV, or Excel.

You do not need to manage scrapers, browsers, or rotating IPs — all handled internally.

### Input

```json
{
  "videos": [
    "dQw4w9WgXcQ",
    "https://www.youtube.com/watch?v=9bZkp7q19f0"
  ],
  "maxComments": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["DATACENTER"]
  }
}
````

| Field | Type | Description |
|---|---|---|
| `videos` | array | YouTube video IDs (e.g. `dQw4w9WgXcQ`) or URLs in any form (`watch`, `youtu.be`, `shorts`, `embed`). Required. |
| `maxComments` | integer | Max top-level comments to return per video. Default `50`. Set to `0` for unlimited. |
| `proxyConfiguration` | object | Apify Proxy settings. Datacenter works for most runs; switch to residential for very large jobs. |

### Output

Input: `dQw4w9WgXcQ`, `maxComments: 5`

```json
{
  "commentId": "Ugzge340dBgB75hWBm54AaABAg",
  "author": "@YouTube",
  "authorChannelId": "UCBR8-60-B28hp2BmDPdntcQ",
  "authorIsVerified": true,
  "authorIsCreator": false,
  "content": "can confirm: he never gave us up",
  "publishedTime": "1 year ago",
  "likeCount": "241K",
  "replyCount": "960",
  "isHearted": true,
  "_input": "dQw4w9WgXcQ",
  "_videoId": "dQw4w9WgXcQ",
  "_source": "S1-primary",
  "_scrapedAt": "2026-05-18T10:42:48.845856+00:00"
}
{
  "commentId": "UgyEnXfdC-umwvTt8JF4AaABAg",
  "author": "@Oatman69",
  "authorChannelId": "UCWf34D_s8K_m2vwBISIDWtg",
  "authorIsVerified": false,
  "authorIsCreator": false,
  "content": "Gonna flag this for nudity so I can rick roll the YouTube staff",
  "publishedTime": "6 years ago",
  "likeCount": "551K",
  "replyCount": "589",
  "isHearted": true,
  "_input": "dQw4w9WgXcQ",
  "_videoId": "dQw4w9WgXcQ",
  "_source": "S1-primary",
  "_scrapedAt": "2026-05-18T10:42:48.845856+00:00"
}
{
  "commentId": "UgxIOV-sXAchpKX94cB4AaABAg",
  "author": "@ochkalov",
  "authorChannelId": "UCtbyFPryy7J4DR4xh5CRCvA",
  "authorIsVerified": false,
  "authorIsCreator": false,
  "content": "1987 : normal song\r\n2026 : national anthem of the universe",
  "publishedTime": "6 years ago (edited)",
  "likeCount": "128K",
  "replyCount": "933",
  "isHearted": true,
  "_input": "dQw4w9WgXcQ",
  "_videoId": "dQw4w9WgXcQ",
  "_source": "S1-primary",
  "_scrapedAt": "2026-05-18T10:42:48.845856+00:00"
}
// ... 2 more
```

| Field | Type | Description |
|---|---|---|
| `commentId` | string | YouTube's stable identifier for the comment. Use this to deduplicate across runs or build deep links. |
| `author` | string | Author's display handle (e.g. `@YouTube`). |
| `authorChannelId` | string | Author's channel ID (begins with `UC`). Stable across handle changes. |
| `authorIsVerified` | boolean | `true` if the author's channel carries YouTube's verified checkmark. |
| `authorIsCreator` | boolean | `true` if the author is the creator of the video being commented on. |
| `content` | string | Comment text as displayed, with original line breaks preserved. |
| `publishedTime` | string | Relative timestamp as YouTube shows it (e.g. `1 year ago`, `6 years ago (edited)`). |
| `likeCount` | string | Like count as YouTube formats it (e.g. `241K`, `1.2M`, `403`). |
| `replyCount` | string | Number of replies under this top-level comment, as a string. |
| `isHearted` | boolean | `true` if the channel creator hearted the comment. |
| `_input` | string | The video ID or URL exactly as you supplied it. Use this to join results back to your input list. |
| `_videoId` | string | Normalized 11-character YouTube video ID extracted from your input. |
| `_source` | string | Internal tag for the path used to fetch the record. `S1-primary` is the fastest, richest path. |
| `_scrapedAt` | string | ISO-8601 UTC timestamp when the record was scraped. |

#### Error envelope

Videos with comments disabled, removed videos, or invalid IDs return a structured error row instead of crashing the run:

```json
{
  "_input": "https://www.youtube.com/watch?v=disabled-example",
  "_videoId": "disabled-exa",
  "_error": "comments_disabled_or_not_found",
  "_source": "S1-primary",
  "_scrapedAt": "2026-05-18T10:43:11.001234+00:00"
}
```

Possible `_error` values:

| Value | Meaning |
|---|---|
| `invalid_input` | The input string could not be parsed as a YouTube video ID or URL. |
| `fetch_failed` | The video page could not be fetched (network / blocked / removed). See `_errorDetail`. |
| `comments_disabled_or_not_found` | The video exists but has no comments section (disabled by creator, or age-restricted). |

Filter on `_error` to triage failed rows.

### Pricing

This actor is billed per result: **$3.50 per 1,000 comments** (Tier 3). Each comment row in the dataset counts as one result — so the unit is *1,000 comments*, not *1,000 videos*. Error envelope rows are not billed.

### Other Sosmed Actors

| Platform | Actor | Best for |
|---|---|---|
| YouTube | [YouTube Video Detail Scraper](https://apify.com/xtracto/youtube-video-detail-scraper) | Title, description, views, likes, channel for any video |
| YouTube | [YouTube Channel Scraper](https://apify.com/xtracto/youtube-channel-scraper) | Channel profile + uploaded video listing |
| Reddit | [Reddit Post Detail Scraper](https://apify.com/xtracto/reddit-post-detail-scraper) | Post body + comment thread for any subreddit post |
| Bluesky | [Bluesky Post Detail Scraper](https://apify.com/xtracto/bluesky-post-detail-scraper) | Post text + reply chain on atproto |
| Instagram | [Instagram Post Detail Scraper](https://apify.com/xtracto/instagram-post-detail-scraper) | Caption, media, like and comment counters for any post |
| Facebook | [Facebook Post Detail Scraper](https://apify.com/xtracto/facebook-post-detail) | Post body + reactions + top comments |

Browse the full catalog at [apify.com/xtracto](https://apify.com/xtracto).

### Notes

- **Top-level comments only.** Replies to comments are not expanded into separate rows — use the `replyCount` field to gauge thread depth. A dedicated replies actor is on the roadmap.
- **`replyCount` is the count, not the comments.** A row with `replyCount: 960` means 960 replies exist under that comment; those replies are not included in the dataset.
- **Comments-disabled videos** return a single `{"_error": "comments_disabled_or_not_found"}` row. This also covers age-restricted videos that hide their comments without a sign-in.
- **`maxComments: 0` means unlimited** — be mindful for viral videos with millions of comments, as billing is per result.
- **Counts are formatted strings** (`"241K"`, `"1.2M"`) because that is how YouTube exposes them in the comments view. Convert in your downstream pipeline if you need integers.
- **Default ordering is YouTube's "Top comments"** ranking (relevance). Chronological / newest-first sorting is on the roadmap.
- **Live-stream chats are NOT covered** — live chat replays use a different data feed.

# Actor input Schema

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

List of YouTube video IDs (e.g. dQw4w9WgXcQ) or URLs in any form (watch, youtu.be, shorts, embed). One row per comment will be written to the dataset.

## `maxComments` (type: `integer`):

Maximum number of top-level comments to return per video. Set to 0 for unlimited (use with care on viral videos with millions of comments).

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

Apify Proxy settings. Datacenter proxy is sufficient for most runs; switch to residential for large jobs (>10k comments) to spread the load across more IPs.

## Actor input object example

```json
{
  "videos": [
    "dQw4w9WgXcQ",
    "https://www.youtube.com/watch?v=9bZkp7q19f0"
  ],
  "maxComments": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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": [
        "dQw4w9WgXcQ",
        "https://www.youtube.com/watch?v=9bZkp7q19f0"
    ],
    "maxComments": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("xtracto/youtube-video-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": [
        "dQw4w9WgXcQ",
        "https://www.youtube.com/watch?v=9bZkp7q19f0",
    ],
    "maxComments": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("xtracto/youtube-video-comments-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "dQw4w9WgXcQ",
    "https://www.youtube.com/watch?v=9bZkp7q19f0"
  ],
  "maxComments": 50
}' |
apify call xtracto/youtube-video-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=xtracto/youtube-video-comments-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Video Comments Scraper",
        "description": "Paginate top-level comments on any public YouTube video. Returns author, channelId, content, publishedTime, likeCount, replyCount.",
        "version": "1.0",
        "x-build-id": "UfjzSxgJ3MG1esJKm"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/xtracto~youtube-video-comments-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-xtracto-youtube-video-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/xtracto~youtube-video-comments-scraper/runs": {
            "post": {
                "operationId": "runs-sync-xtracto-youtube-video-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/xtracto~youtube-video-comments-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-xtracto-youtube-video-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "videos"
                ],
                "properties": {
                    "videos": {
                        "title": "YouTube video IDs or URLs",
                        "type": "array",
                        "description": "List of YouTube video IDs (e.g. dQw4w9WgXcQ) or URLs in any form (watch, youtu.be, shorts, embed). One row per comment will be written to the dataset.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxComments": {
                        "title": "Max comments per video",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of top-level comments to return per video. Set to 0 for unlimited (use with care on viral videos with millions of comments).",
                        "default": 50
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy settings. Datacenter proxy is sufficient for most runs; switch to residential for large jobs (>10k comments) to spread the load across more IPs.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
