# Youtube Comment Scraper (`dead00/youtube-comment-scraper`) Actor

Scrape YouTube comments without an API key or login. Get comment text, authors, likes, timestamps, and Super Thanks amounts in seconds. Replies included free.

- **URL**: https://apify.com/dead00/youtube-comment-scraper.md
- **Developed by:** [Dead](https://apify.com/dead00) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 comment scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 Comment Scraper

Extract comments from any public YouTube video — no login, no API key, no quota limits.

Point it at a video URL and get back structured comment data: text, author, likes, timestamps, hearted status, and Super Thanks amounts. Replies are included free.

### Why this Actor

**No YouTube API key.** The official Data API caps you at 10,000 units per day, which is roughly 100 comment requests. This Actor has no such ceiling.

**Fast by default.** 100 comments in under 10 seconds. Most scrapers walk the entire comment section before returning anything — on a video with 50,000 comments that means minutes of waiting for data you already had. This one stops as soon as it has what you asked for.

**Super Thanks amounts.** Paid comments are captured with their monetary value, so you can identify a creator's highest-value supporters. Most scrapers drop this field entirely.

**Replies at no extra charge.** You pay per top-level comment. Replies come free.

### Pricing

Pay per event: **$3.00 per 1,000 comments** returned.

You are charged only for top-level comments that land in your dataset. Replies, retries, and failed videos cost nothing. A run that finds no comments costs nothing.

| Run | Comments billed | You receive |
|---|---|---|
| 100 comments, replies off | 100 | 100 comments |
| 100 comments, 10 replies each | 100 | 100 comments + up to 1,000 replies |
| Video with comments disabled | 0 | Nothing |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | — | **Required.** YouTube video URLs. Accepts `watch?v=`, `youtu.be/`, `/shorts/`, and `/embed/` formats. |
| `maxComments` | integer | `100` | Top-level comments per video. `0` for unlimited. |
| `sortBy` | string | `recent` | `recent` (newest first) or `popular` (most liked first). |
| `includeReplies` | boolean | `false` | Fetch replies for each comment. Free, but slower. |
| `maxRepliesPerComment` | integer | `10` | Replies per comment, 1–50. Ignored when `includeReplies` is off. |
| `language` | string | `en` | Language for YouTube-generated text like relative timestamps. |
| `proxyConfiguration` | object | — | Optional Apify proxy settings. |

#### Example input

```json
{
    "startUrls": [
        { "url": "https://www.youtube.com/watch?v=ScMzIvxBSi4" }
    ],
    "maxComments": 100,
    "sortBy": "recent",
    "includeReplies": true,
    "maxRepliesPerComment": 10,
    "language": "en"
}
```

### Output

One dataset item per top-level comment.

```json
{
    "videoUrl": "https://www.youtube.com/watch?v=ScMzIvxBSi4",
    "commentId": "UgxKREWxIgDrw8w2e_Z4AaABAg",
    "text": "This is exactly what I needed, thank you!",
    "author": "@example_user",
    "authorId": "UCxxxxxxxxxxxxxxxxxxxxxx",
    "authorPhoto": "https://yt3.ggpht.com/ytc/...",
    "likes": "1.2K",
    "paidAmount": "$5.00",
    "paidCurrency": "$",
    "paidAmountValue": 5.0,
    "isSuperThanks": true,
    "replyCount": 12,
    "publishedAt": "2 days ago",
    "timeParsed": 1753804800.0,
    "isHearted": true,
    "replies": [
        {
            "commentId": "UgxKREWxIgDrw8w2e_Z4AaABAg.AbCdEfGhIjK",
            "text": "Same here!",
            "author": "@another_user",
            "authorId": "UCyyyyyyyyyyyyyyyyyyyyyy",
            "authorPhoto": "https://yt3.ggpht.com/ytc/...",
            "likes": "34",
            "paidAmount": "",
            "paidCurrency": null,
            "paidAmountValue": null,
            "isSuperThanks": false,
            "publishedAt": "1 day ago",
            "timeParsed": 1753891200.0,
            "isHearted": false
        }
    ]
}
```

#### Field notes

**`likes`** is YouTube's display string, not a number — `"1.2K"`, `"15K"`, `"0"`. Parse it yourself if you need arithmetic.

**`publishedAt`** is relative (`"2 days ago"`), because that is all YouTube exposes. Use **`timeParsed`** for a Unix timestamp resolved at scrape time.

**`paidAmount`** is the Super Thanks value as YouTube rendered it, including currency symbol and locale formatting. `paidAmountValue` and `paidCurrency` are best-effort parses of it — for locales that use a comma as the decimal separator, trust `paidAmount` and parse it yourself.

**`replies`** is only present when `includeReplies` is enabled. When replies are off the key is omitted entirely, rather than set to an empty array, so an empty list always means "this comment genuinely has no replies" and never "we didn't look."

**`replyCount`** is YouTube's own count and can exceed the number of items in `replies`. Two reasons: your `maxRepliesPerComment` cap, or YouTube counting replies that were deleted or held for review. A comment showing `replyCount: 2` with an empty `replies` array is normal, not an error.

### Performance

| Configuration | Approximate time |
|---|---|
| 100 comments, replies off | 5–8 seconds |
| 100 comments, replies on | 5–8 seconds |
| 1,000 comments, replies off | 45–60 seconds |

Comments arrive 20 per request, so 100 comments is five sequential round-trips no matter what. Replies are the expensive part: each thread needs its own request, which is why `includeReplies` defaults to off.

### Limitations

- **Public videos only.** Private, unlisted, age-restricted, and members-only videos are not accessible.
- **Comments must be enabled.** Videos with comments turned off return nothing and are not charged.
- **Approximate ordering.** `popular` and `recent` reflect YouTube's own sorting, which is not strictly deterministic between runs.
- **No comment editing history**, and no access to comments hidden by the creator or held for review.
- **Live chat is not comments.** Live stream chat replay is a separate system and is not supported.

### FAQ

**Do I need a YouTube API key?**
No. Nothing to configure, no quota to manage.

**Am I charged for replies?**
No. You pay per top-level comment; replies are included at no cost.

**Why did I get fewer comments than I asked for?**
The video has fewer comments than your `maxComments` value, or your run's spending limit was reached. Check the log — it reports exactly how many were returned per video.

**Can I scrape multiple videos in one run?**
Yes. Add as many URLs to `startUrls` as you like. Each is scraped up to `maxComments` independently.

**Do I need a proxy?**
Not usually. If you are running large jobs continuously and start seeing failures, enable Apify Proxy in the input.

**Does it work on YouTube Shorts?**
Yes. Shorts URLs are recognised and handled like any other video.

### Support

Found a bug or need a field that isn't here? Open an issue on the Actor's Issues tab.

# Actor input Schema

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

List of YouTube video URLs to scrape comments from.

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

Maximum number of top-level comments to scrape per video. Set to 0 for unlimited (slow on videos with many comments). You are charged per comment returned; replies are included free.

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

Sort comments by popularity or recency.

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

Fetch replies for each top-level comment. Replies are free, but each reply thread costs an extra request, so runs take noticeably longer. Leave this off unless you need reply text.

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

Maximum number of replies to fetch per top-level comment (1-50). Ignored when Include Replies is off.

## `publishedAfter` (type: `string`):

Only return comments newer than this. Switch between an absolute date (2026-01-15) and a relative span (7 days, 3 months). Leave empty for no filter. Note: YouTube only exposes approximate ages like '3 months ago', so filtering is accurate to within roughly a month for older comments. Works best with 'Most Recent' sorting, which lets the run stop early instead of scanning the whole video.

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

Locale for YouTube's own generated text — the relative timestamps ('2 days ago' vs 'vor 2 Tagen') and like counts. It does NOT translate comments, and does not change which comments are returned. Leave as 'en' unless you specifically need localised timestamps: other locales can make timestamps harder to parse and may reduce the accuracy of the date filter.

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

Optional Apify proxy configuration to avoid rate limiting.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=ScMzIvxBSi4"
    }
  ],
  "maxComments": 100,
  "sortBy": "recent",
  "includeReplies": false,
  "maxRepliesPerComment": 10,
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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=ScMzIvxBSi4"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dead00/youtube-comment-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=ScMzIvxBSi4" }],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dead00/youtube-comment-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=ScMzIvxBSi4"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dead00/youtube-comment-scraper --silent --output-dataset

```

## MCP server setup

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