YouTube Comments Scraper — Replies & New Comment Monitor avatar

YouTube Comments Scraper — Replies & New Comment Monitor

Pricing

from $0.40 / 1,000 comments

Go to Apify Store
YouTube Comments Scraper — Replies & New Comment Monitor

YouTube Comments Scraper — Replies & New Comment Monitor

The comments of YouTube videos — or of a channel's latest videos — newest or top first, with replies, likes, pins, creator hearts, the author's channel and the video's exact comment count. Monitoring mode brings only new comments and carries a burst over to the next run. No login, no API key.

Pricing

from $0.40 / 1,000 comments

Rating

0.0

(0)

Developer

Berkan Kaplan

Berkan Kaplan

Maintained by Community

Actor stats

0

Bookmarked

15

Total users

13

Monthly active users

17 days ago

Last modified

Share

foXLabs YouTube series: Channel Email Scraper · Channel Finder · Channel Videos Scraper · Search Scraper

💬 Get the comments under YouTube videos — for the videos you name, or for a channel's latest uploads — with replies, likes, pins, creator hearts, each author's channel and the video's exact comment count. Schedule it in monitoring mode — newest first, without filters — and every run brings only what was written since: a burst of comments too large for one run is carried over to the next run, not skipped. Built for community and brand monitoring, audience research, and comment datasets for analysis and AI. No YouTube API key, no login, no cookies.

🔍 What is YouTube Comments Scraper — and when should you use it?

Give this Actor video URLs or IDs (watch, youtu.be, Shorts and live addresses) or channels — it then takes each channel's latest videos — and it returns one row per comment or reply, read live from the comment list YouTube shows to every visitor: 20 comments a request, newest first (every comment) or top first (YouTube's own selection).

Use it when you need: every comment of a video with its thread structure; the new comments under your own or a competitor's videos since the last run; the most-liked comments and the conversations under them; the comments that mention a word — a price, a bug, a brand name.

Use something else when: you need exact timestamps for old comments (YouTube shows "3 weeks ago", not a date — a row carries that text and the range of days it can mean); live-chat messages, Community-post comments, or the comments of private and members-only videos (YouTube does not show them to a visitor); or videos found by keyword — find those with YouTube Search Scraper, or list a channel's uploads with YouTube Channel Videos Scraper, and pass the URLs here.

🤖 Use with AI agents

Already on the Apify MCP server? Ask for this Actor by name: foxlabs/youtube-comments-scraper. Checked on 2026-10-08: the server lists it as the tool foxlabs--youtube-comments-scraper, and a call through it returned five comments (the run took 2.8 seconds).

Your agent can pay for its own runs. The Actor is pay-per-event only, runs with limited permissions and does not use Standby — Apify's conditions for agentic payments — and Apify Store lists it as eligible for them (read from the Store on 2026-10-08). For an agent with a wallet and no human to sign in, Apify sells a prepaid, spend-capped API token over x402 at agi.apify.com; the terms of that path are Apify's own (see apify.com/agents.md). Billing is the same either way: per delivered comment or reply; status rows are free.

Otherwise paste this into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

I want YouTube comments from the Apify Actor `foxlabs/youtube-comments-scraper`.
Input: `videos` is a list of video URLs or IDs; `channels` is a list of channel URLs or @handles (the Actor reads the comments of each channel's latest `maxVideosPerChannel` videos). `maxCommentsPerVideo` caps the rows per video and `maxComments` the rows in total. `sort` is "newest" (every comment) or "top" (YouTube's selection). `maxRepliesPerComment` adds replies. `onlyNewComments: true` with a `listName` delivers only the comments that list has not delivered before.
Start with: {"videos":["https://www.youtube.com/watch?v=e1q-TuHdc4Y"],"maxCommentsPerVideo":100}
Ask me which videos or channels, run the Actor, then summarise the comments: the main topics, the questions people ask, and the most-liked ones.

The machine-readable API, MCP config and OpenAPI definition live at apify.com/foxlabs/youtube-comments-scraper.md.

📋 Overview

Everything you need to turn YouTube comment sections into structured rows — in one Actor, with no login, cookies or API key.

