Pricing
from $0.99 / 1,000 results
YouTube Video Comments Scraper
Paginate top-level comments on any public YouTube video. Returns author, channelId, content, publishedTime, likeCount, replyCount.
Pricing
from $0.99 / 1,000 results
Rating
0.0
(0)
Developer
Actor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Pull top-level comments from any public YouTube video in bulk β author name, channel ID, comment text, like count, reply count, publish time, and creator-hearted flag β as a clean structured JSON dataset.
Why use this actor
- No account / no login required β just give it a YouTube video ID or URL.
- No API key needed β no YouTube Data API quota, no OAuth, no project setup.
- Bulk + paginated β fetches hundreds or thousands of top-level comments per video in a single run, all the way until the comment list is exhausted or your limit is hit.
- Flexible input β accepts raw video IDs (
dQw4w9WgXcQ) or any URL form (watch?v=,youtu.be/,shorts/,embed/). - Rich detail per comment β author display name, channel ID, verified and creator badges, text content, publish time, like count, reply count, and the creator-hearted flag.
- Status-aware β comments-disabled videos, removed videos, and bad inputs return a structured
_errorrow instead of a silent empty output, so you can triage failures. - Stable JSON output suitable for pipelines, spreadsheets, and databases β every row carries
_input,_videoId,_source,_scrapedAtenvelope fields so you can join results back to your input list.
How it works
- You provide a list of YouTube video IDs (e.g.
dQw4w9WgXcQ) or full URLs. - The actor fetches the video page, locates the comments section, then walks through every page of comments the same way YouTube's web app does.
- Each comment is flattened into a structured row and streamed into your dataset, ready to download as JSON, CSV, or Excel.
You do not need to manage scrapers, browsers, or rotating IPs β all handled internally.
Input
{"videos":["dQw4w9WgXcQ","https://www.youtube.com/watch?v=9bZkp7q19f0"],"maxComments":50,"proxyConfiguration":{"useApifyProxy":true,"apifyProxyGroups":["DATACENTER"]}}
| Field | Type | Description |
|---|---|---|
videos | array | YouTube video IDs (e.g. dQw4w9WgXcQ) or URLs in any form (watch, youtu.be, shorts, embed). Required. |
maxComments | integer | Max top-level comments to return per video. Default 50. Set to 0 for unlimited. |
proxyConfiguration | object | Apify Proxy settings. Datacenter works for most runs; switch to residential for very large jobs. |
Output
Input: dQw4w9WgXcQ, maxComments: 5
{"commentId":"Ugzge340dBgB75hWBm54AaABAg","author":"@YouTube","authorChannelId":"UCBR8-60-B28hp2BmDPdntcQ","authorIsVerified":true,"authorIsCreator":false,"content":"can confirm: he never gave us up","publishedTime":"1 year ago","likeCount":"241K","replyCount":"960","isHearted":true,"_input":"dQw4w9WgXcQ","_videoId":"dQw4w9WgXcQ","_source":"S1-primary","_scrapedAt":"2026-05-18T10:42:48.845856+00:00"}{"commentId":"UgyEnXfdC-umwvTt8JF4AaABAg","author":"@Oatman69","authorChannelId":"UCWf34D_s8K_m2vwBISIDWtg","authorIsVerified":false,"authorIsCreator":false,"content":"Gonna flag this for nudity so I can rick roll the YouTube staff","publishedTime":"6 years ago","likeCount":"551K","replyCount":"589","isHearted":true,"_input":"dQw4w9WgXcQ","_videoId":"dQw4w9WgXcQ","_source":"S1-primary","_scrapedAt":"2026-05-18T10:42:48.845856+00:00"}{"commentId":"UgxIOV-sXAchpKX94cB4AaABAg","author":"@ochkalov","authorChannelId":"UCtbyFPryy7J4DR4xh5CRCvA","authorIsVerified":false,"authorIsCreator":false,"content":"1987 : normal song\r\n2026 : national anthem of the universe","publishedTime":"6 years ago (edited)","likeCount":"128K","replyCount":"933","isHearted":true,"_input":"dQw4w9WgXcQ","_videoId":"dQw4w9WgXcQ","_source":"S1-primary","_scrapedAt":"2026-05-18T10:42:48.845856+00:00"}// ... 2 more
| Field | Type | Description |
|---|---|---|
commentId | string | YouTube's stable identifier for the comment. Use this to deduplicate across runs or build deep links. |
author | string | Author's display handle (e.g. @YouTube). |
authorChannelId | string | Author's channel ID (begins with UC). Stable across handle changes. |
authorIsVerified | boolean | true if the author's channel carries YouTube's verified checkmark. |
authorIsCreator | boolean | true if the author is the creator of the video being commented on. |
content | string | Comment text as displayed, with original line breaks preserved. |
publishedTime | string | Relative timestamp as YouTube shows it (e.g. 1 year ago, 6 years ago (edited)). |
likeCount | string | Like count as YouTube formats it (e.g. 241K, 1.2M, 403). |
replyCount | string | Number of replies under this top-level comment, as a string. |
isHearted | boolean | true if the channel creator hearted the comment. |
_input | string | The video ID or URL exactly as you supplied it. Use this to join results back to your input list. |
_videoId | string | Normalized 11-character YouTube video ID extracted from your input. |
_source | string | Internal tag for the path used to fetch the record. S1-primary is the fastest, richest path. |
_scrapedAt | string | ISO-8601 UTC timestamp when the record was scraped. |
Error envelope
Videos with comments disabled, removed videos, or invalid IDs return a structured error row instead of crashing the run:
{"_input":"https://www.youtube.com/watch?v=disabled-example","_videoId":"disabled-exa","_error":"comments_disabled_or_not_found","_source":"S1-primary","_scrapedAt":"2026-05-18T10:43:11.001234+00:00"}
Possible _error values:
| Value | Meaning |
|---|---|
invalid_input | The input string could not be parsed as a YouTube video ID or URL. |
fetch_failed | The video page could not be fetched (network / blocked / removed). See _errorDetail. |
comments_disabled_or_not_found | The video exists but has no comments section (disabled by creator, or age-restricted). |
Filter on _error to triage failed rows.
Pricing
This actor is billed per result: $3.50 per 1,000 comments (Tier 3). Each comment row in the dataset counts as one result β so the unit is 1,000 comments, not 1,000 videos. Error envelope rows are not billed.
Other Sosmed Actors
| Platform | Actor | Best for |
|---|---|---|
| YouTube | YouTube Video Detail Scraper | Title, description, views, likes, channel for any video |
| YouTube | YouTube Channel Scraper | Channel profile + uploaded video listing |
| Reddit Post Detail Scraper | Post body + comment thread for any subreddit post | |
| Bluesky | Bluesky Post Detail Scraper | Post text + reply chain on atproto |
| Instagram Post Detail Scraper | Caption, media, like and comment counters for any post | |
| Facebook Post Detail Scraper | Post body + reactions + top comments |
Browse the full catalog at apify.com/xtracto.
Notes
- Top-level comments only. Replies to comments are not expanded into separate rows β use the
replyCountfield to gauge thread depth. A dedicated replies actor is on the roadmap. replyCountis the count, not the comments. A row withreplyCount: 960means 960 replies exist under that comment; those replies are not included in the dataset.- Comments-disabled videos return a single
{"_error": "comments_disabled_or_not_found"}row. This also covers age-restricted videos that hide their comments without a sign-in. maxComments: 0means unlimited β be mindful for viral videos with millions of comments, as billing is per result.- Counts are formatted strings (
"241K","1.2M") because that is how YouTube exposes them in the comments view. Convert in your downstream pipeline if you need integers. - Default ordering is YouTube's "Top comments" ranking (relevance). Chronological / newest-first sorting is on the roadmap.
- Live-stream chats are NOT covered β live chat replays use a different data feed.
