YouTube Comments Scraper
Give it YouTube video or Shorts links and it returns one JSON row per comment: text, likes, reply count, date, pinned, creator-heart and by-creator flags, with the video title and channel. Replies are optional and come right after their comment. $1.80 per 1,000 comments; you pay only for rows you get.
$1.80 per 1,000 comments on the Free plan, down to $0.81 on higher plans
Why this actor
- Top or newest order, a date cut-off, a cap per video and per run.
- Input names of the leading comment actors are accepted (
startUrls,maxComments,sortCommentsBy,oldestCommentDate,sort,includeReplies,maxItems). - Videos with comments turned off, private or missing videos come back as free error rows that say why.
- No personal data: comment authors' names, handles and channels are never collected, and @mentions in the text are replaced.
What you get
| Field | What it holds |
|---|---|
commentId, commentUrl | Stable comment id and a link that opens the video at this comment. |
text | The comment. Emails, phones, profile links and @mentions are replaced. |
likeCount | Likes, rounded by YouTube above 1,000. |
replyCount | Replies to a top-level comment. |
publishedText, publishDate | "3 weeks ago" and the approximate date it means. |
isReply, parentCommentId | Replies point at their comment. |
isPinned, isHearted, isByChannelOwner, isAuthorVerified | Creator signals. |
position | Rank of the comment in the chosen order. |
videoId, videoTitle, channelName, channelId, videoCommentCountText | The video and its channel. |
Sample row (from the README example; long text shortened, lists cut to two items):
{
"rowType": "comment",
"platform": "youtube",
"commentId": "UgzKYksqeQ5gA3t0g0F4AaABAg",
"commentUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=UgzKYksqeQ5gA3t0g0F4AaABAg",
"videoId": "dQw4w9WgXcQ",
"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
"channelName": "Rick Astley",
"channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
"videoCommentCountText": "2.4M",
"text": "I Rick rolled my entire French class with a fake quiz link.",
"publishedText": "6 years ago",
"publishDate": "2020-11-01",
"publishDateIsApprox": true,
"isEdited": true,
"likeCount": 106000,
"replyCount": 648,
"isReply": false,
"parentCommentId": null,
"isByChannelOwner": false,
"isAuthorVerified": false,
"isHearted": false,
"isPinned": false,
"position": 1,
"sortedBy": "top",
"scrapedAt": "2026-10-31T04:00:00.000Z"
}
Price
Live Apify price on 2026-11-02, per 1,000 rows, by Apify plan. You pay only for rows delivered; error and summary rows marked free in the README cost nothing. Plus $0.001 per GB of memory when a run starts.
| Per 1,000 | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|
| Comment (main) | $1.80 | $1.35 | $1.08 | $0.81 | $0.81 | $0.81 |
Use cases
- Audience research: what viewers ask, praise and complain about under your or a competitor's videos.
- Product feedback: comments under review videos of a product, newest first, every day.
- Sentiment and topic analysis: clean text with likes as a weight, no personal data to scrub.
- Agents: "what do people say about this video" before writing a summary.
Run it from code or an AI agent
Actor ID arcadium/youtube-comments. Set APIFY_TOKEN to your Apify API token. The input below is the actor’s prefilled example; see the guide for every field.
curl
curl -X POST "https://api.apify.com/v2/acts/arcadium~youtube-comments/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"maxComments":20}'JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/youtube-comments').call({
"urls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ"
],
"maxComments": 20
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);Python
# pip install apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/youtube-comments").call(run_input={
"urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"maxComments": 20,
})
items = client.dataset(run.default_dataset_id).list_items().items # apify-client 3.x returns a Run object
print(items)MCP
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/youtube-comments",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}LangChain
# pip install langchain-apify (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("arcadium/youtube-comments")
rows = tool.invoke({"run_input": {
"urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"maxComments": 20,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])LlamaIndex
# pip install llama-index-readers-apify
import os
from llama_index.core import Document, VectorStoreIndex
from llama_index.readers.apify import ApifyActor
reader = ApifyActor(os.environ["APIFY_TOKEN"])
documents = reader.load_data(
actor_id="arcadium/youtube-comments",
run_input={
"urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
"maxComments": 20,
},
dataset_mapping_function=lambda item: Document(text=str(item.get("text") or ""), metadata={"url": item.get("url")}),
)
index = VectorStoreIndex.from_documents(documents)CrewAI
# pip install crewai crewai-tools langchain-apify (reads APIFY_API_TOKEN from the environment)
from crewai import Agent
from crewai_tools import ApifyActorsTool
tool = ApifyActorsTool(actor_name="arcadium/youtube-comments")
researcher = Agent(
role="Research analyst",
goal="Answer with data collected by the tool",
backstory="Uses public web data.",
tools=[tool],
)n8n
{
"nodes": [
{
"name": "Run arcadium/youtube-comments",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
0,
0
],
"parameters": {
"method": "POST",
"url": "https://api.apify.com/v2/acts/arcadium~youtube-comments/run-sync-get-dataset-items",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\"urls\":[\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"],\"maxComments\":20}",
"options": {
"timeout": 300000
}
}
}
],
"connections": {}
}Google Sheets
// Extensions > Apps Script. Store your token once: Project Settings > Script properties > APIFY_TOKEN.
function importLastRun() {
const token = PropertiesService.getScriptProperties().getProperty('APIFY_TOKEN');
const url = 'https://api.apify.com/v2/acts/arcadium~youtube-comments/runs/last/dataset/items?status=SUCCEEDED&clean=true&format=json';
const res = UrlFetchApp.fetch(url, { headers: { Authorization: 'Bearer ' + token } });
const rows = JSON.parse(res.getContentText());
if (!rows.length) return;
const keys = Object.keys(rows[0]);
const values = rows.map((r) => keys.map((k) => (typeof r[k] === 'object' ? JSON.stringify(r[k]) : r[k])));
const sheet = SpreadsheetApp.getActiveSheet();
sheet.clearContents();
sheet.getRange(1, 1, 1, keys.length).setValues([keys]);
sheet.getRange(2, 1, values.length, keys.length).setValues(values);
}Limitations
- YouTube shows comment dates as "3 weeks ago", so
publishDateand theoldestCommentDatecut are approximate (to the unit shown). - Like counts above 1,000 are rounded by YouTube ("106K").
- No author names, handles, avatars or author channels, by design. Old replies may start with the replied-to person's display name as plain text without an @; those are not always caught.
- Comments are read as an anonymous visitor sees them; held-for-review and members-only comments are not visible.
FAQ
Can I get the comment author? No. Author names and handles are personal data and are never output; isByChannelOwner and isAuthorVerified say whether the creator or a verified channel wrote it.
A video returned nothing. Why? Look at its error row: comments may be turned off, or the video is private or removed. Error rows are free.
Related actors
YouTube Transcript & Subtitles Scraper
YouTube transcripts and subtitles from $2.48 per 1,000 (pintostudio: $10); pintostudio, johnvc and starvibe inputs work as is.
$2.48 per 1,000 transcripts on the Free plan, down to $1.80 on higher plans
YouTube Scraper
YouTube videos and Shorts from channels, playlists, searches or links, $3.60 per 1,000; streamers/youtube-scraper input works as is.
$3.60 per 1,000 videos on the Free plan, down to $2.16 on higher plans