Why pick this Actor:

  • 🧾 Every comment, not YouTube's selection — "Newest first" (the default) lists all of a video's comments. YouTube's "Top comments" order is a selection: for five videos read in both orders it held 19% to 99% of them. Both orders are here, and the run tells you when a list ended short of the number YouTube counts.
  • 🔁 Monitoring that carries a burst over — a named list remembers what was delivered. Newest first and without filters, each run brings a video's new comments oldest first, so what does not fit into one run is delivered by the next one instead of being skipped.
  • ↩️ Replies where you want them — as many per comment as you ask for, each with the ID of the comment it answers. A thread that showed 782 replies delivered 782.
  • 🔢 Numbers as YouTube has them — the video's comment count to the last digit (9,548, not "9.5K"), a flag where YouTube shortens a like count ("25K"), and 0 — not an empty field — for a comment nobody liked.
  • 📺 Channels as input — a channel line reads the comments of its latest videos and, when you ask for them, of its Shorts and of the entries of its Live tab (videoTypes).
  • 🗓 No invented dates — YouTube shows "3 weeks ago". A row carries that text and the range of days it can mean, and a date only where the day is certain.
  • 🧭 Never empty without a reason — comments turned off, a private or members-only video, a mistyped ID: each gets a free status row that says which.
  • 💰 Pay per row — $0.40 per 1,000 comments or replies. Status rows and comments your filters remove are free.
  • 🤖 Agent-ready — on the Apify MCP server and open to agentic payments (x402).

✨ Features

  • 🎯 Two ways in — videos (URLs or IDs, up to 10,000 lines) and channels (URLs, @handles or IDs, up to 1,000): each channel's latest maxVideosPerChannel videos of the kinds in videoTypes (videos, shorts, live).
  • 🔀 Two orders — sort: "newest" for the complete list, "top" for what YouTube's page shows first.
  • 🧵 Threads — maxRepliesPerComment puts each comment's replies right after it, oldest first, with parentCommentId.
  • 🧹 Filters — publishedWithinDays, minLikes, textContains (words or phrases, any of them). What a filter removes is not delivered and not charged.
  • 🔁 Only new — onlyNewComments with a listName: scheduled runs deliver what the list has not delivered before, and with replies on also the undelivered replies under comments you already have, while those comments are among a video's first maxCommentsPerVideo.
  • 📊 Video context on every row — title, channel, @handle and the video's comment count, so a row stands on its own in a spreadsheet.
  • 🧾 A last word in every run — the status message says what was delivered and what the run knows was not: filtered out, waiting for the next run, cut by a limit, refused by YouTube.

🎬 Quick Start

curl -X POST "https://api.apify.com/v2/acts/foxlabs~youtube-comments-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"videos":["https://www.youtube.com/watch?v=e1q-TuHdc4Y"],"maxCommentsPerVideo":100}'

The answer is the dataset itself: 100 comment rows, in about three seconds.

🚀 Getting Started (3 steps)

  1. Choose your videos — paste video addresses into Videos, or channels into Channels to read the comments of their latest uploads.
  2. Set the limits — maxCommentsPerVideo (default 100) and maxComments (default 1,000) cap the rows; add maxRepliesPerComment for replies, or switch sort to top.
  3. Run and export — download the dataset as JSON, CSV, Excel, HTML or XML. To keep watching, tick Only comments not delivered before, give the list a name and put the run on a schedule.

📥 Input

{"videos":["https://www.youtube.com/watch?v=e1q-TuHdc4Y"],"maxCommentsPerVideo":100}
FieldTypeDescription
videosarrayVideo URLs or IDs, one per line: watch?v=…, youtu.be/…, /shorts/…, /live/…, or the 11-character ID.
channelsarrayChannel URLs, @handles or channel IDs: the comments of each channel's latest videos. Give videos, channels, or both.
maxVideosPerChannelintegerFor channel lines: how many of the channel's latest videos, per kind (default 5, up to 500). Members-only videos are left out.
videoTypesarrayFor channel lines: videos, shorts, live — which of the channel's lists to take the latest from (default ["videos"]).
maxCommentsPerVideointegerRows per video — comments and replies together (default 100).
maxCommentsintegerRows in total (default 1,000). You are charged only for delivered rows.
sortstringnewest (default): every comment, latest first. top: YouTube's "Top comments" — its own selection.
maxRepliesPerCommentinteger0 (default) reads no replies. Otherwise each comment is followed by up to this many of its replies, oldest first.
publishedWithinDaysintegerOnly comments from the last N days. A comment is left out only when it is certainly older ("3 weeks ago" passes a limit of 25 days).
minLikesintegerOnly comments and replies with at least this many likes.
textContainsarrayOnly comments and replies whose text contains at least one of these words or phrases (up to 100; upper and lower case are the same; "cost" also finds "Costco").
onlyNewCommentsbooleanRemember delivered comments under listName and deliver only what is new (see Monitoring). Default off.
listNamestringName of that memory: letters, digits and hyphens, up to 40 characters (default default). One name per project.
proxyConfigurationobjectNothing to change for normal use: requests go out directly, and a kind of request YouTube refuses is moved to Apify Proxy by the Actor itself.

