# YouTube Comments Scraper: Videos, Channels & Replies (`t3data/youtube-comments`) Actor

Scrape YouTube comments and replies from videos, Shorts, playlists or whole channels. Top or newest first, likes, reply counts, pinned and creator-hearted flags. Pay only for comments you get.

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

## Pricing

from $0.70 / 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: Videos, Channels & Replies

Scrape **YouTube comments and replies** with no API key and no quota. It works on single videos, Shorts, playlists or whole channels, with likes, reply counts, author, approximate date, and **pinned** and **hearted-by-creator** flags. **You only pay for comments you get**: videos with comments turned off are free.

| | |
|---|---|
| 💲 **Price** | $1 per 1,000 comments (a reply counts as one comment). Failed videos are free. |
| ⚡ **Speed** | ~900 comments in 30 seconds, with replies loaded in parallel |
| 📥 **Input** | Video URLs or IDs, Shorts, live replays, playlists, channels (`@handle`) |
| 📤 **Output** | One row per comment or reply: text, author, likes, replies, date, flags, direct link |
| 🔀 **Sort** | Top comments or newest first, like YouTube's menu |

### What people use it for

- **Audience research**: what viewers love, hate and ask for, on your channel or a competitor's
- **Sentiment and AI analysis**: feed thousands of comments to an LLM, a sentiment model or topic clustering
- **Product feedback**: mine review and unboxing videos for complaints and feature requests
- **Content ideas**: the top questions in comments make the best next videos
- **Brand and influencer monitoring**: see how audiences react to sponsored segments
- **Giveaways and community**: export every commenter on a video

### How to use it

1. Paste one or more YouTube URLs (videos, playlists or channels).
2. Set **Max comments per video**, pick **Top** or **Newest first**, and optionally include replies.
3. Click **Start**, then download the results as JSON, CSV or Excel, or fetch them through the API.

### For AI agents and automations

- **One job:** get the comments (and optionally replies) of YouTube videos, playlists or channels. Minimal input: `{ "urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"], "maxCommentsPerVideo": 100 }`
- **Fast enough for a single tool call:** 100 comments on one video finish in under 10 seconds; ~900 in ~30 seconds, which fits inside the Apify MCP server's default 30-second wait. For big jobs, start the run asynchronously and read the dataset when it finishes.
- **Where the results are:** dataset items (fields below). A **run summary** is in the key-value store record `OUTPUT`: `status` (`SUCCEEDED`, `PARTIAL`, `STOPPED_AT_SPEND_LIMIT`, `ABORTED`, `NO_RESULTS`, `SOURCE_UNAVAILABLE`), `results`, `errorsByCode` and a plain-English `message`.
- **Predictable billing:** pay per event. Only successful comments are charged; error rows are free.
- **Respects "Max cost per run":** it never starts work your budget can't pay for, then stops cleanly with status `STOPPED_AT_SPEND_LIMIT`. Everything fetched up to that point is kept.
- **Graceful on abort and restarts:** partial results are always kept, and a platform restart resumes without duplicates or double charges.
- **Honest failures:** if the source blocks every request or changes its format, the run fails with a clear message and you pay $0, instead of quietly returning empty results.
- Works with the **Apify MCP server** (Claude, Cursor, other agents), agentic payments, and the API.

### Input examples

The top 500 comments on one video:

```json
{ "urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"], "maxCommentsPerVideo": 500 }
```

The newest comments on a channel's last 10 videos:

```json
{ "urls": ["https://www.youtube.com/@mkbhd"], "maxVideosPerPlaylist": 10, "maxCommentsPerVideo": 200, "sortBy": "newest" }
```

Comments with up to 20 replies each:

```json
{ "urls": ["https://youtu.be/QVv3mQzlrN0"], "maxCommentsPerVideo": 300, "includeReplies": true, "maxRepliesPerComment": 20 }
```

### Output

One item per comment or reply. From a real run:

```json
{
  "type": "comment",
  "commentId": "Ugxzbv_ZeZXNRcfwsSF4AaABAg",
  "parentCommentId": null,
  "videoId": "dQw4w9WgXcQ",
  "videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "commentUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=Ugxzbv_ZeZXNRcfwsSF4AaABAg",
  "text": "Is everyone going to ignore the fact that Rick Astley looks like a twelve year old boy but has a uniquely deep voice?",
  "author": "@candycake9531",
  "authorChannelId": "UCNLgzvqrGzFi5SEAbVkFchg",
  "authorChannelUrl": "https://www.youtube.com/@candycake9531",
  "authorIsChannelOwner": false,
  "authorIsVerified": false,
  "likeCount": 291000,
  "likeCountText": "291K",
  "replyCount": 679,
  "publishedTimeText": "6 years ago",
  "publishedAtApprox": "2020-10-15T13:04:48.000Z",
  "isEdited": false,
  "isPinned": false,
  "isHeartedByCreator": false,
  "sortedBy": "top",
  "videoCommentCountText": "2,459,435"
}
```

