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

Scrape public YouTube Community posts from channel handles, channel URLs, channel IDs, or individual post URLs. Returns text, media, likes, timestamps, linked videos, and channel metadata. Public data only; no cookies required. $0.005 per saved post.

- **URL**: https://apify.com/khadinakbar/youtube-community-posts-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, Automation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 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.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## YouTube Community Posts Scraper

Turn public YouTube Community feeds into structured, analysis-ready data. Give the Actor known channel URLs, canonical `@handles`, channel IDs, or individual Community post URLs. It returns one validated dataset row per public post with text, images, public likes, publish information, channel identity, linked-video metadata, and collection provenance.

This YouTube Community Posts Scraper is built for a specific job: **you know which channels or posts matter and need Community content as data rather than screenshots or manual copy-and-paste**. It uses an owner-managed public-data provider and does not ask for your YouTube cookies, Google login, browser session, or personal API key.

Use the [prefilled Actor input](https://apify.com/khadinakbar/youtube-community-posts-scraper/input) when you want to verify one channel with a bounded first run.

### Decide in 30 seconds

| Your job | Use this Actor? | Recommended route |
| --- | --- | --- |
| Export recent public Community posts from known channels | Yes | Put channel URLs, `@handles`, or `UC...` IDs in `channelUrls`. |
| Enrich a known public Community post | Yes | Put its canonical `/post/...` URL in `postUrls`. |
| Monitor creator announcements, polls, images, and linked videos | Yes | Schedule a small channel run and deduplicate downstream by `postId`. |
| Discover channels by topic before collecting their posts | Not first | Start with [YouTube Search Scraper](https://apify.com/khadinakbar/youtube-search-scraper), then pass its `channelUrl` or `channelId` here. |
| Collect comments for a video linked by a Community post | Not directly | Pass this Actor's non-null `videoUrl` or `videoId` to [YouTube Comments Scraper](https://apify.com/khadinakbar/youtube-comments-scraper). |
| Find currently trending videos | No | Use [YouTube Trending Videos Scraper](https://apify.com/khadinakbar/youtube-trending-videos-scraper). |
| Scrape video uploads, Shorts, transcripts, or media files | No | Use the Actor dedicated to that YouTube entity. |
| Access private, members-only, deleted, restricted, or login-only posts | No | Those surfaces are outside this public-data contract. |

Community posts are a distinct YouTube content type. A video-search result, comment, transcript, and Community announcement answer different research questions. Choosing the correct entity first produces cleaner data and fewer empty runs.

### A practical workflow: from creator list to campaign signal

Imagine a creator-partnership team follows 30 channels. The team can see uploads in a video dashboard, but launches often begin as Community posts: a product photo, a short announcement, a poll, or a link to a new video. On Monday, an analyst needs to know which creators mentioned an upcoming release and which posts linked to a video.

The analyst runs this Actor with the 30 channel URLs, `maxPosts: 100`, and a conservative page cap. Each returned row becomes a searchable evidence record. `content` supports keyword review, `imageUrls` identifies visual announcements, `publishedAt` supports reporting windows, and `videoUrl` identifies posts that drive viewers to a video. The analyst stores `postId` as the durable deduplication key and `scrapedAt` as the observation timestamp.

When a linked video needs audience analysis, its `videoUrl` flows into the comments Actor. When the analyst needs more candidate channels, the search Actor supplies `channelUrl` or `channelId` values accepted here. The workflow moves from discovery to Community evidence to video engagement without pretending that one dataset represents all of YouTube.

The team still applies judgment. A current public like count is a snapshot, not a historical time series. A missing count is not zero. A post that has been deleted, restricted, or omitted by the public source cannot be reconstructed by the Actor.

### What one dataset row contains

One row represents one public YouTube Community post. The flat schema works with JSON, CSV, spreadsheets, databases, BI tools, Make, n8n, and AI-agent pipelines.

| Field group | Fields | What it answers |
| --- | --- | --- |
| Post identity | `postId`, `postUrl` | Which public Community post is this? |
| Post content | `content`, `imageUrl`, `imageUrls` | What text or public images did the post contain? |
| Engagement | `likeCount`, `likeCountText` | What public like information was available at collection time? |
| Publication | `publishedAt`, `publishedTimeText` | When was the post published, in machine-readable or display form? |
| Channel | `channelId`, `channelName`, `channelHandle`, `channelUrl` | Which public channel created the post? |
| Linked video | `videoId`, `videoTitle`, `videoUrl`, `videoThumbnailUrl`, `videoViewCount`, `videoViewCountText`, `videoPublishedTimeText`, `videoLengthText`, `videoLengthSeconds` | Did the post link to a video, and what public metadata accompanied it? |
| Provenance | `source`, `sourceEndpoint`, `scrapedAt` | Which route supplied the record and when was it normalized? |

Only `postId`, `postUrl`, `imageUrls`, `source`, `sourceEndpoint`, and `scrapedAt` are required by the normalized record contract. A text-only post can have no images. A media-only post can have no text. A post can have no linked video. Public like counts and timestamps can be absent or change after collection.

The Actor never fabricates an error row. Provider objects are normalized, fully validated, deduplicated by `postId`, and then persisted. Invalid provider records are counted in diagnostics rather than mixed into the dataset.

### Quick start recipes

#### Recipe 1: ten posts from one known channel

Use this first to verify the channel and inspect the output shape with a small cost ceiling.

```json
{
  "channelUrls": ["https://www.youtube.com/@MrBeast"],
  "postUrls": [],
  "maxPosts": 10,
  "maxPagesPerChannel": 1
}
````

#### Recipe 2: several channels sharing one run cap

`maxPosts` applies to the whole run, not separately to each channel. Individual `postUrls` are processed before channel feeds.

```json
{
  "channelUrls": [
    "https://www.youtube.com/@NASA",
    "@TED",
    "UC_x5XG1OV2P6uZZ5FSM9Ttw"
  ],
  "postUrls": [],
  "maxPosts": 50,
  "maxPagesPerChannel": 2
}
```

#### Recipe 3: enrich known Community posts

Use canonical public URLs in the `https://www.youtube.com/post/...` form. Standard watch, Shorts, playlist, and comment URLs are rejected.

```json
{
  "channelUrls": [],
  "postUrls": [
    "https://www.youtube.com/post/Ugkx3w8sfDJf_NDdhUAtu7MTLX3d_Dt1V9UK"
  ],
  "maxPosts": 1,
  "maxPagesPerChannel": 1
}
```

Public post availability changes. If an example post has been removed by the time you run it, the correct result is `VALID_EMPTY`, not a substitute record.

### Input reference and boundaries

| Input | Type and default | Use it for | Important boundary |
| --- | --- | --- | --- |
| `channelUrls` | string array, default empty | Known channel URLs, canonical `@handles`, or exact `UC...` channel IDs | Channel references only; no watch, Shorts, playlist, or post URLs. |
| `postUrls` | string array, default empty | Known canonical public Community post URLs | Must use the `/post/...` route; query parameters are removed during normalization. |
| `maxPosts` | integer, default `20` | Cap all persisted and billable posts in the run | 1–500; shared across every channel and post input. |
| `maxPagesPerChannel` | integer, default `5` | Bound provider pagination for each channel feed | 1–50; page sizes vary, so this is not a result count. |

At least one supported channel or post reference is required. The combined normalized input is capped at 100 unique references. Duplicate handles are compared case-insensitively, duplicate post URLs are canonicalized, and the same `postId` is saved only once even if several inputs expose it.

Inputs are strict and are not coerced. Use the number `10`, not the string `"10"`; fractions and out-of-range values are rejected. Unknown top-level fields are rejected so a misspelled agent parameter cannot silently change the run. Handles must include `@` when entered directly. International handles are accepted in their canonical at-sign form within YouTube's language-dependent length rules.

There is no date-filter input. Collect a bounded current feed, then filter `publishedAt` downstream. This avoids presenting a client-side filter as a guarantee that the upstream feed is an exhaustive historical archive.

### Output example

```json
{
  "postId": "Ugkx3w8sfDJf_NDdhUAtu7MTLX3d_Dt1V9UK",
  "postUrl": "https://www.youtube.com/post/Ugkx3w8sfDJf_NDdhUAtu7MTLX3d_Dt1V9UK",
  "content": "New video is live",
  "imageUrl": "https://yt3.ggpht.com/example=s640",
  "imageUrls": ["https://yt3.ggpht.com/example=s640"],
  "likeCount": 195000,
  "likeCountText": "195K",
  "publishedAt": "2026-07-12T14:07:42.027Z",
  "publishedTimeText": "6 days ago",
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "channelName": "MrBeast",
  "channelHandle": "MrBeast",
  "channelUrl": "https://www.youtube.com/@MrBeast",
  "videoId": "tnTPaLOaHz8",
  "videoTitle": "A linked public video",
  "videoUrl": "https://www.youtube.com/watch?v=tnTPaLOaHz8",
  "videoThumbnailUrl": "https://i.ytimg.com/vi/tnTPaLOaHz8/hqdefault.jpg",
  "videoViewCount": 10000000,
  "videoLengthText": "18:42",
  "videoLengthSeconds": 1122,
  "source": "scrapecreators",
  "sourceEndpoint": "/v1/youtube/channel/community-posts",
  "scrapedAt": "2026-07-18T12:00:00.000Z"
}
```

The default key-value store also contains:

- `OUTPUT`: compact outcome, persisted/failed counts, exact named-event counts, named-event cost, memory allocation, maximum bounded estimate, and warnings.
- `RUN_SUMMARY`: detailed input counts, provider attempts and status classes, deduplication, public-source unavailability, pagination-cap state, stop reason, billing, and safe diagnostics.

Use the dataset for records and `OUTPUT` for orchestration. A transport status alone is not proof that usable posts exist.

### Pricing with worked examples

This Actor uses **Pay per event + Apify platform usage**.

| Event | Price | When it is charged |
| --- | ---: | --- |
| `apify-actor-start` | `$0.00005` | One event per allocated GB or part thereof, with a one-event minimum. |
| `community-post` | `$0.005` | Once for each validated Community post successfully persisted to the dataset. |

At the default 256 MB allocation, the start count is one:

A bounded run of 10 records costs `$0.05005` in named events at the default memory allocation.

- Valid request with no available posts: `1 × $0.00005 = $0.00005`
- 1 saved post: `1 × $0.00005 + 1 × $0.005 = $0.00505`
- 10 saved posts: `1 × $0.00005 + 10 × $0.005 = $0.05005`
- Default maximum of 20 posts: `1 × $0.00005 + 20 × $0.005 = $0.10005`

At 4 GB, 10 posts cost `4 × $0.00005 + 10 × $0.005 = $0.05020` in named events. Apify compute, storage, network, and any other platform usage are additional. `maxPosts` is the strongest result-event cost control; `maxPagesPerChannel` bounds upstream work but does not guarantee a specific row count.

### Run through the API

#### cURL

Keep your token in an environment variable and send it in the authorization header.

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/khadinakbar~youtube-community-posts-scraper/runs?waitForFinish=60' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "channelUrls": ["https://www.youtube.com/@TED"],
    "postUrls": [],
    "maxPosts": 10,
    "maxPagesPerChannel": 1
  }'
```

Read `data.defaultDatasetId` for rows and `data.defaultKeyValueStoreId` for `OUTPUT` and `RUN_SUMMARY`. If the run is still active after the wait window, poll the run endpoint before reading storage.

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/youtube-community-posts-scraper').call({
  channelUrls: ['@TED'],
  postUrls: [],
  maxPosts: 10,
  maxPagesPerChannel: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems({ clean: true });
const output = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT');

console.log({ outcome: output?.value?.outcome, posts: items.length });
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("khadinakbar/youtube-community-posts-scraper").call(run_input={
    "channelUrls": ["@TED"],
    "postUrls": [],
    "maxPosts": 10,
    "maxPagesPerChannel": 1,
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items(clean=True))
output = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")

print({"outcome": output["value"]["outcome"], "posts": len(items)})
```

### Use with AI agents and MCP

Through Apify's Actors MCP server, the generated tool name is `khadinakbar--youtube-community-posts-scraper`. Tool discovery can change with server configuration, so agents should inspect the tool schema rather than inventing parameters.

Agent prompt card:

> Collect up to 10 public Community posts from `@TED` with one page per channel. Return `postId`, `postUrl`, `content`, `publishedAt`, `likeCount`, `imageUrls`, `videoUrl`, and `scrapedAt`. Read `OUTPUT` before deciding success. If the outcome is `VALID_EMPTY`, explain the likely public-availability boundary and do not invent posts. If it is `INVALID_INPUT`, correct the named field without retrying unchanged. Do not request private or login-only content.

Recommended agent sequence:

1. Read the input schema and preserve numeric types.
2. Start with a small `maxPosts` and `maxPagesPerChannel`.
3. Wait for a terminal run state.
4. Read `OUTPUT`, then retrieve dataset rows only when the outcome permits useful data.
5. Treat nullable fields as unknown, not zero or empty evidence.
6. Use `postId` for downstream deduplication and `scrapedAt` for observation time.
7. If `continuationAvailableFor` is reported, increase the page cap in a new bounded run; no opaque provider token is exposed as a public resume input.

### Outcomes, retries, and recovery

| Outcome | Run status | Meaning | Recommended action |
| --- | --- | --- | --- |
| `COMPLETE` | succeeded | The bounded request produced posts without recorded quality warnings | Consume the rows. |
| `PARTIAL` | succeeded | Usable rows exist, but another input, record, write, or charge boundary produced a warning | Keep the good rows; retry only the missing scope if needed. |
| `VALID_EMPTY` | succeeded | Inputs were valid, but no public rows were available; 403/404 resource unavailability is included here | Check channel/post availability and input intent; do not retry rapidly or fabricate data. |
| `INVALID_INPUT` | succeeded | A field type, range, unknown key, or reference was invalid | Correct the reported field; do not retry unchanged. |
| `CONFIG_ERROR` | failed | The owner-managed provider credential, provider credits, or internal configuration prevented work | Escalate to the Actor owner; changing channels will not fix it. |
| `UPSTREAM_FAILED` | failed | The provider failed before any usable row could be saved | Retry with backoff; inspect `RUN_SUMMARY` if it persists. |

The provider retries transient timeouts, HTTP 408/425/429 responses, and server errors with bounded backoff. It does not blindly retry malformed requests, restricted/not-found resources, or configuration failures. Provider messages are bounded and secrets are redacted from surfaced diagnostics.

### Limits and interpretation

- The Actor reads the public Community surface available through one managed provider. It does not claim an independent fallback that does not exist.
- Public Community feeds are not assured to be exhaustive historical archives. Deep history, deleted posts, members-only posts, and source-omitted posts can be absent.
- A 403 or 404 from the public source is treated as unavailable data, not as proof that a channel or post never existed.
- Pagination is bounded independently for each channel, while `maxPosts` is shared across the whole run. Earlier inputs can consume the result cap.
- Individual post URLs are processed before channel feeds.
- `publishedTimeText` and `videoPublishedTimeText` are display strings. Prefer `publishedAt` for machine filtering when it exists.
- Like counts and linked-video views are current public snapshots and can change immediately after collection.
- Image and thumbnail URLs can be temporary or transformed by YouTube's CDN. Store only what your use case and permissions require.
- The Actor returns metadata and image URLs; it does not download videos, bypass access controls, or provide private account data.

### Verification snapshot

On 2026-07-18, the Actor was fresh-pulled from private live build `0.4.1`. The baseline had 529 README words, 52/100 decision-completeness coverage, 6 tests, seven high-severity transitive audit findings, and no explicit output proof across 40 historical successful transports. A pinned current-build failure was traced to a documented provider 404 for a valid channel handle; the old runtime classified that unavailable public resource as `UPSTREAM_FAILED`.

The v0.5 release line adds strict schema-aligned input parsing, international handle handling, exact channel/post routing, safe unavailable-resource outcomes, configuration-aware failures, memory-scaled named-event accounting, non-secret pagination evidence, bounded diagnostics, dependency remediation, and 23 tests. Verification reports 97.38% helper-module line coverage, 83.68% branch coverage, valid Apify schemas, and zero npm audit findings. Release acceptance also exercises at least 20 reviewed exact-build cloud cases, a separate real Actors MCP call, live pricing and metadata checks, and a fresh source readback.

This evidence describes observed checks, not a production reliability guarantee or a claim that YouTube will always expose every field.

### Responsible use

Use this Actor only for public YouTube data you are permitted to process. You are responsible for applicable law, YouTube's terms, privacy obligations, contractual restrictions, and content rights. Do not use it to access private or restricted content, evade controls, identify sensitive individuals, or redistribute copyrighted media without permission. Apply appropriate retention, access, and deletion controls to exported datasets.

### Frequently asked questions

#### Can it scrape a channel's videos or Shorts?

No. It reads Community posts. Use a channel-video or Shorts Actor for uploads.

#### Can I pass a channel name without `@`?

No. Direct handles must use their canonical `@handle` form. You can also pass a supported channel URL or exact `UC...` channel ID.

#### Why did a valid channel return `VALID_EMPTY`?

The channel may have no public Community posts, the Community surface may be unavailable or restricted, or the managed public source may not expose it. Inspect warnings and `RUN_SUMMARY`; do not interpret empty as proof that no post ever existed.

#### Does `maxPosts: 20` mean 20 posts per channel?

No. It is the whole-run cap shared by all inputs.

#### Can I resume with the provider continuation token?

No opaque token is exposed as public input. Increase `maxPagesPerChannel` deliberately and start a new bounded run.

#### Are missing likes or video views zero?

No. Missing means the public source did not provide a usable value. Preserve nullability in analysis.

#### Does the Actor require my YouTube login or API key?

No. It uses owner-managed provider credentials and accepts only public channel/post references from users.

# Actor input Schema

## `channelUrls` (type: `array`):

Use this when you want recent public Community posts from one or more YouTube channels. Accepts a channel URL such as 'https://www.youtube.com/@MrBeast', a channel ID such as 'UCX6OQ3DkcsbYNE6H8uQQuVA', or a handle such as '@MrBeast'. The actor follows the Posts feed and paginates until maxPosts or maxPagesPerChannel. This is NOT a video URL or a specific community-post URL; use postUrls for an individual post.

## `postUrls` (type: `array`):

Use this when you need known public YouTube Community posts rather than a channel feed. Each item must be a URL like 'https://www.youtube.com/post/Ugkx…'. The actor fetches the full public post record, including text, images, likes, channel data, and any linked video. Leave this empty to scrape channel feeds only. This is NOT a standard watch URL, Shorts URL, or a comment URL.

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

Use this when you need to cap the total number of saved community-post records across every input. Enter an integer from 1 to 500; for example, 20 returns at most twenty deduplicated records. Defaults to 20 and also caps billable community-post events at the same number. This is NOT a per-channel limit, so several channels share this total.

## `maxPagesPerChannel` (type: `integer`):

Use this when a channel has a long Community feed and you want to bound pagination requests. Enter an integer from 1 to 50; for example, 5 allows up to five provider pages for each channel. Defaults to 5, and RUN\_SUMMARY names channels with more pages available without exposing opaque provider tokens. This is NOT an exact post count because YouTube page sizes vary.

## Actor input object example

```json
{
  "channelUrls": [
    "https://www.youtube.com/@MrBeast",
    "UCX6OQ3DkcsbYNE6H8uQQuVA"
  ],
  "postUrls": [
    "https://www.youtube.com/post/Ugkxvj2KoApYAXoqLWnKVr6zZe5JjeHrQeP8"
  ],
  "maxPosts": 20,
  "maxPagesPerChannel": 5
}
```

# Actor output Schema

## `communityPosts` (type: `string`):

JSON dataset of public YouTube Community post records.

## `communityPostsCsv` (type: `string`):

CSV export of the same public post records.

## `output` (type: `string`):

Compact machine-readable outcome, counts, charges, and warnings.

## `runSummary` (type: `string`):

Detailed provider telemetry, pagination state, and diagnostics.

# 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 = {
    "channelUrls": [
        "https://www.youtube.com/@MrBeast"
    ],
    "maxPosts": 20,
    "maxPagesPerChannel": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/youtube-community-posts-scraper").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 = {
    "channelUrls": ["https://www.youtube.com/@MrBeast"],
    "maxPosts": 20,
    "maxPagesPerChannel": 5,
}

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

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

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

```

## CLI example

```bash
echo '{
  "channelUrls": [
    "https://www.youtube.com/@MrBeast"
  ],
  "maxPosts": 20,
  "maxPagesPerChannel": 5
}' |
apify call khadinakbar/youtube-community-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=khadinakbar/youtube-community-posts-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Community Posts Scraper",
        "description": "Scrape public YouTube Community posts from channel handles, channel URLs, channel IDs, or individual post URLs. Returns text, media, likes, timestamps, linked videos, and channel metadata. Public data only; no cookies required. $0.005 per saved post.",
        "version": "0.5",
        "x-build-id": "8j4X2KUKL9qaCIudL"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/khadinakbar~youtube-community-posts-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-khadinakbar-youtube-community-posts-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/khadinakbar~youtube-community-posts-scraper/runs": {
            "post": {
                "operationId": "runs-sync-khadinakbar-youtube-community-posts-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/khadinakbar~youtube-community-posts-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-khadinakbar-youtube-community-posts-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "channelUrls": {
                        "title": "YouTube channels",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Use this when you want recent public Community posts from one or more YouTube channels. Accepts a channel URL such as 'https://www.youtube.com/@MrBeast', a channel ID such as 'UCX6OQ3DkcsbYNE6H8uQQuVA', or a handle such as '@MrBeast'. The actor follows the Posts feed and paginates until maxPosts or maxPagesPerChannel. This is NOT a video URL or a specific community-post URL; use postUrls for an individual post.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "postUrls": {
                        "title": "Individual community post URLs",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Use this when you need known public YouTube Community posts rather than a channel feed. Each item must be a URL like 'https://www.youtube.com/post/Ugkx…'. The actor fetches the full public post record, including text, images, likes, channel data, and any linked video. Leave this empty to scrape channel feeds only. This is NOT a standard watch URL, Shorts URL, or a comment URL.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxPosts": {
                        "title": "Maximum posts",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Use this when you need to cap the total number of saved community-post records across every input. Enter an integer from 1 to 500; for example, 20 returns at most twenty deduplicated records. Defaults to 20 and also caps billable community-post events at the same number. This is NOT a per-channel limit, so several channels share this total.",
                        "default": 20
                    },
                    "maxPagesPerChannel": {
                        "title": "Maximum pages per channel",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Use this when a channel has a long Community feed and you want to bound pagination requests. Enter an integer from 1 to 50; for example, 5 allows up to five provider pages for each channel. Defaults to 5, and RUN_SUMMARY names channels with more pages available without exposing opaque provider tokens. This is NOT an exact post count because YouTube page sizes vary.",
                        "default": 5
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