More recipes

  • Every comment of a video with every reply: {"videos":["https://www.youtube.com/watch?v=rN4hGxTE2hg"],"maxCommentsPerVideo":5000,"maxComments":5000,"maxRepliesPerComment":100} — 328 rows for the video in our test, the number YouTube shows for it.
  • The top comments and the conversations under them: {"videos":["https://www.youtube.com/watch?v=DHuVm_ol2mo"],"sort":"top","maxCommentsPerVideo":300,"maxRepliesPerComment":5}
  • Watch a channel's comments — schedule it: {"channels":["@mkbhd"],"maxVideosPerChannel":5,"maxCommentsPerVideo":100,"onlyNewComments":true,"listName":"mkbhd-comments"} — each run delivers only what the list has not delivered before; add "maxRepliesPerComment":5 for new replies too.
  • Comments that talk about the price: {"videos":["https://www.youtube.com/watch?v=DHuVm_ol2mo","https://www.youtube.com/watch?v=rN4hGxTE2hg"],"textContains":["price","cost","how much"],"maxCommentsPerVideo":100}
  • The last two days on a channel's three latest videos, with replies — up to 300 rows a video (the status message says when a video reached that number before the two days were through): {"channels":["@mkbhd"],"maxVideosPerChannel":3,"publishedWithinDays":2,"maxRepliesPerComment":10,"maxCommentsPerVideo":300}
  • The latest 100 comments of a channel's five latest Shorts: {"channels":["@mkbhd"],"videoTypes":["shorts"],"maxVideosPerChannel":5,"maxCommentsPerVideo":100}

📤 Output

One row per comment or reply (type: "comment" or "reply"). A line that is not a video, a video without a comment section and the like come back as a free row with type: "status" and the reason in error, so nothing disappears silently. Every row has the same 33 columns.

