Facebook Groups Scraper - Facebook Group Posts, No Login
Pricing
from $2.50 / 1,000 posts
Facebook Groups Scraper - Facebook Group Posts, No Login
Facebook groups scraper, no login: public group links, ids or names in, one row per post out. Text, time, reactions by type, comments, shares, the author's public name and link, media, the post link and the group's exact member count. Free date window. Find groups by keyword. Misses free.
Pricing
from $2.50 / 1,000 posts
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
Facebook group posts as data, logged out. Give public group links (or a group's numeric id or name), or a single group post's link, and get one row per post: the whole text, the time to the second, the exact reactions by type, the comment and share counts, the author's public name and link, the photos and videos, the shared post, the post's link and its feedback id, and the group's exact member count on every row. Four orders (new posts, recent activity, top posts, listings), a free date window, filters by words and author, and up to 10 comments a post. Or give words and find public groups with their member count and privacy. Every input ends with a free row that says what was read and why it stopped. No login, no cookies, no browser, proxies handled for you.
From $5.00 per 1,000 rows (post) on the Free plan, $4.00 on Starter; every row and add-on is priced under Pricing below. A run start is $0.0045. The default input returns about 21 rows for about $0.1045. A private, missing or empty group is a free row that names its state, with the group's facts: you never pay for a group that gave no post.
Tested head-to-head on 2026-11-05
The job: the newest 20 posts of one public Facebook group by its link (Self-Taught Programmers, the schema's example input), new posts first. Every Actor ran on it the same day from the same harness; a rival's cost is what a buyer account paid, this Actor's is its list price on the Free plan. Fields counts the filled fields of a typical row. The lane's #2 by users/30d (datahamster/facebook-groups-search) finds groups by keyword and reads no group's posts: left out; the next group-posts seller by users/30d is curious_coder/facebook-post-scraper. Re-measured monthly.
| Actor | Rows | First row | Run time | Cost | Fields | Failures |
|---|---|---|---|---|---|---|
| this Actor | 20 | 11 s | 18 s | $0.10 | 42 | none |
apify/facebook-groups-scraper | 20 | 30 s | 39 s | $0.081 | 19 | none |
curious_coder/facebook-post-scraper | 20 | 5.4 s | 9.8 s | $0.021 | 12 | none |
Why this Facebook groups scraper
- No charge for an empty, private or missing group. A private group, a group id that does not exist, an empty group or a link that names no group gets one free row with its
status(private,not_found,invalid_input) and the reason, checked on a second connection before it saysnot_found. The lane's buyers report being charged for empty items; here only a delivered post or a found group is charged. - The date window is free.
onlyPostsNewerThanandonlyPostsOlderThancost nothing extra (the lane leader prices its date filter as an add-on), and every row is checked against the window before it is delivered: a post outside it is never charged. In the new-posts order the walk stops at the window's older end. - The group's facts on every row. One About page a group gives the exact member count ("373,967 total members", never the rounded "374K"), the privacy, the posts of the last day and the last month, the new-members line, the created date, the description and the rules on the group's row, and the member count and privacy on every post row.
- No silent short lists. The walk goes to Facebook's own end of the list and asks the end again on a second connection before it calls the group COMPLETE; every group's row says COMPLETE, CAPPED, DATE_LIMIT or PARTIAL with the reason, how many posts were read, and the cursor where it stopped.
- The author's link and the post's feedback id. The author's public profile link where Facebook links it in the group, and the post's
feedback_id, which our Facebook Comments Scraper takes to read every comment and reply of the post. - Find groups by keyword.
searchQuerieslists public groups for your words, each with its exact member count, privacy and activity, in a web index's order (Facebook's own group search is closed to a logged-out reader); filter by privacy and member range for free. - Speed, measured. On 16 runs of version 0.1.7 on Apify (2026-11-05, 512 MB: the deploy gate, five cost runs, a 300-post walk and the head-to-head run below) the first post came 2.9 to 9.7 seconds after the Actor started (each group's About page is read first, for its exact member count); a group's newest 20 posts were out by 10.7 to 18.5 seconds, 50 posts by 22.5, and one group's 300 posts by 169 seconds. The head-to-head card counts from the run's start request, the container's start included: 11 seconds to the first row on its run, 7.3 by the Actor's own clock.
Who it's for
- Community and market researchers — the posts of the groups where a topic is discussed, with their reactions, comments and the authors' public names, inside a date window, for a corpus or a trend report.
- Brand, product and support teams — the newest posts of a list of groups each morning (
onlyPostsNewerThanset to1 day), filtered by a product or brand name withtextContains. - Lead and partnership teams — groups about a keyword with their exact member counts and activity (
searchQueries,minMembers), then their newest posts.
Quick start
A group's newest 20 posts
{"startUrls": ["https://www.facebook.com/groups/selftaughtprogrammers/"],"resultsLimit": 20}
Two groups, the last week's posts, with comments
{"startUrls": ["https://www.facebook.com/groups/selftaughtprogrammers/","https://www.facebook.com/groups/874728723021553/"],"resultsLimit": 100,"onlyPostsNewerThan": "7 days","maxCommentsPerPost": 5}
Find groups by keyword
{"searchQueries": ["maths formulas"],"maxGroupsPerQuery": 10,"groupPrivacy": "public"}
Switching from apify/facebook-groups-scraper?
Your input works as it is. Each name in the left column is read as this Actor's own field and the run log says so (read <theirs> as <ours>); a name marked not read is ignored with a note. A value in the other Actor's shape, an object list or its own date form, is read too.
| apify/facebook-groups-scraper | this Actor | what to know |
|---|---|---|
startUrls | startUrls | The same name and shape: group links as strings or as {"url": …} items; a group's numeric id or name works too. |
resultsLimit | resultsLimit | The same name: posts per group. Unset here means 20; 0 means every post. |
viewOption | viewOption | The same name and the same four values: CHRONOLOGICAL, RECENT_ACTIVITY, TOP_POSTS, CHRONOLOGICAL_LISTINGS. |
onlyPostsNewerThan | onlyPostsNewerThan | The same name and forms: a date, a time or a span such as 7 days. |
What differs:
resultsLimitis 20 when you do not set it; 0 reads every post the group's feed serves.- The date window (
onlyPostsNewerThan, andonlyPostsOlderThan, which the leader does not have) is free here; the leader prices its date filter as an add-on. - The output columns are snake_case (
likes,comments,shares,group_name,author_name,media) where the leader's are camelCase (likesCount,commentsCount,sharesCount,groupTitle,user.name,attachments); each field's description names the leader's key. - Each input gets a free summary row (
record_type=target) beside its post rows; filter onrecord_type=postfor the posts alone. - A private, missing or empty group is a free row here, never a charged empty item.
Output
One row per post (and one free summary row for every input):
| field | meaning |
|---|---|
record_type | post on a post row (charged); group on a group a search found (charged); target on an input's free summary row (a group, a post link or a search you gave). |
status | ok, or why an input gave no row: not_found (no group or post by that link, id or name: Facebook answers an empty record or "This content isn't available" on two connections), private (a private group: only its members can see its posts; the row still carries the group's facts), invalid_input (a value that is not a Facebook group, group post or search, an empty value), duplicate (the same group as another value of the run, such as a group's name and its numeric id: its posts are on that value's rows), failed (Facebook refused every connection tried; run it again later), not_read (maxItems, your charge limit or the time limit came first). |
input | The value you gave that this row answers (the leader's inputUrl). |
post_id | Facebook's id of the post (the leader's legacyId). |
url | The post's own link, https://www.facebook.com/groups/<group>/posts/<id>/ (the leader's url). |
feedback_id | Facebook's id of the post's reactions and comments (the leader's feedbackId). Give it to our Facebook Comments Scraper for every comment and reply of the post. |
post_type | photo, album, video, reel, link (a link with its preview), shared (a shared post), listing (a buy-and-sell listing, listing has its fields), text, event or other, read from the post's attachment, never guessed from the text. |
is_video | True when the post carries a video or a reel. |
is_share | True when the post shares another post (shared_post has it). |
time | When the post was published, UTC, to the second (the leader's time). |
timestamp | The same time as Unix seconds. |
video_publish_time | When the video of a video post was uploaded, UTC (usually a minute before time). Null on other posts. |
text | The post's whole text, never cut (the leader's text); empty when the post has none (a photo alone, a share without words). |
text_length | The text's length in characters. |
hashtags | The hashtags of the text, without #, in order, each once. |
mentions | The people, pages, groups and apps the text tags, as Facebook publishes them with the post: type, id, name, url (the leader's textReferences). |
links_in_text | The links written in the text, unwrapped from Facebook's redirect. |
author_id | The id of the member or page that posted (the leader's user.id). |
author_name | The author's public name as Facebook shows it (the leader's user.name). |
author_url | The author's public profile link where Facebook links it in the group (63 % of posts on ordinary groups, stage 2), never built from the id; null otherwise. |
author_type | Facebook's own type for the author: user (a member; also a page in Facebook's new pages experience), page, group (a post by the group itself) or anonymous (a member who posted anonymously: the name is the one Facebook shows). |
reactions | All reactions, exact (the leader's likesCount). |
likes | The same as reactions (all reaction types, not only Like). |
reaction_types_count | How many reaction types the post has (the leader's topReactionsCount). |
reactions_like | Like reactions, exact; 0 when none (the leader's reactionLikeCount). |
reactions_love | Love reactions; 0 when none. |
reactions_care | Care reactions; 0 when none. |
reactions_haha | Haha reactions; 0 when none. |
reactions_wow | Wow reactions; 0 when none. |
reactions_sad | Sad reactions; 0 when none. |
reactions_angry | Angry reactions; 0 when none. |
comments | The post's comment count as Facebook gives it, replies included (the leader's commentsCount). |
shares | The post's share count (the leader's sharesCount). |
video_views | Video views (Facebook's video_view_count), exact. Null on a post with no video. |
video_plays | Video plays (Facebook's play_count), exact, when Facebook gives it. Null otherwise. |
video_post_views | Views of the video in this post (Facebook's video_post_view_count), when given. |
media | The post's photos and videos, in order (the leader's attachments): type (photo or video), id, url (the full-size photo or the video's page), width, height, alt_text (Facebook's description of a photo, the leader's ocrText), video_hd_url, video_sd_url, thumbnail_url, duration_s. The file links are Facebook's own and stop working after some days. |
media_count | How many photos or videos the post holds (an album's or a listing's own count, which can be more than media lists). |
media_truncated | True when the post holds more photos than media lists: Facebook sends a logged-out reader at most 5 photos of an album or a listing. |
video_captions_url | The video's captions file (.srt) when Facebook has one; null otherwise. |
link | A link post's preview: url (the target, unwrapped), title, description, domain, image_url. Null on other posts. |
event | An event post's event: id, name, url, when, place. Null on other posts. |
shared_post | The post this post shares: post_id, url, author_name, author_id, author_url, text, time, media, media_count, media_truncated. Its own counts are not given by Facebook in the sharing post. Null on other posts. |
listing | A buy-and-sell listing's own fields: id, title, price (as Facebook shows it, such as "Contact seller" or "$40"), location, is_sold, and marketplace_url for a Marketplace item posted to the group. Null on an ordinary post: a price is never read from a post's text. |
top_comment | The first top comment Facebook shows with the post: id, text, time, likes, replies, author_name, author_id, author_url, url. Null when the post shows none. |
top_comments | With maxCommentsPerPost 1-10: up to that many comments of the post from one more call, each as in top_comment (the leader's topComments); else the top comment alone. |
comments_status | served (the comments call answered), none (the post has no comment: no call), refused (Facebook refused the call; the row is delivered without them), not_asked (maxCommentsPerPost is 0, or the post came already). |
group_id | The group's numeric id, on every row. |
group_name | The group's name (the leader's groupTitle), on every row. |
group_url | The group's link (the leader's facebookUrl). |
group_members | On a post row: the group's exact member count, from its About page once a run (includeGroupInfo). Null with includeGroupInfo off, or on a row read from a post link. |
group_privacy | On a post row: public (the posts this Actor reads come from public groups). |
privacy | On a group or input row: public or private, from the group's About page. |
privacy_text | The About page's own line: "Anyone can see who's in the group and what they post." or "Only members can see …". |
visibility | visible (anyone can find the group) or hidden, from the About page. |
members | The group's exact member count ("373,967 total members" on its About page); it moves by the hour. |
members_text | The About page's member line as served. |
new_members_text | The About page's new-members line as Facebook serves it to a logged-out reader ("No new members in the last week" on every group read in testing, a busy one too: the count is for members). |
posts_last_day | Posts in the group in the last day, as the About page counts them. |
posts_last_month | Posts in the group in the last month, as the About page counts them. |
created_at | When the group was created, UTC. |
description | The group's own description. |
rules | The titles of the group's rules, in order. |
rules_count | How many rules the group lists. |
cover_url | The group's cover photo (a Facebook link that expires). |
view | On a group's input row: the order read (CHRONOLOGICAL new posts, RECENT_ACTIVITY, TOP_POSTS, CHRONOLOGICAL_LISTINGS). |
verdict | On an input row: COMPLETE (read to the list's own end, read twice), CAPPED (resultsLimit, maxGroupsPerQuery, maxItems or your charge limit reached; next_cursor says where), DATE_LIMIT (the date window's older end reached) or PARTIAL (stopped early: note says why). |
rows_delivered | On an input row: the post rows (or, for a search, the group rows) it delivered and charged. |
posts_read | On a group's input row: the posts read, the ones the filters left out included. |
newest_time | On a group's input row: the newest post time read. |
oldest_time | On a group's input row: the oldest post time read; give it as onlyPostsOlderThan to read on from there. |
calls | On a group's input row: the feed calls the walk made (3 posts a call). |
next_cursor | On a group's input row: Facebook's cursor where the walk stopped (CAPPED, PARTIAL), null at the list's end. |
search_query | On a found group's row and its search's input row: the words searched. |
search_engine | The web index that listed the groups (yahoo, else bing): Facebook's own group search is closed to a logged-out reader. |
search_rank | On a found group's row: its place in the web index's order (1 = first). |
note | Why an input row has the status or the verdict it has. |
scraped_at | When this row was read (UTC). |
story_id | Facebook's own id of the post's feed story (the leader's id, the UzpfS… form). |
author_picture_url | The author's profile picture as Facebook shows it beside the post (a Facebook link that expires). |
author_is_verified | True when Facebook shows the verified badge beside the author's name on the post, false when it shows none; null when the post has no name line to read. |
locations | The places the group's admins set on its About page (such as "Barcelona, Spain"); empty when they set none. |
topics | The topics the group's admins set on its About page (such as "Mathematics"); empty when they set none. |
Example record:
{"record_type": "post","status": "ok","input": "https://www.facebook.com/groups/306490195164828/","post_id": "1150908894056283","url": "https://www.facebook.com/groups/306490195164828/posts/1150908894056283/","feedback_id": "ZmVlZGJhY2s6cGZiaWQwMk45eTNFV21xU0g4clFrd0xWYWtqUlYxVXN5d3lIelpBbUdXckVEeFBtVDVNQzNuN3VWaVBvQWhFRWt0ZkNvN1hs","post_type": "text","is_video": false,"is_share": false,"time": "2026-11-05T09:17:21Z","timestamp": 1793870241,"video_publish_time": null,"text": "Should we cut back hydrangeas please","text_length": 36,"hashtags": [],"mentions": [],"links_in_text": [],"author_id": "2292218444903000","author_name": "Anonymous participant","author_url": null,"author_type": "anonymous","reactions": 1,"likes": 1,"reaction_types_count": 1,"reactions_like": 1,"reactions_love": 0,"reactions_care": 0,"reactions_haha": 0,"reactions_wow": 0,"reactions_sad": 0,"reactions_angry": 0,"comments": 16,"shares": 0,"video_views": null,"video_plays": null,"video_post_views": null,"media": [],"media_count": 0,"media_truncated": false,"video_captions_url": null,"link": null,"event": null,"shared_post": null,"listing": null,"top_comment": {"id": "1150949240718915","text": "(a member's comment)","time": "2026-11-05T09:18:55Z","likes": 8,"replies": 0,"author_name": "A member","author_id": "100000000000001","author_url": null,"url": "https://www.facebook.com/groups/306490195164828/posts/1150908894056283/?comment_id=1150949240718915"},"top_comments": [{"id": "1150949240718915","text": "(a member's comment)","time": "2026-11-05T09:18:55Z","likes": 8,"replies": 0,"author_name": "A member","author_id": "100000000000001","author_url": null,"url": "https://www.facebook.com/groups/306490195164828/posts/1150908894056283/?comment_id=1150949240718915"}],"comments_status": "not_asked","group_id": "306490195164828","group_name": "Gardening tips and tricks","group_url": "https://www.facebook.com/groups/306490195164828/","group_members": 99470,"group_privacy": "public","privacy": null,"privacy_text": null,"visibility": null,"members": null,"members_text": null,"new_members_text": null,"posts_last_day": null,"posts_last_month": null,"created_at": null,"description": null,"rules": null,"rules_count": null,"cover_url": null,"view": null,"verdict": null,"rows_delivered": null,"posts_read": null,"newest_time": null,"oldest_time": null,"calls": null,"next_cursor": null,"search_query": null,"search_engine": null,"search_rank": null,"note": null,"scraped_at": "2026-11-05T09:44:40Z","story_id": "UzpfSTIyOTIyMTg0NDQ5MDMwMDA6Vks6MTE1MDkwODg5NDA1NjI4Mw==","author_picture_url": null,"author_is_verified": false,"locations": null,"topics": null}
Pricing
Pay per post delivered and per group a search finds, plus one run start; no platform usage and no proxy traffic is billed to you.
| event | unit | Free | Starter | Scale | Business |
|---|---|---|---|---|---|
Post (post) | per 1,000 | $5.00 | $4.00 | $3.30 | $2.50 |
Group found (group) | per 1,000 | $3.00 | $2.55 | $2.10 | $1.50 |
Run start (start) | per run | $0.0045 | $0.0045 | $0.0045 | $0.0045 |
A post is $5.00 per 1,000 on the Free plan ($0.005 a post) and $4.00 on Starter. Everything the row carries is inside that price: the text, the time, the reactions by type, the comment and share counts, the author's public name and link, the media, the shared post, the post's link and feedback id, the group's member count and privacy, and the comments of maxCommentsPerPost. The date window is free: no add-on for onlyPostsNewerThan / onlyPostsOlderThan, and none for textContains or authorContains. A group a keyword search finds and delivers is $3.00 per 1,000 on the Free plan and $2.55 on Starter; a group you give as a link is never charged. Each run that delivers a charged row also pays the run start, $0.0045 once; a run that delivers none pays nothing at all. So one post costs $0.0095 on the Free plan and $0.0085 on Starter; a group's newest 20 posts $0.1045 and $0.0845; 1,000 posts $5.0045 and $4.0045; a search that finds 10 groups $0.0345 and $0.03. Free: every input's summary row, a private, missing or empty group, a value that is not a group link, a post given twice, a group a search found outside your privacy or member range, a post a filter or the date window leaves out, and an input left unread at maxItems, your charge limit or the time limit. A run that stops early (a timeout, an abort) is charged for the rows it delivered. maxItems counts the charged rows across inputs. Before the first request the log names the price of a post (and of a group found) at your plan, the run start and the most the run can cost when resultsLimit, maxGroupsPerQuery or maxItems bounds it (under your charge limit). With resultsLimit 0 and no maxItems there is no such bound: Facebook gives no count of a group's posts ahead, and a list's end is far apart from group to group (a small group of our tests ended at 62 posts, read to its end twice; a group of 710 members still had posts after 300, back six months), so set resultsLimit, maxItems or a charge limit for a deep walk. Enterprise plans have their own rates — the Actor's Pricing tab shows the price for your plan.
Usage patterns
- Deep walks, the orders and the date window —
resultsLimit(20 unless you set it) counts the posts delivered from each group after the filters; 0 reads every post the group's feed serves, 3 posts a call, to Facebook's own end.viewOptiontakes the group's own orders:CHRONOLOGICAL(new posts, the default),RECENT_ACTIVITY,TOP_POSTS,CHRONOLOGICAL_LISTINGS(buy-and-sell listings).onlyPostsNewerThan/onlyPostsOlderThantake a date (2026-09-01), a time (2026-09-01T12:00:00Z) or a span back from now (7 days,2 months).maxItemscaps the whole run's charged rows. A group's walk is one page after another (Facebook's cursor), so several groups in one run read at the same time and one deep group takes about 2 seconds a call. - Filters and comments —
textContainskeeps the posts whose text or shared text holds any of your words,authorContainsthe posts whose author's name holds any of yours (both case-insensitive); a filtered walk reads 20 calls, then 7 a delivered post, and its row says how many matched. A post a filter leaves out is free.maxCommentsPerPost1-10 adds up to that many comments a post from one more call (free); every comment and reply is our Facebook Comments Scraper's job, by the row'sfeedback_id. - What a row is —
record_type=post: one post, charged.record_type=group: one group a search found, charged.record_type=target: one free row per input with itsstatus,verdict,rows_delivered,posts_read, the newest and oldest post time read, the group's facts and anotesaying why it stopped. The photo and video links are Facebook's own and stop working after some days: download what you keep.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
startUrls | array | [] | One per line. A public group's link (https://www.facebook.com/groups/selftaughtprogrammers/, /groups/ |
resultsLimit | integer | 20 | The posts to deliver from each group, after the filters below. 0 = every post the group's feed serves, to the list's own end (3 posts a call: a deep walk takes time). Empty = 20. |
viewOption | CHRONOLOGICAL / RECENT_ACTIVITY / TOP_POSTS / CHRONOLOGICAL_LISTINGS | "CHRONOLOGICAL" | The group's own sort: new posts first (the default), recent activity, top posts, or buy-and-sell listings (newest first). The date window stops a new-posts walk at its older end; in the other orders it is a filter. |
onlyPostsNewerThan | string | Only posts from this time on: a date (2026-10-01, 00:00 UTC), a time (2026-10-01T12:00:00Z) or a span back from now (7 days, 2 months). Free (no add-on price): a new-posts walk stops at the first older post. | |
onlyPostsOlderThan | string | Only posts up to this time: a date (2026-10-01 = up to 00:00 UTC that day), a time or a span back from now. The newer posts are read on the way (at most 100 calls) and not delivered. | |
textContains | array | [] | Deliver only the posts whose text (or the shared post's text) contains any of these words, case-insensitive. A filtered walk reads 20 calls, then 7 a delivered post, and its group row says how many matched. |
authorContains | array | [] | Deliver only the posts whose author's public name contains any of these words, case-insensitive. |
includeGroupInfo | boolean | true | Read each group's About page once (one call a group): the exact member count, the privacy, posts in the last day and month, the created date, the description and the rules, on the group's row, and the member count and privacy on every post row. Off: a numeric id's posts are read with no page call (a group name still needs it). |
maxCommentsPerPost | integer | 0 | 0 = the first top comment the post itself carries (no extra call); 1-10 = up to that many comments, from one more call a post that has comments (slower). Free either way. Every comment and reply of a post: give its feedback_id to our Facebook Comments Scraper. |
searchQueries | array | [] | One search a line (maths formulas). Each gives up to maxGroupsPerQuery public groups in a web index's order (Facebook's own group search is closed to a logged-out reader), one row a group with its exact member count and privacy. The groups' posts are not read: put the links you want in Facebook groups above. |
maxGroupsPerQuery | integer | 10 | The most groups to deliver for each search (1-50). |
groupPrivacy | any / public / private | "any" | Deliver only the found groups of this privacy. |
minMembers | integer | 0 | Deliver only the found groups with at least this many members (the exact count); 0 = no bound. |
maxMembers | integer | 0 | Deliver only the found groups with at most this many members; 0 = no bound. |
maxItems | integer | 0 | The most charged rows of the whole run (posts and found groups), across all inputs; 0 = no cap beyond your charge limit. |
proxyUrl | string | Your own proxy (scheme://user:pass@host:port) for every call instead of ours. Leave empty: the Actor brings its own connections at no cost to you. |
Errors
A run does not fail because of your input. When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends Succeeded, charges nothing, and says what to change:
- the status message starts with
INPUT REJECTED; - the dataset holds one row,
{"error": true, "code": "…", "message": "…"}, and no results; - the key-value store record
ERRORholds the same object.
From code, check error on the first row before reading results.
A private group, a group that does not exist, an empty group, or a value that is not a Facebook group link is not an error: it gets one free row with its status and the reason (with the group's member count and privacy when Facebook shows them), and the run goes on with the others. A run that ends Failed is a fault on our side, never your input; it charges nothing, and we are alerted.
FAQ
Which status and verdict is which?
A post or group row is ok. An input row: ok with a verdict (COMPLETE: read to Facebook's own end, read twice; CAPPED: resultsLimit, maxGroupsPerQuery, maxItems or your charge limit reached; DATE_LIMIT: the window's older end reached; PARTIAL: stopped early, the note says why), or free: private (a private group: only members see its posts), not_found (no such group or post, on two connections), invalid_input (not a group link, an empty value), duplicate (the same group as another value of the run), failed (Facebook refused every connection tried; run it again later), not_read (maxItems, your charge limit or the time limit came first).
Can it read private groups?
No. A private group's posts are for its members, and this Actor uses no account. A private group gets a free row with its name, member count and privacy, so you know what it is.
Does it read every post a group has?
It reads what the group's logged-out feed serves, in the order you choose, to Facebook's own end flag. A group whose feed is mostly one admin's posts (welcome posts, for one) is served as Facebook lists it. An album gives its first 5 photos with the album's real count beside them.
Why does the group search not find my group by its exact name?
Facebook's own group search is closed to a logged-out reader, so the search reads a web index (site:facebook.com/groups <words>) and gives the groups in its order. A large group the index does not list for your words can be missing; give its link in startUrls instead.
Does it need a Facebook account, cookies or an API key?
No. Everything is read from Facebook's public, logged-out pages: no login, no cookie, no token of yours. The connections are included in the price.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/facebook-groups-scraper').call({"startUrls": ["https://www.facebook.com/groups/selftaughtprogrammers/"], "resultsLimit": 20});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/facebook-groups-scraper').call(run_input={'startUrls': ['https://www.facebook.com/groups/selftaughtprogrammers/'], 'resultsLimit': 20})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/facebook-groups-scraper --input '{"startUrls": ["https://www.facebook.com/groups/selftaughtprogrammers/"], "resultsLimit": 20}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~facebook-groups-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"startUrls": ["https://www.facebook.com/groups/selftaughtprogrammers/"], "resultsLimit": 20}'
AI agents and MCP
Apify's MCP server offers this Actor as a tool to Claude, Cursor, VS Code and any other MCP client. Connect https://mcp.apify.com?tools=hyperbach/facebook-groups-scraper and ask, for example: "Get the newest 50 posts of the public Facebook group selftaughtprogrammers with their reactions, comments and authors". The agent fills the input from the table above and reads the rows from the run's dataset. A field under the name another Actor gives it is read as this Actor's own: urls, url, links, groupUrls as startUrls; search, searchQuery, queries, query as searchQueries; maxPosts, postsLimit, maxPostsPerGroup, postsPerGroup as resultsLimit; sortBy, sort, sorting, sortingSetting as viewOption (and more).
n8n, Make and Zapier
The Apify node in n8n, the Apify app in Make and the Apify integration in Zapier run this Actor on a schedule or from a trigger and read its dataset. A webhook on the run's end (Integrations on the Actor page) sends the rows on to your own endpoint. Nothing to install on our side.
Support
Disagree with a charge? Write to apify@hyperbach.com with the run ID. We will ask Apify to compensate you, and the charge comes back to your Apify account as platform credit.
Did it do the job? A short review on the Store, at any rating, helps the next buyer choose.
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.