# YouTube Comments Scraper (`sfoln/youtube-video-comments`)

Scrape comments from YouTube videos and Shorts, top or newest first: text, date, likes, reply count and author name, handle and channel, one JSON record per comment. $0.30 per 1,000 comments + $0.003 per page of ~20. No YouTube API key or login needed.

- Family: Social media data
- Categories: Social media, Videos, Automation
- Availability: on request (private on Apify). Email contact@sfoln.com with subject "Access request: YouTube Comments Scraper (sfoln/youtube-video-comments)" before calling; calls fail until it is public.
- JSON: https://www.sfoln.com/actors/youtube-video-comments.json
- MCP: https://mcp.apify.com?tools=sfoln/youtube-video-comments
- REST (sync): POST https://api.apify.com/v2/actors/sfoln~youtube-video-comments/run-sync-get-dataset-items
- REST (async): POST https://api.apify.com/v2/actors/sfoln~youtube-video-comments/runs

YouTube Comments Scraper gets comments from YouTube videos and Shorts, sorted by top or newest, one normalized record per comment: comment ID, text, publish date, likes, reply count, and the author's name, handle, channel ID and verification and creator flags. It's built for audience and sentiment research, community management, product feedback mining, dataset building and AI agents.

## Price per delivered record

| Event | Price | Per 1,000 | Charged for |
| --- | --- | --- | --- |
| YouTube comment (`youtube-comment`) | $0.0003 | $0.30 / 1,000 | Charged once per comment delivered as a dataset record. Video summary records are never charged. |
| YouTube comments page (`youtube-comments-query`) | $0.003 | $3 / 1,000 | Charged once per page of comments (about 20) that delivered at least one new comment. Covers the per-request upstream fee. Also charged for an empty page the upstream billed (when the budget covers it). |

Pay-per-event, USD, billed by Apify; no platform usage charge. Only records with status `ok` are charged. Cap a run with `maxTotalChargeUsd`. Apify free plan: up to 10 per run.

## Run

```bash
curl -X POST "https://api.apify.com/v2/actors/sfoln~youtube-video-comments/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"videos":["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"maxCommentsPerVideo":20}'
```

MCP client configuration:

```json
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/youtube-video-comments"
    }
  }
}
```

Example prompt: Get the 100 top comments of https://www.youtube.com/watch?v=dQw4w9WgXcQ and summarize what viewers are saying.

## Input

Enter YouTube video URLs or IDs. Each video produces one dataset record per comment plus one summary record per video.

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| `videos` (required) | array | — | Video URLs or IDs: youtube.com/watch, youtu.be, /shorts/ or /live/ URLs, or 11-character video IDs. Duplicates are removed. Accounts on the Apify free plan can process up to 10 videos per run. |
| `maxCommentsPerVideo` | integer | `50` | Max comments per video: How many comments to return per video (1–500). Each delivered comment is one charged event, plus one page event per page of about 20. |
| `order` | string | `"top"` | Order: top = YouTube's "Top comments" ranking, newest = most recent first. One of `"top"`, `"newest"`. |
| `maxVideos` | integer | `100` | Max videos: Safety cap on the number of videos processed in this run. |
| `concurrency` | integer | `4` | Concurrency: How many videos are fetched in parallel (1–8). |
| `itemTimeoutSecs` | integer | `600` | Time limit per input (seconds): Pagination for one video stops cleanly shortly before this limit (60–3600). Raise it for very large per-input limits. |
| `includeRaw` | boolean | `false` | Include raw upstream response: Attach the unmodified provider object to each result record. |

Example input:

```json
{
  "videos": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxCommentsPerVideo": 20
}
```

## Output

One record per input item with `status` (`ok` is charged; `not_found`, `error`, `skipped_*` are free) and `charged`. The run stores an `OUTPUT` summary record.

| Field | Type | Meaning |
| --- | --- | --- |
| `input` | string | object | Input: The video URL or ID as provided. |
| `recordType` | string | Record type: comment (one per delivered comment, charged) \| video (one summary per video, never charged) |
| `position` | integer | Position: 1-based position of the comment within its input |
| `videoId` | string | null | Video ID |
| `videoUrl` | string | null | Video URL |
| `order` | string | Order: Summary records only: top \| newest |
| `commentId` | string | null | Comment ID |
| `text` | string | null | Text |
| `publishedAt` | string | null | Published at: ISO 8601, approximate |
| `publishedTimeText` | string | null | Published (relative) |
| `likes` | number | null | Likes |
| `replyCount` | number | null | Replies |
| `isReply` | boolean | null | Is reply |
| `isPinned` | boolean | null | Pinned |
| `isHearted` | boolean | null | Hearted by creator |
| `authorName` | string | null | Author name |
| `authorHandle` | string | null | Author handle |
| `authorChannelId` | string | null | Author channel ID |
| `authorChannelUrl` | string | null | Author channel URL |
| `authorIsVerified` | boolean | null | Author verified |
| `authorIsCreator` | boolean | null | Author is the video creator |
| `rowsDelivered` | integer | Comments delivered: Summary records only. |
| `pagesFetched` | integer | Pages fetched: Summary records only. |
| `pagesCharged` | integer | Pages charged: Summary records only. |
| `reachedEnd` | boolean | Reached end: Summary records only: the upstream reported no further pages. |
| `stopReason` | string | Stop reason: Summary records only: limit \| end \| budget \| max_pages \| deadline \| empty_pages \| error |
| `status` | string | Status: ok \| not_found \| error \| skipped_invalid \| skipped_budget \| skipped_free_plan |
| `charged` | boolean | Charged |
| `chargedEvent` | string | Charged event |
| `error` | object | Error |
| `warnings` | array | Warnings |
| `source` | string | Source |
| `fetchedAt` | string | Fetched at |

Example record:

```json
{
  "input": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "recordType": "comment",
  "position": 1,
  "videoId": "dQw4w9WgXcQ",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "commentId": "UgwVfRopfS2F-WB3aF14AaABAg",
  "text": "I love how in the middle he said \"I've been able to work with 2 great coaches...\"",
  "publishedAt": "2025-01-23T23:14:02.948Z",
  "publishedTimeText": "9 days ago",
  "likes": 110,
  "replyCount": 5,
  "isReply": false,
  "isPinned": null,
  "isHearted": null,
  "authorName": "@SimonT80",
  "authorHandle": "SimonT80",
  "authorChannelId": "UC8JC3uSUmmXTCTKl-bgr1DA",
  "authorChannelUrl": "https://youtube.com/@SimonT80",
  "authorIsVerified": false,
  "authorIsCreator": false,
  "status": "ok",
  "charged": true,
  "chargedEvent": "youtube-comment",
  "source": "scrapecreators",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}
```

## Related

- [YouTube Video Details Scraper](https://www.sfoln.com/actors/youtube-video-lookup.md) (`sfoln/youtube-video-lookup`)
- [YouTube Search Scraper](https://www.sfoln.com/actors/youtube-search.md) (`sfoln/youtube-search`)
- [TikTok Comments Scraper](https://www.sfoln.com/actors/tiktok-video-comments.md) (`sfoln/tiktok-video-comments`)
- [Instagram Comments Scraper (No Login)](https://www.sfoln.com/actors/instagram-post-comments.md) (`sfoln/instagram-post-comments`)

Publisher: SFOLN LLC, contact@sfoln.com. Catalogue: https://www.sfoln.com/catalog.json. Agent guide: https://www.sfoln.com/agents.md.