| Field | Meaning |
|---|---|
| `type` | `comment`, `reply`, or `error` (free) |
| `parentCommentId` | For replies, the comment they answer |
| `text`, `author`, `authorChannelUrl` | The comment and who wrote it |
| `likeCount` / `likeCountText` | Number (converted from YouTube's rounded "291K") and the original text |
| `replyCount` | Replies under the comment |
| `publishedTimeText` / `publishedAtApprox` | YouTube's relative time, and an estimated ISO date |
| `isPinned`, `isHeartedByCreator`, `authorIsChannelOwner`, `authorIsVerified`, `isEdited` | Flags |
| `commentUrl` | Direct link that opens the comment on YouTube |
| `videoTitle`, `videoCommentCountText` | Video context |

### Cost examples

| Job | Comments | Cost |
|---|---|---|
| Top 100 comments on 10 videos | 1,000 | $1.00 |
| 300 comments + up to 5 replies each, 20 videos | ~15,000 | ~$15 |
| Every comment on a 50k-comment video | 50,000 | $50 |

Set **Max cost per run** to cap any run, and the actor stops cleanly at the limit.

### Integrations

- **API**: `client.actor("t3data/youtube-comments").call({ urls: [...] })` (JS), or `client.actor("t3data/youtube-comments").call(run_input={"urls": [...]})` (Python). Full snippets are on the **API** tab.
- **AI agents (MCP)**: available as a tool through the Apify MCP server.
- **n8n node**: install `n8n-nodes-t3data-youtube-comments` (n8n → Settings → Community Nodes → Install) for a ready-made node with all the options above, also usable as an AI Agent tool. [npm package](https://www.npmjs.com/package/n8n-nodes-t3data-youtube-comments)
- **No-code**: Make, Zapier, Google Sheets, Slack and webhooks, through Apify integrations.
- **Export**: JSON, CSV, Excel, XML, HTML or RSS.

### Error codes (never charged)

| Code | Meaning |
|---|---|
| `COMMENTS_DISABLED` | Comments are turned off (common on kids' videos) |
| `NO_COMMENTS` | Nobody has commented yet |
| `VIDEO_UNAVAILABLE` | Private, deleted or unavailable |
| `INVALID_URL` | Not a YouTube video, playlist or channel link |
| `PLAYLIST_NOT_FOUND` / `CHANNEL_NOT_FOUND` | The playlist is private, or the channel handle doesn't exist |
| `SOURCE_UNAVAILABLE` (run status) | Every request was blocked, or the source changed its format. The run fails with $0 charged; retry later |
| `BLOCKED` | YouTube kept refusing after every retry (rare; try again) |

### FAQ

**Are like counts exact?** YouTube shows rounded numbers for large counts ("291K"). `likeCount` converts them to a number, and `likeCountText` keeps the original.

**Are dates exact?** YouTube only says "3 weeks ago". `publishedAtApprox` turns that into a date, which is accurate to within that unit (about a week for "weeks ago", a year for "years ago").

**Can I get every comment on a huge video?** Yes. Set `maxCommentsPerVideo` high. YouTube serves comments 20 at a time in order, so very large videos take a few minutes. Cap your spend with **Max cost per run**.

**Do I need a proxy or a YouTube API key?** No. A residential proxy and IP rotation are built in, and their cost is included in the price.

**Is it legal?** It reads only publicly visible comments. Comments can contain personal data such as usernames, so handle the data according to the privacy rules that apply to you (e.g. GDPR).

**Something broke?** Open an issue on the **Issues** tab with the video URL. Fixes usually ship within a day.

### Limits

- Exact timestamps aren't available from YouTube, only relative times (see `publishedAtApprox`).
- Comments on private, members-only or age-restricted videos aren't supported.
- Very large videos are limited by YouTube's 20-per-page delivery, so they take time but do finish.

### More from T3 Data

- [YouTube Transcripts](https://apify.com/t3data/youtube-transcripts): full transcripts, SRT and AI-ready chunks for videos, playlists and channels
- [YouTube Channel & Shorts Scraper](https://apify.com/t3data/youtube-channel): channel info plus every video and Short with exact views, likes and dates
- [Google News Scraper](https://apify.com/t3data/google-news): news by keyword, topic or location, with real article URLs and full text
- [Google Ads Transparency Scraper](https://apify.com/t3data/google-ads-transparency): every ad an advertiser or domain runs on Google, with dates, images and YouTube videos
- [Google Trends Scraper](https://apify.com/t3data/google-trends): interest over time, by region, related queries, and trending now
- [Google Hotels Scraper](https://apify.com/t3data/google-hotels): hotel prices, ratings and booking-site prices for any city and dates

***

*This Actor is an independent tool. It is not affiliated with, endorsed by, or sponsored by YouTube or Google. It only accesses publicly visible comments.*

# Actor input Schema

## `urls` (type: `array`):

Video URLs (watch, youtu.be, Shorts, live), plain video IDs, playlist URLs, or channel URLs (@handle, /channel/UC…). Playlists and channels are expanded to their most recent videos.

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

Top-level comments to collect per video (replies are counted separately).

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

Same as the sort menu on YouTube.

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

Also collect replies under each comment. Each reply is one result.

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

Only used when replies are included.

## `maxVideosPerPlaylist` (type: `integer`):

For channels, the most recent uploads are taken first.

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

How many videos to process at the same time.

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

Residential proxy is strongly recommended — YouTube blocks datacenter IPs. Proxy cost is included in the price.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "maxCommentsPerVideo": 100,
  "sortBy": "top",
  "includeReplies": false,
  "maxRepliesPerComment": 20,
  "maxVideosPerPlaylist": 20,
  "maxConcurrency": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One item per comment or reply, plus free error rows for videos without comments.

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

One JSON object: status (SUCCEEDED, PARTIAL, STOPPED_AT_SPEND_LIMIT, ABORTED, NO_RESULTS, SOURCE_UNAVAILABLE), results count, failed inputs by error code, and a plain-English message.

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

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

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

```

## MCP server setup

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

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/rZazC8ICxaNUSPMEM/builds/5INcjwJRmwEXe9Vc8/openapi.json
