apihq/youtube-comments-scraper · YouTube

YouTube Comments Scraper

Export a YouTube video's comments and replies to JSON from a URL or video ID. One record per comment with author, likes, replies, and timestamp.

$0.0004/comment · failed items $0.0000 — on your existing Apify account, a one-item first run costs under a cent.

What does YouTube Comments Scraper do?

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.

Best for

Use it for sentiment and brand-safety analysis, audience research, moderation review, and building comment datasets for LLM pipelines. The billing matters most when the job runs unattended and one comments-off video must not take down the batch.

Use something else when

Replies are opt-in. By default it returns top-level comments only. Set includeReplies: true to fetch replies; they count toward maxComments and add extra requests.

Price
$0.40 per 1,000 comments · failed items $0
Usage on Apify
6,300+ comments delivered

Example run

input
{ "videoUrls": ["dQw4w9WgXcQ", "00000000000"], "maxComments": 5 }

outcome

  • 5 success: true comment rows from the good video — billed
  • 1 success: false row, code: VIDEO_NOT_FOUND, for the bad ID — not billed
  • Run status: SUCCEEDED
  • Charged: 5 comments = $0.002

Good input returns billed rows. Bad input returns free error rows in the same dataset, and the run still succeeds.


Why pipelines pick it

A bad video never breaks the batch

A deleted or private video, or one with comments turned off, returns a success:false row with a machine-readable code. The rest of the batch keeps going.

You pay only for comments

The charge fires per comment delivered, not per dataset write. There is no start fee, so a run that returns zero comments costs $0.

Every failure is machine-readable

Stable codes like VIDEO_NOT_FOUND and COMMENTS_DISABLED let your pipeline branch on the error type instead of parsing error text.

No YouTube Data API key or quota

The official Data API needs a Google key and rations daily quota. This actor reads public data from a plain video URL or 11-character ID.

Best for: Use it for sentiment and brand-safety analysis, audience research, moderation review, and building comment datasets for LLM pipelines. The billing matters most when the job runs unattended and one comments-off video must not take down the batch.


Input & output

input example
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "kJQP7kiw5Fk",
    "https://youtu.be/9bZkp7q19f0"
  ],
  "maxComments": 200,
  "sort": "newest",
  "includeReplies": true
}
output — success (billed)
{
  "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"
}
output — failure (free, same dataset)
{
  "success": false,
  "video_url": "00000000000",
  "code": "VIDEO_NOT_FOUND",
  "error": "Video not found or unavailable: 00000000000",
  "request_id": "req_911f37d2e55644ff9d9e4a3f",
  "status_code": 404
}

Branch on the success field to split hits from misses. Quote the request_id in any support issue and we can trace the exact request.

output fields

fieldtypewhat it is
successbooleantrue for a comment (billed), false for a video that could not be listed (free).
video_idstringThe 11-character video ID the comment belongs to. Copied onto every row so each row stands alone.
video_titlestringThe video's title.
comment_idstringThe comment's unique ID.
textstringThe comment body.
like_countstringLikes as a display string (e.g. "264K"). May be empty.
reply_countintegerNumber of replies on the comment.
published_timestringRelative publish string (e.g. "1 year ago").
reply_levelinteger0 for a top-level comment, 1+ for a reply.
parent_comment_idstringOn reply rows: the top-level comment they belong to.
is_pinnedbooleanTrue if the comment is pinned.
is_heartedbooleanTrue if the creator hearted the comment.
author_namestringAuthor display name (e.g. @handle).
author_channel_idstringThe author's UC… channel ID.
author_thumbnail_urlstringThe author's avatar URL.
author_is_verifiedbooleanTrue if the author's channel is verified.
author_is_creatorbooleanTrue if the author is the video's channel owner.
author_is_artistbooleanTrue if the author is an official artist channel.
urlstringDirect link to the comment.

Error codes, stable across releases

Every failure record carries one of these machine-readable codes. None of them are ever charged.

codebilledmeaning
VIDEO_NOT_FOUND$0.0000The video is deleted, private, or the ID does not exist.
COMMENTS_DISABLED$0.0000The video exists but has comments turned off.
VALIDATION_FAILED$0.0000The input was not a recognizable video URL or 11-character ID.
VIDEO_COMMENTS_TIMEOUT$0.0000Listing the video's comments timed out.
DEADLINE_EXCEEDED$0.0000The 30-second per-page deadline was hit. Returned as an unbilled row with status_code 504.

Every error code across the eight APIs, in one reference →


What a run costs

per comment$0.0004
per 1,000 comments$0.40
per failed item$0.0000
per-run start fee$0.0000

The charge fires only when a result is delivered, and platform compute is included in the per-result price. To cap the spend of a run, set a limit in Apify's Run Limits panel. The actor stops at the cap and reports how far it got.

How pay-per-result billing works →


What this actor doesn't do

  • Replies are opt-in. By default it returns top-level comments only. Set includeReplies: true to fetch replies; they count toward maxComments and add extra requests.
  • A comments-off video returns a success:false row with code COMMENTS_DISABLED, not an error that stops the run.
  • It reads 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.

Frequently asked questions

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, a Shorts URL, a youtu.be link, or a bare 11-character video ID, mixed freely, up to 50 unique videos per job. Unrecognizable input comes back as success:false 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 and bill at the same per-comment rate.
What if a video has comments turned off?
It comes back as a success:false record with code COMMENTS_DISABLED in the same dataset. You are not charged.
Can I sort comments?
Yes. Set sort to top (most relevant, the default) or newest (most recent first).
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.

Automation templates


Pairs with

Run it on the Apify account you already have

Paste one input into the actor's console and check the dataset it returns. A one-item first run costs under a cent — no new subscription, pay only for delivered results.

Get a video's comments