What it does
When you analyse YouTube comments, the useful part is what people said, not who said it. Yet most comment exports hand you display names, channel IDs and profile pictures, which turns a sentiment dataset into a list of identifiable people you then have to manage. This actor strips those fields from every row by design.
It reads comments through the official YouTube Data API v3 with your own free API key. Each row holds the comment text, like count, reply count, published and edited dates, comment ID and video ID. Turn on includeReplies to add replies as their own rows, linked to the parent by parentId and capped by maxRepliesPerComment (default 20), so one enormous thread cannot consume the run.
It fits sentiment analysis, audience research, product feedback mining, LLM and RAG datasets and moderation reviews. Comments cost $0.50 per 1,000, and one free key covers about 1 million comments a day. If you need to know who commented, this is deliberately not the tool for that.
How it works
- Video URLs or IDs are read from
videoUrlsand comment threads are fetched withcommentThreads.list, 100 per call. - Top-level comments are capped per video by
maxCommentsPerVideo, sorted newest first or by YouTube's top comments viacommentOrder. - With
includeReplieson, up to 5 replies come with each thread call, and longer threads are fetched withcomments.listup tomaxRepliesPerComment. - Author display name, channel ID, profile image and channel URL are removed from every row before it is written to your dataset.
- Videos with comments turned off, or that are private or deleted, produce a free error row.
Input example
A typical run input (JSON). Every field is also available as a form in the Apify console.
{
"apiKey": "AIzaSy...your-own-key",
"mode": "comments",
"videoUrls": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
],
"maxCommentsPerVideo": 500,
"includeReplies": true,
"maxRepliesPerComment": 20,
"commentOrder": "relevance"
}All input fields
| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
apiKey | string | no | Required. Your own free YouTube Data API v3 key (starts with AIza). Get one in about a minute: console.cloud.google.com → create a project → APIs & Services → Library → enable "YouTube Data API v3" → Credentials →… | |
mode | string | no | "comments" | videos: details and stats for video URLs/IDs (1 quota unit per 50 videos). search: YouTube search results, enriched with full video details (100 units per page of 50). channel: channel stats plus every upload (about 2… |
videoUrls | array | no | Videos for the videos and comments modes: watch URLs, youtu.be links, Shorts, embed or live URLs, or bare 11-character IDs. Duplicates are removed. videos.list takes 50 IDs per call. | |
maxCommentsPerVideo | integer | no | 100 | Top-level comments per video (comments mode). Replies are not counted here; they are capped separately by Max replies per comment. 100 top-level comments per quota unit. |
includeReplies | boolean | no | false | Also return replies (comments mode), up to Max replies per comment per thread. Each reply is its own comment-result row, linked by parentId. |
maxRepliesPerComment | integer | no | 20 | With Include replies on: at most this many replies per top-level comment (comments mode), so one huge thread cannot eat the run. 0 = no replies. Up to 5 replies come free with the thread call; more cost 1 quota unit… |
commentOrder | string | no | "time" | time: newest first. relevance: YouTube's top comments. |
searchTerms | string | no | "" | Optional keyword filter applied by YouTube to the comments (comments mode). |
searchQueries | array | no | [] | One or more search terms (search mode). Each page of up to 50 results costs 100 of your 10,000 daily quota units, so a full key's day is about 100 pages (5,000 results). |
maxResultsPerQuery | integer | no | 50 | Search results per query (search mode). YouTube returns at most about 500 per query. Each 50 = one search page (100 quota units). |
order | string | no | "relevance" | search.list order (search mode). |
searchType | string | no | "video" | video: video rows with full details. channel: channel rows with subscriber, video and view counts (search mode). |
publishedAfter | string | no | "" | Optional date (YYYY-MM-DD). In search mode, filters results; in channel mode, only uploads on or after it (and paging stops at older videos, saving quota). |
publishedBefore | string | no | "" | Optional date (YYYY-MM-DD) for search mode. |
regionCode | string | no | "" | Optional 2-letter country code (US, GB, DE …): search results available in that country (search mode). |
relevanceLanguage | string | no | "" | Optional ISO 639-1 language code (en, es, de …): results most relevant to that language (search mode). |
videoDuration | string | no | "any" | Filter search results by duration (search mode, videos only). short < 4 min, medium 4–20 min, long > 20 min. |
channels | array | no | [] | Channel URLs (youtube.com/@handle, /channel/UC…, /user/name), @handles or channel IDs (UC…), for channel mode. Each gives one channel row plus its uploads. |
maxVideosPerChannel | integer | no | 100 | Newest uploads per channel (channel mode). 0 = channel row only. Every 50 videos cost about 2 quota units. |
includeShorts | boolean | no | true | Channel mode. The API does not flag Shorts, so this uses a heuristic (3 minutes or less, not live): turning it off also drops regular videos that short. |
Output example
Every comment and reply is one row with its text, likes and date, and replies are marked with isReply, as in this sample:
| videoId | text | likeCount | replyCount | isReply | publishedAt |
|---|---|---|---|---|---|
| jNQXAC9IVRw | We're so honored that the first ever YouTube video was filmed here! | 4869312 | 1001 | false | 2020-02-17T18:58:15Z |
| jNQXAC9IVRw | Very cool! | 71945 | true | 2020-02-17T23:30:02Z | |
| jNQXAC9IVRw | cool | 57510 | true | 2020-02-17T23:36:46Z |
Pricing
Pay per event: you are charged only for the results you receive, with no subscription. Set a maximum total charge on any run and it stops cleanly at the cap.
| Charged for | When | Price | Per 1,000 | Worked example |
|---|---|---|---|---|
| Comment result | Charged per comment or reply row delivered (author fields stripped) | $0.0005 | $0.50 | 10,000 comments = $5.00 (streamers/youtube-comments-scraper: $20) |
| Video result | Charged per video row delivered (full details and stats) | $0.0004 | $0.40 | 1,000 videos = $0.40 (streamers/youtube-scraper: $4.00 per 1,000) |
| Channel result | Charged per channel row delivered (stats, country, uploads playlist) | $0.0005 | $0.50 | 100 channels = $0.05; their videos are video-result rows |
| Search page | Charged per search page of up to 50 results that returned rows (search mode; it costs 100 of your quota units) | $0.002 | $2 | 50 search results = $0.002 + 50 × $0.0004 = $0.022 |
| Actor Start (platform start fee) | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.00005 | — | One run at 256 MB = $0.0000125 |
Prices are read from the live Apify Store listing when this page is built. The listing is always authoritative.
Try YouTube Comments Scraper (Official API) on Apify. Pay only for the results you get.
Run on Apify →Use cases
Sentiment analysis on a launch video
Export the top or newest comments on a product launch, trailer or ad and score them with your own model. Because author fields are gone, the dataset is just text, likes and timestamps.
Training and RAG datasets
Collect comment text across many videos for classification, topic modelling or retrieval experiments without storing commenter identities alongside it. Remember that @mentions typed inside a comment stay in the text.
Product feedback mining
Use searchTerms to have YouTube return only comments containing a keyword, such as a feature name or a bug, then read or cluster just those.
Moderation and community review
Pull the newest comments with commentOrder set to time on a schedule and review them in a spreadsheet, using like and reply counts to prioritise.
How it compares
| ActorForge Comments Scraper | Typical comment scrapers | Copying from youtube.com | |
|---|---|---|---|
| Commenter names and channel IDs | Stripped by design | Usually included | Visible |
| Data source | Official YouTube Data API v3 | youtube.com pages | Browser |
| Replies linked to parent comment | Yes (parentId) | Varies | Manual |
| Keyword filter on comments | Yes (searchTerms) | Varies | Browser find only |
| Pinned or hearted flags | No (not in the API) | Sometimes | Visible |
| Needs a YouTube API key | Yes (free) | No | No |
| Price per 1,000 comments | $0.50 | Varies | Free, by hand |
If your project genuinely needs to know who commented, or whether the creator pinned or hearted a comment, a scraper that keeps author fields is the better fit. This actor is for work where the text matters and the identities are a liability.
Limits and honest notes
- You need your own free YouTube Data API v3 key (see the 4-step guide above). Without one the run stops at once with instructions, and nothing is charged.
- Quota is per Google Cloud project: 10,000 units/day for free. Unit costs: videos.list, channels.list, playlistItems.list, commentThreads.list and comments.list cost 1 unit each, and search.list costs 100. A
quotaExceedederror stops the run cleanly; rows already delivered are kept, and the failed call is free. - Only public data the API returns for an API key: no private or unlisted-by-ID-only details, no dislike counts (removed by YouTube), no revenue, no watch time, and no subscriber lists. Channels that hide their subscriber count give
subscriberCount: null. - Like counts that the creator hides come back as null. Counts are YouTube's own; subscriber counts are rounded by YouTube to 3 significant figures.
- Free rows (type error) cover invalid inputs, videos and channels that are not found, private or deleted, and videos with comments disabled.
- You must refresh or delete stored API data within 30 days (YouTube Developer Policies III.E.4). We keep nothing after the run.
- The run's spend limit is respected: each page of rows is charged before it is delivered, and the run stops cleanly at the cap.
- Author identity is never returned: no display name, author channel ID, profile image or channel URL. If you need commenter lists, this is not the actor for you. The comment text itself is returned as written, so an @mention a commenter typed stays in the text.
- The API does not say whether a comment is pinned or hearted by the creator, so those fields are not in the rows. Videos with comments turned off give a free error row.
maxCommentsPerVideocounts top-level comments only. Replies are capped per comment bymaxRepliesPerComment(default 20, 0 = no replies, max 1,000). Up to 5 replies come with the thread call; more cost 1 extra quota unit per 100 replies. Every reply is its owncomment-resultrow.
FAQ
How can I export YouTube comments to CSV for sentiment analysis?
Add the video links to videoUrls, pick how many top-level comments you want with maxCommentsPerVideo, and run. The dataset can be downloaded as CSV, JSON or Excel, with one row per comment and no author fields.
Does the export include commenter usernames?
No. Display name, author channel ID, profile image and channel URL are stripped from every row. The comment text is returned as written, so an @mention someone typed stays in the text.
Are replies counted against the comment limit?
No. maxCommentsPerVideo counts top-level comments only. Replies are capped per thread by maxRepliesPerComment (default 20, 0 for none, up to 1,000), and each reply is its own billed row.
How many YouTube comments can I download per day?
Comment threads cost 1 quota unit per 100 comments, so the 10,000 free daily units on one key cover about 1 million comments. Long reply threads use 1 extra unit per 100 replies beyond the first 5.
What happens if a video has comments turned off?
You get a free error row for that video and the run continues with the others. Nothing is charged for it.
Use it from code
Run the actor through the Apify API with the input above.
cURL
curl -X POST "https://api.apify.com/v2/acts/actor-forge~youtube-comments-api/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"apiKey": "AIzaSy...your-own-key", "mode": "comments", "videoUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"], "maxCommentsPerVideo": 500, "includeReplies": true, "maxRepliesPerComment": 20, "commentOrder": "relevance"}'JavaScript (Node.js)
// Node.js 18+ (built-in fetch). Set APIFY_TOKEN in your environment.
const input = {
"apiKey": "AIzaSy...your-own-key",
"mode": "comments",
"videoUrls": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
],
"maxCommentsPerVideo": 500,
"includeReplies": true,
"maxRepliesPerComment": 20,
"commentOrder": "relevance"
};
const res = await fetch(
"https://api.apify.com/v2/acts/actor-forge~youtube-comments-api/run-sync-get-dataset-items",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify(input),
}
);
const items = await res.json();
console.log(items.length, items[0]);Python
# pip install apify-client (set APIFY_TOKEN in your environment)
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"apiKey": "AIzaSy...your-own-key",
"mode": "comments",
"videoUrls": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
],
"maxCommentsPerVideo": 500,
"includeReplies": True,
"maxRepliesPerComment": 20,
"commentOrder": "relevance"
}
run = client.actor("actor-forge/youtube-comments-api").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)The run-sync-get-dataset-items endpoint waits for the run (up to 5 minutes) and returns the dataset rows directly. For longer runs, start the run asynchronously and read the dataset when it finishes, as the Python example does. Replace APIFY_TOKEN with your own token from the Apify console.
Step-by-step guides
How to Get YouTube Data With the Official API (Free Key, No Code)
Create a free YouTube Data API v3 key in Google Cloud (no billing account), paste it into an ActorForge YouTube actor, and get video, channel…
Related actors
YouTube Scraper (Official API) — Videos, Search & Stats
Bring your own free YouTube API key. Get video details and stats (views, likes, comments, duration, tags), YouTube search results, channel uploads…
$0.40 per 1,000 · video resultYouTube Search Scraper (Official API) — Videos by Keyword
Bring your own free YouTube API key. YouTube search by keyword with sort, date, region, language and length filters — every result enriched with…
$0.30 per 1,000 · video resultYouTube Channel Scraper (Official API) — All Videos & Stats
Bring your own free YouTube API key. Get any channel's stats (subscribers, total views, video count, country) and every upload with views, likes…
$0.40 per 1,000 · video resultBilibili Video & Comment Scraper — 哔哩哔哩 Search, No Login
Scrape Bilibili (哔哩哔哩) videos without login: keyword search, video URLs/BV ids, and the popular feed. Each video comes with full stats (views…
$4 per 1,000 · video resultTry YouTube Comments Scraper (Official API) on Apify. Pay only for the results you get.
Run on Apify →