FieldDescription
typecomment, reply, or status
inputThe line of your input the row belongs to: the video address, or the channel whose list named the video
videoId / videoUrl / videoTitleThe video the comment stands under
videoChannelId / videoChannelTitle / videoChannelHandle / videoChannelUrlThe channel the video belongs to
videoCommentsCountThe number YouTube shows above the comments — comments and replies together, to the last digit; read when the run opens the video's comments
commentId / commentUrlThe comment's ID (the stable key; a reply's ID begins with the ID of its comment) and its own link (watch?v=…&lc=…, the form YouTube puts behind a comment's age)
parentCommentIdOn a reply: the comment it answers; null on a comment
threadPositionThe comment's place in the video's list in the order asked for (1 = first; a pinned comment is first). A reply carries the place of its comment
textThe comment as written, line breaks included
publishedTextWhat YouTube shows: "3 weeks ago", "7 hours ago" (English: the Actor asks YouTube in English)
ageDaysMin / ageDaysMaxThe range of days publishedText can mean at the time of the run: "3 weeks ago" is 21 to 27. For months and years it holds whether YouTube counts 30-day or calendar months ("1 month ago" is 28 to 61)
publishedDateOnly for a comment less than a day old whose hour lies within one UTC day; null for every older comment — YouTube shows no date for it
isEditedYouTube marks the comment "(edited)"
likes / likesAreRoundedThe like count: exact below 1,000; from 1,000 on YouTube shows "1.2K" and the row has 1200 with likesAreRounded: true. 0 when nobody liked the comment
replyCountThe number of replies YouTube shows for the comment; null on a reply (replies are one level deep)
isPinned / isHeartedPinned by the video's owner · given a heart by the video's owner
authorName / authorHandle / authorChannelId / authorChannelUrlThe comment's author as YouTube shows them
authorIsVerified / authorIsCreatorThe author's channel carries YouTube's verified badge · the author is the owner of the video
scrapedAtWhen the row was made
errornull on comment and reply rows; the reason on status rows

Sample — a row as the Actor returned it on 2026-10-07, every column, nothing shortened:

{
"type": "comment",
"input": "jjgJhYZXX1U",
"videoId": "jjgJhYZXX1U",
"videoUrl": "https://www.youtube.com/watch?v=jjgJhYZXX1U",
"videoTitle": "SkyRover X1 Drone Review",
"videoChannelId": "UCtzigO8afjz8vqvXNs_9TwA",
"videoChannelTitle": "Colibri FPV",
"videoChannelHandle": "@colibrifpv",
"videoChannelUrl": "https://www.youtube.com/channel/UCtzigO8afjz8vqvXNs_9TwA",
"videoCommentsCount": 87,
"commentId": "Ugyb2xCw4FPXOuTVLxV4AaABAg",
"commentUrl": "https://www.youtube.com/watch?v=jjgJhYZXX1U&lc=Ugyb2xCw4FPXOuTVLxV4AaABAg",
"parentCommentId": null,
"threadPosition": 34,
"text": "Wow, awesomely stunning footage and scenery. Those waterfalls... Truly amazing!!!\nNice small, lightweight photography aircraft. Looks very capable and utilitarian.",
"publishedText": "7 months ago",
"publishedDate": null,
"ageDaysMin": 208,
"ageDaysMax": 247,
"isEdited": true,
"likes": 1,
"likesAreRounded": false,
"replyCount": 1,
"isPinned": false,
"isHearted": true,
"authorName": "@MaxDelEcuador",
"authorHandle": "@MaxDelEcuador",
"authorChannelId": "UCpFT2mb4U5D_VxoC99GprUA",
"authorChannelUrl": "https://www.youtube.com/channel/UCpFT2mb4U5D_VxoC99GprUA",
"authorIsVerified": false,
"authorIsCreator": false,
"scrapedAt": "2026-10-07T22:44:18.308Z",
"error": null
}

🧠 How it works

The Actor asks YouTube for a video's comments the way its own page does when you scroll: 20 comments a request, in the order you chose. Videos are read side by side, eight at a time. Within a video's rows the order is the order of its list — a comment, then its replies. (An "only new" list that follows a video writes its comments oldest first instead: see Monitoring.) The rows of different videos are written mixed, as they arrive: sort by videoId and threadPosition to have each video's comments together.

Two orders, and they are not the same set. We read five videos to the end in both orders. "Newest first" listed 226, 924, 2,187, 3,790 and 6,563 comments; "Top comments" listed 222, 913, 660, 1,106 and 1,250 of them — every one also in the newest list. Read again the same evening from another address, the Top list of the third video held 1,076. So Top is YouTube's own selection, large for small videos and a fraction for big ones, and not the same from one reading to the next. When a list that was followed to its end holds more than 5% — and more than 20 comments — fewer than the number YouTube shows for the video, the status message says so.

The count. videoCommentsCount is the number in the header above the comments, which counts comments and replies together. For ten videos followed newest-first to the end, the comments and the replies they show added up to it: exactly for 87, 97, 328, 1,165 and 9,548 in runs on the platform and for 2,683, 4,605 and 8,007 in a probe through a proxy; 10,250 of 10,251 in one more platform run; and 119,548 of 119,554 for the largest, read through a proxy over 99 minutes while the video went on getting comments. A comment's replyCount depends on the order: read 90 seconds apart, one comment showed 248 replies in "Top comments" and 349 in "Newest first", and of 1,000 comments 25 differed, Top lower every time. The newest-first counters are the ones that add up to the video's number.

Replies. With maxRepliesPerComment above 0, each comment that has replies costs one or more extra requests (YouTube gives 10 to 50 replies a request). YouTube gives replies oldest first only, so with a limit of 5 you get a comment's first five replies. Replies count toward maxCommentsPerVideo. In the runs that read every reply, each thread delivered exactly the number of replies it showed: 61 threads of one video (the largest 14 replies) and 18 of another (the largest 782).

Dates. YouTube shows a comment's age rounded down — "3 weeks ago" is 21 to 27 days — and no date. The row keeps the text and gives ageDaysMin / ageDaysMax. A comment less than a day old gets a publishedDate when the hour YouTube names lies within one UTC day; about one in twenty-four such comments does not, because that hour holds midnight. Newest first, ages never went backwards in our runs (44,534 comments checked), which is what lets publishedWithinDays stop reading a video at the first comments that are certainly older; a pinned comment is first whatever its age.

The video's name. For a channel line the video's title and channel come from the channel's own list, at no extra request. For a video you give by its address the Actor asks YouTube's public embed answer (one small request per video) and, once per channel, which channel the @handle belongs to. A video whose owner has turned embedding off has no embed answer: its own page names it and its channel instead — two such videos in our test, one of them with comments, which came with the video's title, channel and @handle like any others.

Videos without comments. YouTube's comment answer for a video without a comment section is the same empty answer whatever the reason, so the Actor reads the video's own page to tell them apart, and the status row says which it is: the page says "Comments are turned off" (a video made for kids, an ordinary video, a stream on air and one that had not started, in our test), the video is for the channel's members only, or the video is private. The page is read for the first 25 such videos of a run; beyond that a row names the reasons there can be.

When YouTube refuses. Requests go out directly from the run's own address, and YouTube refuses the comment requests of some runs (HTTP 403): 20 of our first 100 test runs that sent requests — 18 of them at one of the run's first ten requests, two only after 380 and 385 requests. Why YouTube turns some runs away from the start is not something we could establish. The Actor then sends the run's comment requests through Apify Proxy and goes on. All 20 runs ended complete, but slower: an early refusal takes YouTube 5 to 10 seconds to send, and through the proxy a request took 0.2 to 3.2 seconds (0.5 in the median run), against 0.03 to 0.3 directly.

🔁 Monitoring: only new comments

Tick onlyNewComments, give the list a name, and put the run on a schedule. The list is kept in a key-value store of your account.

Newest first, without filters — the list follows each video.

  • The first run reads each video's first maxCommentsPerVideo comments — its first look — and delivers them oldest first. The list notes where that look ends; what lies below it is never delivered.
  • Every later run reads from the newest comment down to where the delivered ones begin and delivers what is new, oldest first. A video with nothing new costs one or two comment requests.
  • Nothing is cut off by a limit. A run delivers at most maxCommentsPerVideo rows for a video. When more are due — more new comments than that number, a first look whose comments and replies together do not fit into it, or a run that stopped at maxComments, at its spending limit or at a timeout — the run has delivered the oldest of them, and the rest are still above the delivered ones, where the next run finds them. The status message says how many are waiting: "35 new comments of 1 video wait for the next run of the list …".
  • With replies on, a comment comes with its replies, oldest first, up to maxRepliesPerComment; replies are rows and count toward maxCommentsPerVideo. Each run also looks at the video's first maxCommentsPerVideo comments again: a delivered comment whose replies were not all delivered, or whose reply count has changed, has its undelivered replies delivered — the oldest of them first, up to maxRepliesPerComment a run, so a thread longer than that number is read again in every run until it is exhausted. A reply under a comment that has moved out of those first comments is not seen.
  • A first look at more than 20,000 comments (maxCommentsPerVideo above that) is handed over as it is read, newest first, and is carried on only when one run delivers all of it: give such a run the limits and the time to finish.

Measured on the platform on 2026-10-08, on a video that was getting three to four comments a minute (builds 0.1.9 and 0.1.10, without replies): the first run delivered its 30 newest comments; a run nine minutes later found 35 new ones, delivered the 30 oldest and said 5 were waiting; the next three runs delivered those 5, then 2, then 3. A plain reading of the video's 200 newest comments right afterwards held the 70 delivered comments, none of them twice and none missing between them — and one more above them, written about when the last of those runs was made and not in YouTube's list yet at that moment: the next run's. The same list half an hour later: 127 comments were new, and with one more that was written meanwhile they came in runs of 30, 30 and 68 — 128 different comments, none twice and none missing.

With a filter, or in "top" order — every run looks at a window. Each run looks at each video's first maxCommentsPerVideo comments and delivers what the list has not delivered: a comment that passes a filter now and did not before is delivered now. A window cannot tell whether new comments fell outside it: when a video gets more comments between two runs than the window holds, the older of them are not seen, and the status message can only say so when the video filled its number. Pick a number well above what a video gets between two runs — or follow the video without filters and filter the rows afterwards.

What a list does not see.

  • YouTube's list shows a comment some time after it is written. In 20 readings of one busy video, about 40 seconds apart, the newest comment shown was between 5 seconds and more than a minute old, and twice the list stood still for over a minute before 14 and 19 comments came in at once. A comment written just before a run comes with the next run.
  • The Actor looks for new comments above the delivered ones. In those readings all 76 comments that appeared came in at the top. A comment that YouTube adds to its list late, at its own older place — one that was held back, say — is delivered only if fewer than 20 delivered comments stand above it and it is not more than about a quarter of an hour older than the list's last complete reading of the video; otherwise a run that follows the video does not find it. How often YouTube does that we have not measured.
  • A video that got more than 20,000 new comments since the list last read it: the oldest of them are not reached, and the status message says so.
  • A list keeps its newest 150,000 entries. When it lets older ones go the status message says how many.

A run that finds nothing new ends with an empty dataset and the status message "No new comments, no rows charged: …".

🧪 Data quality — measured

Measured on the Apify platform on 2026-10-07 (build 0.1.6; the row format has not changed since).

One video, its 1,000 newest commentsTen videos, 100 newest each (945 rows)One video to its end (8,047 rows)One video to its end with every reply (328 rows)
Text1,000 of 1,000945 of 9458,047 of 8,047328 of 328
Author's channel ID1,000 of 1,000945 of 9458,047 of 8,047328 of 328
Author's name and @handle1,000 of 1,000945 of 9458,046 of 8,047328 of 328
Like count1,000 of 1,000945 of 9458,047 of 8,047328 of 328
Reply count (comments)1,000 of 1,000945 of 9458,047 of 8,047226 of 226
Age in days1,000 of 1,000945 of 9458,047 of 8,047328 of 328
Date, of the comments under a day old30 of 32203 of 21030 of 32none under a day
Video title and channel1,000 of 1,000945 of 9458,047 of 8,047328 of 328
Unique comment IDs1,000 of 1,000945 of 9458,047 of 8,047328 of 328
  • Dates: the comments under a day old that got no date all read "22 hours ago" at 22:23 to 22:27 UTC — an hour that holds midnight.
  • Ten videos, 945 rows: nine videos gave 100 each; the tenth has 45 comments (its 97 on YouTube include 52 replies), and the status message said so.
  • To the end: the 8,047 comments of the third column show 1,501 replies between them — together the 9,548 YouTube displayed for the video. A larger video, read on 2026-10-08 with a like filter so that few rows were written: 8,539 comments showing 1,711 replies, 10,250 of the 10,251 YouTube counted. And the largest list we have followed to its end, the same day: a video whose oldest comment was four days old and for which YouTube counted 119,554 comments when the reading began. Read newest first with the Actor's own reader — from our own machine through Apify Proxy, not in a platform run — it gave 111,169 comments showing 8,379 replies, 119,548 together, 6 short of that count; one comment came twice. (The video went on getting comments during the reading, so at any one moment the gap may have been larger.) That took 5,571 requests, none refused or retried, and 99 minutes at the proxy's pace.
  • Zero is a value: 7,091 of those 8,047 comments had no like; each has likes: 0.
  • With every reply: 226 comments and 102 replies, 328 rows for a video YouTube shows 328 for. Every reply stood directly after its comment, and each of the 61 threads delivered the number of replies it showed. The same input with every request through Apify Proxy gave the same 328 rows in the same order.
  • A large thread: 1,000 rows of another video were 167 comments and 833 replies; its 18 threads each delivered the number shown, the largest 782.
  • Kinds of video (2026-10-08, one run of eight lines): a video with embedding turned off delivered its comments; a made-for-kids video, another with embedding off, a stream on air and a stream that had not started each got "the video's page says "Comments are turned off""; a members-only video and a private video each got a row that says so; an ID YouTube does not know got "YouTube knows no video with the ID …". A Short gives comments like any video. The three streams we saw on air showed no comment section; a stream that had ended (it was streamed in 2022) gave its comments like any video.

⏱️ Performance — measured

On the platform with the default 1,024 MB, evening of 2026-10-07.

  • 100 comments of one video (the prefilled input): 2 to 5 seconds; 10 to 15 seconds in the runs YouTube refused first.
  • 1,000 newest comments of one video: 8 to 12 seconds (53 requests); its 1,000 top comments: 16 seconds. One video's comments are paged one request after the other; a page took 0.1 to 0.2 seconds newest first and about 0.3 seconds for Top.
  • 945 comments of ten videos, read side by side: 4 to 5 seconds. 80 comments of a channel's 40 latest videos: 3 seconds.
  • A video's 8,047 comments to the end: 55 to 76 seconds in three runs. The 10,000 newest comments of a video with 659,559: 104 seconds.
  • 328 rows with every reply: 7 seconds directly (77 requests), 13 seconds with every request through the proxy, 24 seconds in a run YouTube refused after 8 seconds. 1,000 rows with a thread of 782 replies, through the proxy: 57 seconds.
  • Monitoring a busy video (2026-10-08, 256 MB, nine runs of one list): 4 to 12 seconds and 5 to 11 requests when YouTube answered directly — the more comments were new, the more requests — and 13 to 27 seconds in the two runs it refused first.
  • 49 comments that mention a price, out of 1,150 read: 7 seconds.

A run the platform restarts continues from the rows it already delivered. We restarted three test runs on purpose: they ended with 1,246, 1,500 and 3,000 different comments and no row twice. An "only new" run that was restarted with 525 rows written and none of them in its list yet took them into the list, and the list's next run delivered nothing. A run that timed out after 2,650 comments with 2,000 of them in its list was followed by a run that read the other 650 back from the dead run's dataset and delivered none of them twice.

💼 Use cases

1. Community and brand monitoring — know what is written under your videos, or a competitor's, without re-reading everything. Input: your channels with onlyNewComments on a schedule. Output: each run's new comments, oldest first, with the video they stand under. Use: a daily digest, an alert on a keyword, a support queue.

2. Audience research — what viewers ask for, praise and complain about. Input: the videos of a topic with sort: "newest" and limits high enough for every comment. Output: the full comment set with likes and reply counts to weigh it. Use: topic and sentiment analysis, FAQ mining, content planning.

3. Product and launch feedback — the comments that mention your product, price or a problem. Input: review videos with textContains: ["price", "battery", "broke"]. Output: only the matching comments (and, with maxRepliesPerComment set, the matching replies). Use: a feedback board per product, counted by word.

4. Creator workflows — what to answer first. Input: your latest videos with maxRepliesPerComment. Output: threads with isHearted, isPinned, authorIsCreator and reply counts. Use: find questions without an answer from you, and the comments worth a pin.

5. Datasets for analysis and AI agents — comments with their thread structure. Input: any list of videos. Output: one row per comment or reply with parentCommentId, author and video context. Use: training and evaluation sets, summarisation, retrieval.

🔗 Integration

JavaScript / Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('foxlabs/youtube-comments-scraper').call({"videos":["https://www.youtube.com/watch?v=e1q-TuHdc4Y"],"maxCommentsPerVideo":100});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items.filter((r) => r.type !== 'status')) console.log(row.threadPosition, row.likes, row.authorName, row.text);

