YouTube Comments Scraper
Pricing
$0.40 / 1,000 comments
YouTube Comments Scraper
Export YouTube comments and replies to JSON by video URL or ID. Comments-off or deleted videos return success:false, cost $0, and never break the batch. One record per comment with author, likes, replies, and timestamp. $0.40 per 1,000 comments.
Pricing
$0.40 / 1,000 comments
Rating
0.0
(0)
Developer
apihq
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Export a public YouTube video's comments and replies as clean JSON from a video URL or ID. No YouTube Data API key, no quota, no browser.
The contract is simple: a video with comments off never fails your run, and you only pay for comments delivered. Paste a deleted video, a bad ID, or a video with comments turned off, and it comes back as a success: false row while the rest of the batch keeps going. Pay-per-result at $0.40 per 1,000 comments. Failed videos cost $0.
See one run
Input:
{ "videoUrls": ["dQw4w9WgXcQ", "00000000000"], "maxComments": 5 }
What comes back:
- 5
success: truecomment rows from the good video, billed - 1
success: falserow,code: VIDEO_NOT_FOUND, for the bad ID, not billed - Run status: SUCCEEDED
- Charged: 5 comments = $0.002
That is the whole contract. Good input returns billed rows, bad input returns free error rows in the same dataset, and the run still succeeds so one bad video never costs you a batch.
Why this Actor
- A bad video never breaks the batch. A deleted or private video, or one with comments disabled, returns a
success: falserecord with a machine-readablecode(VIDEO_NOT_FOUND,COMMENTS_DISABLED,VALIDATION_FAILED,VIDEO_COMMENTS_TIMEOUT,DEADLINE_EXCEEDED). Branch oncodewithout parsing English. - You pay only for comments. Billing fires on an explicit per-comment event, not on dataset writes, so failure rows sit in your dataset for free. There is no per-run start fee, so a run that returns zero comments costs zero.
- No YouTube Data API key, no quota. The official YouTube Data API needs a Google key and rations a daily quota per call. This reads public data directly, so there is no Google key to provision and no daily Data API quota to ration. (You still run it with your normal Apify account, like any Actor.)
Best for
Data and AI workflows that turn video discussion into text: sentiment and brand-safety analysis, audience research, moderation and spam review, and building comment datasets for LLM pipelines. The failure-free billing and machine-readable error rows matter most when the extraction runs unattended inside a larger pipeline, where one comments-off video should never take down the batch. It works fine for one-off manual pulls too.
Input example
A single video, top comments:
{"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ","maxComments": 100,"sort": "top"}
A batch, newest first, with replies:
{"videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ","kJQP7kiw5Fk","https://youtu.be/9bZkp7q19f0"],"maxComments": 200,"sort": "newest","includeReplies": true}
videoUrl and videoUrls are merged and de-duplicated. Up to 50 unique videos run per job. Each video is walked until maxComments (which counts top-level comments and replies together).
Output example
One record per comment. The video's id is copied onto every row so each row stands alone:
{"success": true,"video_id": "dQw4w9WgXcQ","video_title": "Rick Astley - Never Gonna Give You Up (Official Video)","comment_id": "Ugzge340dBgB75hWBm54AaABAg","text": "can confirm: he never gave us up","like_count": "264K","reply_count": 961,"published_time": "1 year ago","reply_level": 0,"is_pinned": true,"is_hearted": true,"author_name": "@YouTube","author_channel_id": "UCBR8-60-B28hp2BmDPdntcQ","author_is_verified": true,"author_is_creator": false,"author_is_artist": false,"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=Ugzge340dBgB75hWBm54AaABAg"}
A video that cannot be found lands in the same dataset and is not charged:
{"success": false,"video_url": "00000000000","code": "VIDEO_NOT_FOUND","error": "Video not found or unavailable: 00000000000","request_id": "req_911f37d2e55644ff9d9e4a3f","status_code": 404}
Split hits from misses on the success field. Quote request_id in any support issue and we can trace the exact request.
What you get
Every comment is one record with success: true:
| Field | Type | What it is |
|---|---|---|
success | boolean | true for a comment (billed), false for a video that could not be listed (not billed). |
video_id | string | The 11-character video ID the comment belongs to. |
video_title | string | The video's title. |
comment_id | string | The comment's unique ID. |
text | string | The comment body. |
like_count | string | Likes as a display string (for example 264K). May be empty. |
reply_count | integer | Number of replies on the comment. |
published_time | string | Relative publish string (for example 1 year ago). |
reply_level | integer | 0 for a top-level comment, 1+ for a reply. |
parent_comment_id | string | On reply rows: the top-level comment they belong to. |
is_pinned | boolean | True if the comment is pinned. |
is_hearted | boolean | True if the creator hearted the comment. |
author_name | string | Author display name (for example @handle). |
author_channel_id | string | The author's UC... channel ID. |
author_thumbnail_url | string | The author's avatar URL. |
author_is_verified | boolean | True if the author's channel is verified. |
author_is_creator | boolean | True if the author is the video's channel owner. |
author_is_artist | boolean | True if the author is an official artist channel. |
url | string | Direct link to the comment. |
Videos that could not be listed carry success: false, video_url, a machine-readable code, a human-readable error, the service request_id, and the HTTP status_code. They are not charged.
Pricing
Pay-per-result. One charge per comment delivered: $0.0004 each, which is $0.40 per 1,000 comments. Replies (when includeReplies is on) bill at the same per-comment rate. The charge fires only after a comment row lands in your dataset.
- 1,000 delivered comments cost $0.40.
- A run that hits only comments-off or deleted videos costs $0.
- There is no per-run start fee, so an empty run is genuinely free.
Apify subscriber discounts apply automatically: roughly $0.32 per 1,000 on the Scale plan and $0.24 per 1,000 on Business. Platform compute is included in the per-comment price. Cap the maximum spend of a single run from Apify's Run Limits panel; the Actor honors the cap and stops cleanly mid-thread when the budget runs out.
What this Actor does not do
Honest scope, so you know before you run it:
- Replies are opt-in. By default it returns top-level comments only. Set
includeReplies: trueto also fetch replies; they count towardmaxCommentsand add extra requests. - Comments-off videos return no comments. A video with comments disabled comes back as a
success: falserow withcode: COMMENTS_DISABLED, not an error that stops the run. - Public videos only. Private, deleted, and members-only videos return
success:false. - It reads video comments. Community-post comments and live-chat messages are out of scope.
How to use this Actor
- Open the Actor in the Apify Console.
- Set
videoUrl(single),videoUrls(a list), or both. Each accepts a watch URL, a Shorts URL, ayoutu.belink, or a bare 11-character video ID. Up to 50 unique videos run per job. - Set
maxCommentsto cap how many comment rows to return per video,sorttotopornewest, andincludeRepliesif you want replies. - Click Start. Each comment is one
success: truerecord. Videos that cannot be listed produce onesuccess: falserecord and do not stop the run. Only comments are charged.
The Actor is also callable from the Apify API and every official integration (Make, Zapier, n8n, Slack, webhooks). The API tab in the Console has ready-to-paste JavaScript, Python, and curl snippets.
Reliability
A bad video never fails the batch. A deleted video, a mistyped ID, or a comments-off video becomes a success: false record with a specific code. The run keeps going and finishes successfully.
You never pay for a failure. Billing fires on an explicit per-comment charge event, not on dataset writes, so success: false records are free. There is no per-run start fee either.
Hard 30-second deadline per page request. Each page of comments is fetched under a 30-second deadline. If YouTube or the proxy network stalls, that video returns a 504 with code: DEADLINE_EXCEEDED as a success: false record instead of hanging your run.
FAQ
Do I need a YouTube Data API key?
No. The Actor reads YouTube's public data directly and does not consume Google API quota.
What video formats are accepted?
A watch URL (https://www.youtube.com/watch?v=...), a Shorts URL, a youtu.be link, or a bare 11-character video ID. Unrecognizable input comes back as a success: false record with code: VALIDATION_FAILED, not a rejected run.
How do I get replies?
Set includeReplies: true. Reply rows carry reply_level: 1 and parent_comment_id so you can reconstruct threads. Replies count toward maxComments.
What if a video has comments turned off?
It comes back as a success: false record with code: COMMENTS_DISABLED. You are not charged.
Can I sort comments?
Yes. Set sort to top (most relevant, the default) or newest (most recent first).
Can I also get the video's transcript or a channel's videos?
Yes, with the sibling Actors: YouTube Transcript Scraper for captions, YouTube Channel Scraper for a channel's videos, and YouTube Shorts Scraper for Shorts.
Can I use this Actor from my own code?
Yes. Use the Apify API or one of the official SDKs (Node.js: apify-client, Python: apify-client). The Console shows ready-to-paste code samples on the API tab.
How does billing know a video failed?
Billing fires on an explicit per-comment charge event, not on dataset writes. The Actor only fires it when a comment is delivered, so success: false records sit in your dataset for free. You get every result in one place and still branch on success and code, with a request_id for support correlation.
Found a bug or want a feature?
Open an issue on this Actor's Issues tab and include the request_id from any error record you saw. We respond within one business day.