# YouTube Comments Scraper – Replies, Likes, Shorts, No API Key (`nourishing_courier/youtube-comments-scraper`) Actor

YouTube Comments Scraper for videos and Shorts: comment text, author, likes, reply count, pinned and hearted flags, date, plus optional replies threaded to their parent. Top or newest first, no API key or quota. Export to CSV/Excel or feed sentiment analysis and LLMs.

- **URL**: https://apify.com/nourishing\_courier/youtube-comments-scraper.md
- **Developed by:** [Ani Björkström](https://apify.com/nourishing_courier) (community)
- **Categories:** Videos, Social media, AI
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 comment delivereds

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 – Replies, Likes, Shorts, No API Key

**YouTube Comments Scraper** that pulls every public comment from YouTube videos and **Shorts** – text, author, channel, likes, reply count, pinned and hearted flags, dates – and, if you want them, the **replies** threaded to their parent comment. Paste video URLs, get flat rows you can export to CSV or Excel, load into a database, or feed straight into sentiment analysis and LLM pipelines.

- **Comments and replies in one dataset.** Every reply is its own row with `type: "reply"` and `parentCommentId`, so threads rebuild with one join.
- **No API key, no quota.** Unlike the YouTube Data API v3 (10,000 units a day, OAuth project, key management), this YouTube comment scraper reads the same public comment feed the YouTube website loads. Nothing to set up.
- **Pay only for delivered comments.** A video with comments turned off returns one explanatory row that costs nothing.

***

### What you get

Every row the YouTube Comments Scraper writes has the same flat shape:

| Field | Description |
|---|---|
| `type` | `comment` (top-level), `reply`, or `error` (a video that returned nothing, with the reason) |
| `commentId` | YouTube's comment id (replies look like `parentId.replyId`) |
| `videoId`, `videoUrl`, `videoTitle` | The video the comment belongs to |
| `text` | Full comment text, emojis and links included |
| `author` | Display name / handle, e.g. `@YouTube` |
| `authorChannelId`, `authorChannelUrl` | Commenter's channel id and link |
| `authorAvatar` | Profile picture URL |
| `authorIsVerified` | Verified badge |
| `authorIsChannelOwner` | `true` when the video's own creator wrote it |
| `likes` | Like count as an integer (`"1.2K"` becomes `1200`) |
| `replyCount` | Number of replies under a top-level comment |
| `publishedTimeText` | YouTube's own label, e.g. `3 days ago` |
| `publishedAtApprox` | ISO 8601 UTC timestamp derived from that label – approximate by nature (YouTube only shows relative times) |
| `isEdited` | The comment was edited |
| `isPinned` | Pinned by the creator |
| `isHearted` | Hearted by the creator |
| `parentCommentId` | For replies: the comment they answer (`null` for top-level comments) |
| `position` | Order within the video (comments) or within the thread (replies) |
| `commentUrl` | Direct link that opens the video with this comment highlighted |
| `videoCommentCount` | Total comment count YouTube shows for the video |
| `scrapedAt` | ISO 8601 UTC timestamp of the run |
| `error` | Only on `type: "error"` rows – why a video returned nothing |

***

### Input

The YouTube Comments Scraper takes one field for all videos. Watch URLs, `youtu.be` short links, **Shorts URLs** (`youtube.com/shorts/...`), live URLs and bare 11-character ids all work, in any mix. With no input at all the actor scrapes 100 top comments of a well-known video, so a test or scheduled run is never empty.

**Top 500 comments of two videos**

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

**Newest comments with replies – videos and Shorts together**

```json
{
  "videoUrls": [
    "https://www.youtube.com/shorts/5mU6SRS2Bxo",
    "dQw4w9WgXcQ"
  ],
  "sortBy": "newest",
  "maxCommentsPerVideo": 200,
  "includeReplies": true,
  "maxRepliesPerComment": 50
}
```

| Option | Default | What it does |
|---|---|---|
| `videoUrls` | one demo video | Video, Shorts, live or `youtu.be` URLs, or bare ids. Duplicates are skipped. Channel and playlist URLs are not expanded |
| `maxCommentsPerVideo` | `100` | Cap on top-level comments per video (up to 100,000) |
| `sortBy` | `top` | `top` (YouTube's "Top comments") or `newest` ("Newest first"). A pinned comment is always listed first |
| `includeReplies` | `false` | Also collect replies, one row each |
| `maxRepliesPerComment` | `20` | Cap on replies per comment when replies are on |
| `concurrency` | `3` | Videos scraped in parallel (1–10) |
| `proxyConfiguration` | off | Not needed; Apify datacenter proxy can be switched on for very large volumes |

***

### Output example

A real top-level comment as the YouTube Comments Scraper returns it:

```json
{
  "type": "comment",
  "commentId": "Ugzge340dBgB75hWBm54AaABAg",
  "videoId": "dQw4w9WgXcQ",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "text": "can confirm: he never gave us up",
  "author": "@YouTube",
  "authorChannelId": "UCBR8-60-B28hp2BmDPdntcQ",
  "authorChannelUrl": "https://www.youtube.com/@YouTube",
  "authorIsVerified": true,
  "authorIsChannelOwner": false,
  "likes": 321000,
  "replyCount": 962,
  "publishedTimeText": "1 year ago",
  "publishedAtApprox": "2025-09-30T12:20:33Z",
  "isEdited": false,
  "isPinned": true,
  "isHearted": true,
  "parentCommentId": null,
  "position": 1,
  "commentUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=Ugzge340dBgB75hWBm54AaABAg",
  "videoCommentCount": 2457943,
  "scrapedAt": "2026-09-30T18:20:33Z"
}
```

A reply row has the same fields with `type: "reply"`, `replyCount: 0` and `parentCommentId` set. A video with comments turned off gives one row like `{"type": "error", "videoId": "...", "error": "Comments are turned off for this video"}`.

***

### Use cases

Who uses a YouTube Comments Scraper, and for what:

- **Sentiment analysis and brand monitoring** – marketing teams score thousands of comments on a launch video, an ad or a competitor's review and track the mood over time.
- **Creators and social media managers** – export YouTube comments to CSV or Excel, find the most-liked questions to answer, collect FAQ ideas for the next video, spot unanswered replies.
- **AI and LLM builders** – flat JSON rows are ready for RAG, topic clustering, or a "summarise what viewers think" prompt in ChatGPT or Claude; `likes` gives a natural relevance weight.
- **Market and academic researchers** – build comment corpora for discourse, misinformation or audience studies, with thread structure intact via `parentCommentId`.
- **Product teams** – mine tech-review and unboxing videos for feature requests and bug reports.
- **Agencies and influencer marketers** – measure real engagement on sponsored videos and Shorts, not just view counts.
- **Community moderators** – pull the newest comments on a schedule and flag spam or abuse downstream.

***

### Pricing

The YouTube Comments Scraper uses pay per event: you are charged once per **delivered comment or reply row**. There is no charge for `error` rows (comments turned off, private or deleted videos, bad URLs), and turning replies off means you only pay for top-level comments. See the Pricing tab for the current per-1,000 price. Platform usage is modest: about 2,400 comments and replies were collected in under a minute in testing.

***

### Integrations

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("nourishing_courier/youtube-comments-scraper").call(run_input={
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "maxCommentsPerVideo": 300,
    "includeReplies": True,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["type"], row["likes"], row["text"][:80])
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('nourishing_courier/youtube-comments-scraper').call({
    videoUrls: ['https://www.youtube.com/shorts/5mU6SRS2Bxo'],
    sortBy: 'newest',
    maxCommentsPerVideo: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'comments');
```

**curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/nourishing_courier~youtube-comments-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN&format=csv" \
  -H "Content-Type: application/json" \
  -d '{"videoUrls":["dQw4w9WgXcQ"],"maxCommentsPerVideo":100}'
```

**n8n, Make, Zapier** – add the Apify node, pick the YouTube Comments Scraper, paste an input above and send the rows to Google Sheets, Airtable, Notion, Slack or an OpenAI/Claude node for sentiment analysis. **MCP** – through the Apify MCP server an AI agent can call it as a tool ("get the top 200 comments on this video and tell me the main complaints"). Datasets download as JSON, CSV, Excel, XML or RSS.

**Pairs well with:** [YouTube Transcript Scraper](https://apify.com/nourishing_courier/youtube-transcript-scraper) for what the video says, and [YouTube Scraper](https://apify.com/nourishing_courier/youtube-scraper) for video and channel metadata – combine them for a full picture of a video and its audience.

***

### Limits and fair use

The YouTube Comments Scraper reads only public comments – the same ones any logged-out visitor sees. Comments on videos with comments turned off (including most "made for kids" videos), private videos and deleted videos cannot be read; each gets an `error` row explaining why. Age-restricted videos work: their comments load without signing in. YouTube shows only relative dates ("2 weeks ago"), so `publishedAtApprox` is an estimate whose precision matches the label; like counts above 1,000 are rounded the way YouTube displays them ("1.2K"). No proxy is needed at normal volumes; requests back off automatically on rate limits. Comments are personal data of their authors – use them in line with YouTube's Terms of Service and privacy law such as GDPR, and avoid re-identifying or profiling individuals.

***

### FAQ

#### Can I scrape YouTube comments without an API key?

Yes. This YouTube Comments Scraper needs no Google Cloud project, no API key and no OAuth. It is a practical **YouTube comments API alternative** with no daily quota.

#### How do I export YouTube comments to CSV or Excel?

Run the actor, open the Output tab and choose CSV or Excel – or use the `format=csv` API link shown above. Each comment is one flat row, so it opens cleanly in Excel or Google Sheets.

#### Does it scrape replies to comments?

Yes. Turn on `includeReplies` and the YouTube Comments Scraper fetches each thread; every reply becomes its own row with `parentCommentId`, capped by `maxRepliesPerComment`.

#### Can I scrape comments from YouTube Shorts?

Yes. Paste the Shorts URL (`youtube.com/shorts/...`) exactly as it appears; Shorts comments come out in the same format as regular video comments.

#### How many comments can I get per video?

The YouTube Comments Scraper collects up to 100,000 top-level comments per video (`maxCommentsPerVideo`), plus replies if enabled. For very popular videos YouTube keeps loading older comments page by page, and the actor follows until your cap.

#### Can I get the newest comments instead of top comments?

Yes – set `sortBy` to `newest`. It uses YouTube's own "Newest first" order, handy for monitoring a video on a schedule.

#### Is it good for sentiment analysis with an LLM?

That is a main use case for this YouTube Comments Scraper. Rows are flat and clean, with `likes` for weighting and `isHearted`/`authorIsChannelOwner` for creator signals. Send the dataset to an LLM in n8n, Make or your own code.

#### Does it work with n8n, Make and MCP?

Yes. The YouTube Comments Scraper is a standard Apify actor. Use the Apify integration in n8n or Make, or the Apify MCP server to give an AI agent the actor as a tool.

#### Why did a video return an `error` row?

Comments are turned off, the video is private or deleted, or the URL was not a video (channel and playlist URLs are not expanded). The `error` text says which, and those rows are free.

#### Are dates exact?

YouTube only exposes relative times such as "5 months ago", so `publishedAtApprox` is an approximation derived from that label; the original label is kept in `publishedTimeText`.

# Actor input Schema

## `videoUrls` (type: `array`):

Video URLs, youtu.be links, Shorts URLs (youtube.com/shorts/...), live URLs or bare 11-character video ids, one per line. Channel and playlist URLs are not expanded - paste the videos themselves.

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

Cap on top-level comments collected from each video. Replies (if turned on below) are extra and capped separately.

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

Same two orders as the YouTube comment menu. Top = most engaging first; Newest = most recent first (a pinned comment always comes first).

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

Also collect the replies under each comment. Every reply is its own row with type = reply and parentCommentId pointing at its comment. Each reply is billed like a comment.

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

Cap on replies collected under each comment when 'Include replies' is on. Ignored otherwise.

## `concurrency` (type: `integer`):

How many videos to scrape at once.

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

Optional. YouTube comments load fine without a proxy; switch on Apify datacenter proxy only if you scrape very large volumes and start seeing errors.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxCommentsPerVideo": 100,
  "sortBy": "top",
  "includeReplies": false,
  "maxRepliesPerComment": 20,
  "concurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Every comment and reply with author, likes, reply count, pinned/hearted flags and dates.

## `commentsCsv` (type: `string`):

The same records as a spreadsheet-ready CSV file.

## `consoleView` (type: `string`):

Open the run's dataset in Apify Console.

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

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

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

```

## MCP server setup

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