Python

from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('foxlabs/youtube-comments-scraper').call(run_input={"videos": ["https://www.youtube.com/watch?v=e1q-TuHdc4Y"], "maxCommentsPerVideo": 100})
for row in client.dataset(run.default_dataset_id).iterate_items():
if row['type'] != 'status':
print(row['threadPosition'], row['likes'], row['authorName'], row['text'])

Written for apify-client 3 for Python, where call() returns a run object; with version 2 it returns a dict — write run['defaultDatasetId'] there.

Automation (n8n / Zapier / Make): schedule or webhook → run the Actor with your channels and onlyNewComments → handle the JSON dataset → push new comments to a sheet, Slack, a CRM or a dashboard.

📊 Pricing

Pay-per-event: $0.0004 per delivered comment or reply ($0.40 per 1,000 rows), plus Apify's run-start event ($0.00005 for a run with up to 1 GB of memory — the default — also for a run that delivers nothing; Apify counts this event per GB of run memory, so a run you start with more is charged more of them: we measured 256 MB and 1 GB, one event each). Current pricing.

Not charged: status rows, comments that were read but did not pass your filters, and comments an "only new" list had delivered before.

Spending limit. Set a maximum cost per run in the run options. Before every row the Actor checks that it still fits; when the next row would not, it stops delivering, keeps what it has delivered, and says so in its status message. In an "only new" run what was left comes with the next run.

