How to use YouTube Comments Scraper
Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.
$1.80 per 1,000 comments on the Free plan, down to $0.81 on higher plans (live Apify price on 2026-11-02).
1. In the Apify Store (no code)
- Open arcadium/youtube-comments and sign in to Apify (a free account works).
- Fill in the input form. The fields below are the ones the example uses.
- Set a maximum cost per run in the run options if you want a hard cap.
- Start the run. Rows appear in the Output tab as they arrive.
- Export the dataset as JSON, CSV or Excel, or connect an integration.
| Input field | Type | Description |
|---|---|---|
urls | array | Video or Shorts URLs (https://www.youtube.com/watch?v=dQw4w9WgXcQ, https://youtu.be/..., https://www.youtube.com/shorts/...) or bare 11-character video ids. |
maxComments | integer | Rows per video (comments plus replies), 1 to 100,000 (default 100). |
Example input:
{
"urls": [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ"
],
"maxComments": 20
}
2. Over the Apify API
The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).
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}'
3. From 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);
4. From 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)
5. In n8n
Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.
{
"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": {}
}
6. From an AI assistant (MCP)
Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/youtube-comments",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}
More on the MCP page.
7. From 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])
Sample output
One row, from the example in the actor’s README. Long text is shortened and lists are 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"
}
| Field | What it holds |
|---|---|
rowType | Kind of row. Filter on this first. Values: 'comment': one comment or reply (charged). 'error': a video gave no comments; see code and message (free). |
platform | Always 'youtube'. |
commentId | YouTube comment id, stable; replies are <parent id>.<reply id>. |
commentUrl | Link that opens the video with this comment highlighted. |
videoId | Video id, 11 characters. |
videoUrl | Watch page link of the video. |
videoTitle | Video title. |
channelName | The video's channel (not the comment author). |
channelId | The video's channel id (UC...). |
videoCommentCountText | The video's comment count as YouTube shows it, rounded (e.g. '2.4M'). |
text | Comment text. Emails, phone numbers, profile links and @mentions of other users (replaced with @user) are removed. |
publishedText | Relative date as YouTube shows it ('3 weeks ago'). |
publishDate | Approximate date YYYY-MM-DD derived from publishedText (to the unit shown). |
publishDateIsApprox | Always true: YouTube gives comment dates only as relative text. |
isEdited | The author edited the comment. |
likeCount | Likes, rounded by YouTube above 1,000 (106K -> 106000). |
replyCount | Number of replies (top-level comments); 0 for replies. |
isReply | True for a reply. |
parentCommentId | Replies: id of the comment replied to; null for top-level comments. |
isByChannelOwner | Written by the video's own channel. |
isAuthorVerified | The author's channel has a verified or official artist badge. The author's name, handle and channel are never output. |
isHearted | The creator gave the comment a heart. |
isPinned | Pinned by the creator to the top. |
position | 1-based rank of the top-level comment in the chosen order; a reply carries its parent comment's rank. |
sortedBy | 'top' or 'newest': the order the comments were read in. |
scrapedAt | When the row was read, ISO 8601. |
input | Error rows: the input that gave no data. |
code | Error rows: 'not_found', 'unavailable' (e.g. comments turned off), 'invalid_input', 'blocked'. |
message | Error rows: readable reason. |
Schedule it
In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.