# YouTube Community Posts Scraper (`maximedupre/youtube-community-posts`) Actor

Collect public YouTube Community posts from channel handles, URLs, or IDs without customer-supplied YouTube credentials or API keys. Look up post details and comments by ID or URL, then get post text, links, channel context, dates, types, media, and engagement in structured dataset rows.

- **URL**: https://apify.com/maximedupre/youtube-community-posts.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.95 / 1,000 community posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 📣 Explore a YouTube community feed

For marketers, creator teams, researchers, and developers, this Actor collects public YouTube Community posts or looks up known posts and comments. Each dataset row keeps useful source data such as post text, IDs, links, channel context, publication time, type, media, and engagement, so you can review a channel snapshot or reuse it in a workflow.

- Build a structured post dataset with [**YouTube Community Posts Data**](https://apify.com/maximedupre/Youtube%20Community%20Posts/examples/youtube-community-posts-data) for research or reporting.
- Find posts that match a text filter with [**YouTube Community Post Search**](https://apify.com/maximedupre/Youtube%20Community%20Posts/examples/youtube-community-post-search) when you need a focused slice.
- Collect a channel feed snapshot with [**Scrape YouTube Community Posts**](https://apify.com/maximedupre/Youtube%20Community%20Posts/examples/scrape-youtube-community-posts) for a broader review.
- Save accessible post images with [**YouTube Community Post Image Downloader**](https://apify.com/maximedupre/Youtube%20Community%20Posts/examples/youtube-community-post-image-downloader) for image-focused work.
- Retrieve public post data and links with [**YouTube Community Post Download**](https://apify.com/maximedupre/Youtube%20Community%20Posts/examples/youtube-community-post-download) for another workflow.

#### 📦 Post and comment rows

**One row per returned post or comment**

The dataset has two row shapes. A post row keeps the post identity, text, source channel, publication time, type, and available media or engagement data. A comment row adds the comment identity, author, comment engagement, and the context of the post it belongs to.

**Public source scope**

The Actor reads public YouTube data. Private, deleted, restricted, or sign-in-only posts and source fields outside YouTube's public response are not included. Shared video fields contain video metadata and a public link, not the video file. Each run is a snapshot, not a change monitor.

#### ▶️ Run a YouTube Community post lookup

1. Choose `communityPosts`, `postDetails`, or `comments` in `resultType`.
2. For `communityPosts`, enter one or more channel handles, channel URLs, or channel IDs in `channels`.
3. For `postDetails` or `comments`, enter one or more post IDs or full post URLs in `postReferences`.
4. Add post-type, text, or approximate date filters when you need a smaller set. You can also add language detection or store post images for supported post lookups.
5. Start the run and open the `results` link to review the dataset.

#### ⚙️ Input

Choose the result type first. `channels` is used for Community posts. `postReferences` is used for Post details and Comments. Values that do not apply to the selected result type are ignored.

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `resultType` | string | Chooses `communityPosts`, `postDetails`, or `comments`. |
| `channels` | string array | Lists one or more YouTube channel handles, channel URLs, or channel IDs for Community posts. |
| `postTypes` | string array | Optionally keeps only `text`, `image`, `video`, or `poll` Community posts. Leave it empty to return all available types. |
| `keyword` | string | Optionally keeps Community posts whose text contains this keyword. |
| `dateFrom` | date string | Optionally includes Community posts from this approximate publication date onward. Use `YYYY-MM-DD`. |
| `dateTo` | date string | Optionally includes Community posts through this approximate publication date. Use `YYYY-MM-DD`. |
| `maxPosts` | integer | Optionally stops Community posts from each channel. Leave it empty to collect all available posts until the current public feed is exhausted. |
| `maxComments` | integer | Optionally stops Comments from each post. Leave it empty to collect all available comments until the current public thread is exhausted. |
| `postReferences` | string array | Lists one or more YouTube Community post IDs or full post URLs for Post details and Comments. |
| `countryCode` | string | Optionally sets a two-letter country context for localized source labels, such as `US`. |
| `languageCode` | string | Optionally sets a language context for localized source labels, such as `en` or `en-US`. |
| `includeLanguage` | boolean | When enabled, adds the detected language when detection succeeds for Community posts and Post details. A successful detection may add a usage charge. |
| `storeImages` | boolean | When enabled, stores retrieved post images and returns access references when storage succeeds for Community posts and Post details. A stored image may add a usage charge. |

**Successful default input**

This is the public input from the successful default-input Community posts run:

```json
{
  "resultType": "communityPosts",
  "channels": [
    "@YouTube"
  ],
  "maxPosts": 25,
  "includeLanguage": false,
  "storeImages": false
}
```

#### 🧾 Output

The run output contains a `results` link to the successful posts and comments from the run.

**Run output**

| Field | Type | What it does |
| --- | --- | --- |
| `results` | URL string | Opens the successful posts and comments from the run. |

**Post row**

Each post row has `itemType` set to `post`. Optional fields appear when the public source provides them or when the matching enrichment option succeeds.

| Field | Type | What it does |
| --- | --- | --- |
| `itemType` | string | Identifies this row as a `post`. |
| `postId` | string | Stable YouTube ID of the Community post. |
| `postUrl` | URL string | Direct public link to the Community post. |
| `text` | string | Text content of the post. |
| `publishedAt` | string | Source publication time as ISO 8601 when available, or source relative time otherwise. |
| `postType` | string | Post content or attachment type: `text`, `image`, `video`, or `poll`. |
| `channel` | object | Public identity and profile data for the source channel. |
| `channel.channelId` | string | Stable YouTube ID of the source channel. |
| `channel.name` | string | Public name of the source channel. |
| `channel.handle` | string | Public handle of the source channel when available. |
| `channel.subscriberCount` | string | Subscriber count display from the source when available. |
| `images` | object array | Public image references for the post. An image can use the source URL or an Apify storage URL when stored. |
| `images[].url` | URL string | URL used to open or download one post image. |
| `sharedVideo` | object | Metadata and a public link for a video shared in the post. |
| `sharedVideo.videoId` | string | Stable YouTube ID of the shared video. |
| `sharedVideo.url` | URL string | Direct public link to the shared video. |
| `sharedVideo.title` | string | Public title of the shared video when available. |
| `sharedVideo.channelName` | string | Public channel name for the shared video when available. |
| `sharedVideo.publishedAt` | string | Source publication time of the shared video when available. |
| `poll` | object | Choices and vote data for a poll post. |
| `poll.choices` | object array | Choices shown in the poll. |
| `poll.choices[].text` | string | Text of one poll choice. |
| `poll.totalVotes` | string | Total vote count shown by the source when available. |
| `engagement` | object | Available engagement counts for the post. |
| `engagement.likes` | integer | Number of likes on the post when available. |
| `engagement.comments` | integer | Number of comments on the post when available. |
| `language` | string | Detected language when language detection succeeds. |
| `hashtags` | string array | Hashtags found in the post text. |
| `videoLinks` | URL string array | YouTube video links found in the post text. |

**Genuine post row**

The following complete row came from a successful run. Optional fields that were not returned for this row are not added to the example.

```json
{
  "itemType": "post",
  "postId": "Ugkx-7xgRw-Uc9lRS3_2RvS2zASPTZOFtIlw",
  "postUrl": "https://www.youtube.com/post/Ugkx-7xgRw-Uc9lRS3_2RvS2zASPTZOFtIlw",
  "text": "Have you heard about MAX POWER?   It's our new aerospace festival, and it's landing at NASA's Kennedy Space Center in Florida, Nov. 7-8.\n\nLearn how to join us: https://www.nasa.gov/maxpowerhttps://www.youtube.com/watch?v=wJhhS...",
  "publishedAt": "2 weeks ago",
  "postType": "video",
  "channel": {
    "channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
    "name": "NASA",
    "handle": "/@NASA",
    "subscriberCount": "63.1K subscribers"
  },
  "images": [
    {
      "url": "https://i.ytimg.com/vi/wJhhSlplzuE/hqdefault.jpg?sqp=-oaymwEcCOADEI4CSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDJ1mamUdpZ4imKpqYNXzdVhXogGw"
    },
    {
      "url": "https://yt3.googleusercontent.com/9PCzJJ9kWfittH2cj6d2yIev95QLgTV_WNNXRkf0FUPn9uGSBgMKFb0ZENtlJj4lNd3J8O5A=s68-c-k-c0x00ffffff-no-rj"
    }
  ],
  "sharedVideo": {
    "videoId": "wJhhSlplzuE",
    "url": "https://www.youtube.com/watch?v=wJhhSlplzuE",
    "title": "MAX POWER 2026 — Official Announcement",
    "channelName": "UP.Summit",
    "publishedAt": "2 weeks ago"
  },
  "engagement": {
    "likes": 288
  },
  "videoLinks": [
    "https://www.youtube.com/watch?v=wJhhS..."
  ]
}
```

**Comment row**

Each comment row has `itemType` set to `comment`. It keeps the comment and the source post context, so the same table is useful for comment research and post-level analysis.

| Field | Type | What it does |
| --- | --- | --- |
| `itemType` | string | Identifies this row as a `comment`. |
| `commentId` | string | Stable YouTube ID of the comment. |
| `postId` | string | Stable ID of the Community post with the comment. |
| `postUrl` | URL string | Direct public link to the Community post. |
| `text` | string | Text content of the comment. |
| `publishedAt` | string | Source publication time as ISO 8601 when available, or source relative time otherwise. |
| `postType` | string | Content or attachment type of the source post when available. |
| `channel` | object | Public identity and profile data for the channel that published the source post. |
| `channel.channelId` | string | Stable YouTube ID of the source channel. |
| `channel.name` | string | Public name of the source channel. |
| `channel.handle` | string | Public handle of the source channel when available. |
| `channel.subscriberCount` | string | Subscriber count display from the source when available. |
| `author` | object | Public identity data for the comment author. |
| `author.channelId` | string | Stable YouTube ID of the comment author's channel. |
| `author.name` | string | Public name of the comment author. |
| `author.handle` | string | Public handle of the comment author when available. |
| `images` | object array | Public image references carried with the source post when available. |
| `images[].url` | URL string | URL used to open or download one source-post image. |
| `sharedVideo` | object | Metadata and a public link for a video shared in the source post when available. |
| `sharedVideo.videoId` | string | Stable YouTube ID of the shared video. |
| `sharedVideo.url` | URL string | Direct public link to the shared video. |
| `sharedVideo.title` | string | Public title of the shared video when available. |
| `sharedVideo.channelName` | string | Public channel name for the shared video when available. |
| `sharedVideo.publishedAt` | string | Source publication time of the shared video when available. |
| `poll` | object | Choices and vote data for the source post when it is a poll. |
| `poll.choices` | object array | Choices shown in the source poll. |
| `poll.choices[].text` | string | Text of one source-poll choice. |
| `poll.totalVotes` | string | Total vote count shown by the source when available. |
| `engagement` | object | Available engagement counts for the source post. |
| `engagement.likes` | integer | Number of likes on the source post when available. |
| `engagement.comments` | integer | Number of comments on the source post when available. |
| `commentEngagement` | object | Available engagement counts for the comment. |
| `commentEngagement.likes` | integer | Number of likes on the comment when available. |
| `commentEngagement.replies` | integer | Number of replies to the comment when available. |
| `isChannelOwner` | boolean | Says whether the comment author is the source-channel owner when known. |
| `language` | string | Detected language of the source post when detection succeeds. |
| `hashtags` | string array | Hashtags found in the source post text. |
| `videoLinks` | URL string array | YouTube video links found in the source post text. |

**Genuine comment row**

The following complete row came from a successful comment run:

```json
{
  "itemType": "comment",
  "commentId": "UgzyZLivNDjrcg9aLvd4AaABAg",
  "postId": "UgkxZusu9I1Z-VuU5PGZNA2gclHi8V9CJVZk",
  "postUrl": "https://www.youtube.com/post/UgkxZusu9I1Z-VuU5PGZNA2gclHi8V9CJVZk",
  "text": "Adding more days to my life VS adding more life to my days",
  "publishedAt": "1 month ago",
  "postType": "poll",
  "channel": {
    "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
    "name": "MrBeast",
    "handle": "/@MrBeast",
    "subscriberCount": "30.4M subscribers"
  },
  "author": {
    "channelId": "UCescH4jRkgcfMry6qlV1e9g",
    "name": "Krenteboll",
    "handle": "@Krenteboll"
  },
  "commentEngagement": {
    "likes": 7800,
    "replies": 119
  },
  "isChannelOwner": false,
  "poll": {
    "choices": [
      {
        "text": "100 Years Of No Aging"
      },
      {
        "text": "1 Billion Dollars"
      }
    ],
    "totalVotes": "1.7M votes"
  },
  "engagement": {
    "likes": 102000
  }
}
```

#### 💳 Pricing

Charges are tied to successful saved outcomes. The primary events cover a saved post, post detail, or comment. Optional event charges apply only when a post image is stored or a post language is detected successfully. Check the Pricing tab for the current tier price before a run.

| Buyer-facing event | When it applies |
| --- | --- |
| `Community Post` | One public post is saved to the dataset. |
| `Post Detail` | One requested post detail is saved. |
| `Comment` | One public comment is saved to the dataset. |
| `Stored Image` | One public post image is stored with an access reference. |
| `Detected Language` | The language of one public post is detected successfully. |

#### 🔌 Integrations

Open the `results` link in the run output, use the Apify API, or export the dataset for another workflow.

Watch the related guide here:

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### Which result type should I choose?

Choose `communityPosts` to collect posts from channels. Choose `postDetails` for known post IDs or URLs, or choose `comments` to collect comments from known posts.

##### How do I look up one known Community post?

Set `resultType` to `postDetails` and add the post ID or full YouTube post URL to `postReferences`. You can add more than one reference in the same run.

##### Can I collect comments from a post?

Yes. Set `resultType` to `comments`, add one or more post IDs or URLs, and optionally set `maxComments` for each post.

##### What happens when a work limit is empty?

An empty `maxPosts` returns all available posts until the current public feed is exhausted. An empty `maxComments` returns all available comments until the current public thread is exhausted.

##### Does this download YouTube videos?

No. A shared video includes its public link and metadata, not the video file. For image posts, `storeImages` can store retrieved images and return access references when storage succeeds.

##### Can I use this for a YouTube community post download?

Yes. The dataset gives you public post data, links, channel context, dates, types, and available media references for export or later processing.

##### Do I need a YouTube API key or login?

For channel-based Community-post collection, you do not need to supply YouTube credentials or an API key. The Actor reads publicly accessible source data.

##### Are publication dates exact?

The source time is kept as an ISO 8601 time when available. If YouTube exposes only relative time, such as `2 weeks ago`, that source text is kept instead. Date filters are approximate.

##### Can I search several keywords in one run?

The input has one `keyword` filter per run. Separate keyword searches are separate runs, not one combined search.

##### What happens with private or deleted content?

Private, deleted, restricted, or sign-in-only posts and source fields outside YouTube's public response are outside the Actor's scope.

##### Does the Actor monitor changes over time?

No. Each run is a snapshot of the public data available at that time. Use another run when you need a later snapshot.

### 📝 Changelog

**v0.0** (18-09-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~youtube-community-posts/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [YouTube Channel Search Scraper](https://apify.com/maximedupre/youtube-channel-search-scraper): Find public channels by keyword before collecting their Community posts.
- [YouTube Channel Statistics Scraper](https://apify.com/maximedupre/youtube-channel-statistics-scraper): Add public subscriber, view, and video counts to channel research.
- [YouTube Similar Channels Finder](https://apify.com/maximedupre/youtube-similar-channels): Find related public channels to expand a Community-post watch list.
- [YouTube Shorts Comments Scraper](https://apify.com/maximedupre/youtube-shorts-comments-scraper): Read public comments from known Shorts when audience feedback extends beyond Community posts.
- [YouTube Trending Videos Scraper](https://apify.com/maximedupre/youtube-trending-videos-scraper): Compare regional video trends with the posts you collect.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `resultType` (type: `string`):

Choose the kind of result to return.

## `channels` (type: `array`):

Enter one or more YouTube channel handles, channel URLs, or channel IDs. This field is used for Community posts and is ignored for Post details and Comments.

## `postTypes` (type: `array`):

Optional. Return only Community posts with the selected types. Leave this empty to return all available types.

## `keyword` (type: `string`):

Optional. Return Community posts whose text contains this keyword.

## `dateFrom` (type: `string`):

Optional. Include Community posts from this approximate publication date onward. Use a calendar date in YYYY-MM-DD form.

## `dateTo` (type: `string`):

Optional. Include Community posts through this approximate publication date. Use a calendar date in YYYY-MM-DD form.

## `maxPosts` (type: `integer`):

Optional stop for Community posts from each channel. Leave it empty to collect all available posts until the current public feed is exhausted.

## `maxComments` (type: `integer`):

Optional stop for Comments from each post. Leave it empty to collect all available comments until the current public thread is exhausted.

## `postReferences` (type: `array`):

Enter one or more YouTube Community post IDs or full post URLs. This field is used for Post details and Comments and is ignored for Community posts.

## `countryCode` (type: `string`):

Optional two-letter country code for localized source labels, such as US.

## `languageCode` (type: `string`):

Optional language code for localized source labels, such as en or en-US.

## `includeLanguage` (type: `boolean`):

When enabled, add the detected language when detection succeeds for Community posts and Post details. This option may add usage charges.

## `storeImages` (type: `boolean`):

When enabled, store retrieved post images and return access references when storage succeeds for Community posts and Post details. This option may add usage charges.

## Actor input object example

```json
{
  "resultType": "communityPosts",
  "channels": [
    "@examplechannel",
    "UCExampleChannelId"
  ],
  "keyword": "product launch",
  "dateFrom": "2026-01-01",
  "dateTo": "2026-12-31",
  "maxPosts": 25,
  "postReferences": [
    "UgkxExamplePostId"
  ],
  "countryCode": "US",
  "languageCode": "en",
  "includeLanguage": false,
  "storeImages": false
}
```

# Actor output Schema

## `results` (type: `string`):

Open the successful posts and comments from this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "resultType": "communityPosts",
    "channels": [
        "@YouTube"
    ],
    "maxPosts": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/youtube-community-posts").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "resultType": "communityPosts",
    "channels": ["@YouTube"],
    "maxPosts": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/youtube-community-posts").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "resultType": "communityPosts",
  "channels": [
    "@YouTube"
  ],
  "maxPosts": 25
}' |
apify call maximedupre/youtube-community-posts --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/youtube-community-posts"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/01TkDELDANJzdjUSr/builds/muJpU6cCSJxPptSJg/openapi.json
