YouTube Community Posts Scraper
Pricing
from $5.00 / 1,000 community posts
YouTube Community Posts Scraper
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.
Pricing
from $5.00 / 1,000 community posts
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
5 days ago
Last modified
Categories
Share
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 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, 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. |
| Find currently trending videos | No | Use 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.
{"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.
{"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.
{"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
{"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.
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
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
import osfrom apify_client import ApifyClientclient = 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
@TEDwith one page per channel. ReturnpostId,postUrl,content,publishedAt,likeCount,imageUrls,videoUrl, andscrapedAt. ReadOUTPUTbefore deciding success. If the outcome isVALID_EMPTY, explain the likely public-availability boundary and do not invent posts. If it isINVALID_INPUT, correct the named field without retrying unchanged. Do not request private or login-only content.
Recommended agent sequence:
- Read the input schema and preserve numeric types.
- Start with a small
maxPostsandmaxPagesPerChannel. - Wait for a terminal run state.
- Read
OUTPUT, then retrieve dataset rows only when the outcome permits useful data. - Treat nullable fields as unknown, not zero or empty evidence.
- Use
postIdfor downstream deduplication andscrapedAtfor observation time. - If
continuationAvailableForis 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
maxPostsis shared across the whole run. Earlier inputs can consume the result cap. - Individual post URLs are processed before channel feeds.
publishedTimeTextandvideoPublishedTimeTextare display strings. PreferpublishedAtfor 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.