❓ FAQ

Do I get all comments of a video? With sort: "newest" (the default) and limits high enough, yes — see The count above: for every video we followed to its end, the comments and the replies they show added up to the number YouTube shows: exactly for the smaller ones, to within one comment for a video of 10,251 and to within 6 for one of 119,554. One video is paged one request after the other: about 100 to 150 comments a second in our fastest runs (1,024 MB, YouTube answering directly), 40 a second in a 256 MB run that YouTube refused part-way, 19 a second through the proxy from our own machine — so a video with several hundred thousand comments does not fit into the default run timeout of one hour. "Top comments" is a selection YouTube makes; for a large video it is a fraction of the comments.

Why is there no date? YouTube shows only "3 weeks ago". The row gives that text and the range of days it can mean; a date is given only for comments less than a day old, and not for the few whose hour holds midnight. If you run the Actor every day with onlyNewComments, most new comments arrive while YouTube still shows their age in hours.

Why does likes say 25000 and not the exact number? From 1,000 likes on YouTube shows "25K". likesAreRounded tells you which counts are shortened.

Are replies included? When you set maxRepliesPerComment. They count toward maxCommentsPerVideo, and come oldest first — the only order YouTube gives them in.

What happens when a video gets more new comments than maxCommentsPerVideo between two runs? Newest first and without filters, the run delivers the oldest of them and its status message says how many are waiting; the following runs deliver the rest, oldest first. Nothing has to be re-read by hand. Raise the number to get more of them in one run. With a filter or in "top" order nothing is carried over: a run looks at the video's first maxCommentsPerVideo comments and no further (see Monitoring).

Does "only new comments" also find new replies? Yes, with maxRepliesPerComment set, for the comments within each video's first maxCommentsPerVideo: a delivered comment whose replies were not all delivered, or whose reply count has changed, is read again and its undelivered replies are delivered, the oldest first, up to maxRepliesPerComment a run. A reply under a comment that has moved out of those first comments is not seen.

Where is a list kept, and how do I start it over? In a key-value store named youtube-comments-<listName> in your Apify account. Delete that store, or use another listName, to start from nothing. A list keeps its newest 150,000 entries — one for each delivered comment and reply, one for each reply count at which a thread's replies were read to the end, and one note per video it follows.

Does it need a proxy or an API key? No API key, and nothing to set up. Requests go out directly; when YouTube refuses a run's comment requests the Actor sends them through Apify Proxy by itself. Our tests ran on an account with 30 datacenter proxy addresses (read from the account on 2026-10-08); how the switch behaves on a plan with fewer we have not measured. On an account that cannot use Apify Proxy there is nothing to switch to: a video YouTube refuses then ends as "YouTube did not answer".

Can I export to CSV / Excel / JSON? Yes — directly from the Apify dataset.

🐛 Troubleshooting

  • A status row instead of comments — the error column says why: "YouTube lists no comments for …: the video's page says "Comments are turned off"", "… is a members-only video …", "… is private …", "… has no comments yet", "YouTube knows no video with the ID …", "None of the N comments read for … passed your filters", or "… is not a YouTube video: …" for a line that is something else.
  • "N new comments of N videos wait for the next run of the list …" — an "only new" run found more new comments than it delivered. They are not lost: run the list again, or raise maxCommentsPerVideo / maxComments to get more of them in one run.
  • "YouTube's "Top comments" list held only part of the comments of N videos (…)" — Top is YouTube's selection; use sort: "newest" for every comment.
  • "YouTube counts N comments for … but listed none", or "YouTube's page shows a comment section for …, but its comment list came back empty" — YouTube answered with an empty list for a video that has comments. It is rare: in 80 readings of one busy video's first page none was empty, in 20 longer readings one was. The Actor asks such a first page once more before it believes it, and an "only new" list does not take the empty answer for a look at the video. Nothing is charged; run it again.
  • "N videos have fewer comments than maxCommentsPerVideo" — those lists ended. With "(replies are not read: maxRepliesPerComment is 0)" the rest of the video's count are replies.
  • "Stopped after reading N comments: fewer than one in a hundred passed your filters" — loosen the filters, or filter the full set yourself. "…: a run reads at most 50 comments for each row of maxComments (N), and at least 300 …" is the other limit on reading: raise maxComments.
  • "No new comments, no rows charged …" — nothing the list has not delivered before stood in the part of the videos' lists the run looked at.
  • "N videos reached maxCommentsPerVideo (…): with a filter or in "top" order a run looks at a video's first N comments …" — raise maxCommentsPerVideo to look further.
  • "N comments came without their replies, which YouTube did not give" — the comments are delivered; run again for the replies.
  • "The comments of N videos stopped answering before their end (…)" — what came is delivered; run those videos again for the rest.
  • "… another run of the list … is in progress, or was cut off in the last three minutes" — two runs of the same listName would deliver the same comments; start the second when the first has finished.
  • A run that fails at once with "listName may contain letters, digits and "-" …" or "onlyNewComments: this input looks at up to N comments in every run …" — the input was refused before any request; the message says what to change.

🚧 What it does not do

  • No exact timestamps and no dates for comments older than a day: YouTube does not show them.
  • No unrounded like counts from 1,000 on: YouTube shows "1.2K".
  • Replies come oldest first only, and are one level deep (that is how YouTube keeps them).
  • No playlists and no search as input: videos and channels.
  • No comments of members-only or private videos, no Community-post comments, no live-chat messages. An age-restricted video was not among our tests: we could not confirm one without signing in.
  • No profile pictures, and nothing about a comment's author beyond the public name and channel.
  • No translation: a comment comes in the language it was written in.
  • After a restart by the platform the lists are asked again, so threadPosition of rows written after the restart belongs to the new reading.

The Actor reads only what YouTube shows to every visitor who is not signed in: no login, no cookies, no CAPTCHA solving. Comments, author names and channel IDs are public, and they are personal data: use them for a lawful purpose under the law that applies to you (the GDPR in the EU, for instance), do not build profiles of individuals with them, and check that your use fits YouTube's terms. YouTube is a trademark of Google LLC; this Actor is not affiliated with, endorsed or sponsored by YouTube or Google.

🤝 Support & contact

Changelog

0.1.13 — 2026-10-08

  • The note "N new comments … wait for the next run" counts a video's pinned comment too while that has not been delivered; it said one too few. What a run delivers did not change.

0.1.12 — 2026-10-08

  • An "only new" list's first look at a video is carried on by the next runs when one run cannot deliver it whole (replies count as rows; a run can stop at a limit): it is delivered oldest first, and nothing of it is skipped while new comments arrive. Before, such a look was started again and could lose its older part without a word.
  • A run that delivers nothing now says "no rows charged" (it said "nothing charged"; the run-start event applies to every run). This README was corrected after an independent fact-check — the list is in the Changelog tab.

0.1.9 to 0.1.11 — 2026-10-08

  • "Only new comments" delivers a video's new comments oldest first and carries a burst over to the next run; a video without a comment section gets a status row that says why.

0.1 — 2026-10-07 — first version

  • The comments of videos, or of a channel's latest videos: newest first (every comment) or top comments (YouTube's selection), replies on request, 33 columns a row.
  • "Only new comments": a named list follows each video and delivers its new comments oldest first, so a burst larger than one run is carried over to the next runs. With a filter or in "top" order a run looks at each video's first comments instead.
  • A video without a comment section gets a status row that says why: comments turned off, members only, private.
  • Filters by age, likes and words; a spending limit that is exact; runs that continue after a restart. The full list is in the Changelog tab.