# Facebook Groups Search: Groups That Allow Promotion (`firsthand/facebook-groups-search`) Actor

Find Facebook groups by keyword and location, no Facebook account needed. Exact member count, posts per day and month, privacy, rules and whether the group allows self-promotion, plus websites and emails it published. Monitor new Facebook groups on a schedule with webhook or Telegram alerts.

- **URL**: https://apify.com/firsthand/facebook-groups-search.md
- **Developed by:** [Firsthand](https://apify.com/firsthand) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 group returneds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Facebook Groups Search: Groups That Allow Promotion

Find Facebook groups (public and private) by keyword and location and get one row per group:

- exact member count;
- posts in the last day and month and an activity level;
- privacy, location, rules and creation date;
- **whether the group's rules allow self-promotion**, read by an AI model;
- websites and emails the group published itself.

No Facebook account, no cookies.

Use it to find where your customers talk and where you are allowed to post: real estate investors in Texas,
dog owners in London, Shopify sellers, yoga teachers in Kyiv. Turn on **Monitor** mode and a scheduled task sends you
only the groups you have not received before.

### What you get

| name | membersCount | postsLastMonth | activityLevel | promotionPolicy | privacy | locations |
|---|---|---|---|---|---|---|
| Texas Real Estate Investors Network (TREIN) | 31355 | 2304 | very_active | restricted | Public | Dallas, Texas |
| Shopify App Founders | 5033 | 32 | active | restricted | Private | |
| Shopify Australia | 12066 | 104 | active | forbidden | Private | Australia |
| Kyiv Yoga Teachers Club | 494 | 0 | dead | forbidden | Private | Kyiv, Ukraine |

The numbers are from our test runs in October 2026 and change over time.

```json
{
  "groupId": "279017812501607",
  "name": "South London Acro Yoga",
  "url": "https://www.facebook.com/groups/southlondonacro/",
  "membersCount": 1536,
  "privacy": "Public",
  "visibility": "Visible",
  "postsLastDay": 0,
  "postsLastMonth": 5,
  "activityLevel": "low",
  "postsPer1kMembers": 3.3,
  "promotionPolicy": "restricted",
  "promotionRules": [
    "No unrelated promotions or spam"
  ],
  "createdAt": "2017-01-08",
  "history": "Group created on January 8, 2017. Name last changed on July 30, 2017.",
  "locations": [],
  "adminsCount": 5,
  "hasMembershipQuestions": false,
  "imageUrl": "https://scontent.xx.fbcdn.net/...",
  "rules": [
    {
      "title": "No unrelated promotions or spam",
      "description": "Give more to this group than you take. Self-promotion, spam and irrelevant links aren't allowed. Any promotion just relate directly to acro in South London."
    }
  ],
  "websites": [
    "https://www.southlondonacro.co.uk"
  ],
  "emails": [],
  "facebookLinks": [],
  "query": "yoga London",
  "keyword": "yoga",
  "searchLocation": "London",
  "foundBy": "yahoo",
  "status": "ok"
}
```

Every row has a `status`:

- `ok`: a group, charged;
- `not_found`: a group link that is deleted or not visible without login;
- `error`: the page did not open;
- `duplicate`: two links to the same group;
- `skipped`: your limit was reached.

Only `ok` rows are charged.

In our test runs of 106 groups, every row had the exact member count, posts per month and creation date. Of
those, 98 had a description, 77 a location and 58 rules.

### How to search Facebook groups by keyword

1. Put one or more **Search keywords**, for example `real estate investors texas`.
2. Optionally set filters:
   - **Min members** and **Max members**;
   - **Privacy**;
   - **Min posts in the last month**;
   - **Location contains**;
   - **Promotion rules**.
3. Run. Results are in the dataset (table, JSON, CSV, Excel) or through the API.

To enrich groups you already have, put their links in **Group URLs**. Both `/groups/<name or id>/` links and
`/share/g/<code>/` share links work. Groups you list yourself are always returned: the filters apply only to
groups found by keywords.

**Keyword match.** By default a group is kept only if every word of the keyword is in its name or search
description. So `dog training london` does not return general London neighbourhood groups, and
`real estate investors texas` does not return a group named "Houston Real Estate Investors". Switch to *Any word* or
*Off* for a wider list.

### Search Facebook groups by location

Put cities, regions or countries in **Search locations**. Every keyword is searched with every location:
`yoga` with `London` and `Manchester` runs `yoga London` and `yoga Manchester`. Each row says which `keyword` and
`searchLocation` found it.

**Location contains** is a different thing. It keeps only groups whose own Facebook location matches your text. Many
groups set no location, so this filter is stricter.

### Find Facebook groups that allow self-promotion

An AI model reads each group's rules and sets `promotionPolicy`:

| value | meaning |
|---|---|
| `allowed` | the rules allow members to promote their business openly |
| `restricted` | promotion is allowed with a condition: a promo thread or day, admin approval, "within reason", only on-topic offers |
| `listings_only` | a deals or buy-and-sell group: you may post your own listings (for example properties), not promote a business |
| `forbidden` | the rules ban self-promotion, ads or selling, or allow them only for admins or as paid sponsorship |
| `not_mentioned` | the group has rules, but none is about promotion |
| `no_rules` | no rules were found on the group's About page |
| `unknown` | the rules could not be read this time |

`promotionCondition` says the condition in a few words, for example "only in the Friday promo thread" or "only
off-market property listings". `promotionRules` lists the titles of the rules behind the decision, so you can check
them in `rules`.

**Promotion rules** filter:

- *Allowed* keeps `allowed` and `restricted`.
- *Allowed or listings* also keeps `listings_only`.
- *Not forbidden* drops only the explicit bans.

To read the rules, the Actor has to open every group page. In our tests about one group in eight allowed promotion.
So a group that passed your other filters and was skipped by this one is charged as a screening at $0.002. Groups
skipped by the other filters are free, and so are groups whose rules could not be read (`unknown`).

What to expect: of 160 groups from our test runs, 85 had rules. The model marked:

- 20 as allowing promotion with conditions;
- 10 as listings only;
- 44 as banning promotion;
- 11 as not mentioning it.

Rules in any language are read: we tested English, Russian, Ukrainian, German, Spanish, Portuguese, French,
Italian, Dutch, Polish, Turkish and Vietnamese.

How reliable it is: we tried 158 tricky ban wordings collected while testing the Actor, such as "No ads - all posts
need admin approval", "La publicité n'est pas autorisée" and "Promotions are allowed for group admins only". The
model read none of them as permission. Of 45 real conditions, it read 3 as bans. It is still a reading of the
rules, not a promise from the admins: read the rules in `promotionRules` before you post.

### How to find active Facebook groups

- `activityLevel` comes from posts in the last month:
  - `dead`: 0;
  - `low`: 1 to 29;
  - `active`: 30 to 299;
  - `very_active`: 300 or more.
- `postsPer1kMembers` is posts per month per 1,000 members. A group with 100,000 members and 50 posts a month has
  a big number on the door but a quiet feed.
- Use **Min posts in the last month** to skip quiet groups for free.

### Contacts the group published

`websites`, `emails` and `facebookLinks` are taken from the group's own description and rules: the community's site,
a WhatsApp or Telegram link, the organiser's page. The Actor makes no extra requests for them and never looks up
admins or members. In our test runs, 12% of groups published a website and 6% an email. Turn off **Include
contacts** if you do not need them.

### Monitor new Facebook groups

Set **Mode** to *Monitor* and save the input as a task with a schedule (daily or weekly). Each run returns only
groups that this monitor has not returned before (`changeType: new`). Good to know:

- "New" means new to you, not newly created. Monitor reads the top search results for each keyword, so a group
  appears once search engines rank it there.
- If you relax your filters later (for example lower **Min members**), groups skipped earlier are returned as new.
- **Re-check known groups** also opens groups returned earlier. It returns the ones whose member count or privacy
  changed (`changeType: changed`, `previousMembersCount`, `membersChange`). Groups from **Group URLs** are always
  re-checked in Monitor mode.
- **Webhook URL** receives a POST with `newGroups` and `changedGroups` after a run with changes.
- **Telegram bot token** and **Telegram chat ID** send a short summary to your chat: members, posts a month and the
  promotion policy of each new group.

Each saved task keeps its own memory. Without a task, the memory is kept per set of keywords, locations and URLs,
or under your own **Monitor ID**.

### How much does it cost to find Facebook groups?

Pay per result, proxies included:

| Event | Price |
|---|---|
| Group returned (a row with `status: ok`) | $0.00299 ($2.99 per 1,000 groups) |
| Group re-checked in Monitor mode that returned no row | $0.0015 |
| Group opened and skipped by the **Promotion rules** filter (only when that filter is on) | $0.002 |
| Run start | $0.005 per run (one event per GB of memory; the default 512 MB is one event) |

Not charged: groups removed by your other filters (members, privacy, activity, location, keyword), deleted
groups, duplicates and failed pages.

Set **Max groups in total** for a hard cap on returned groups. The Actor also stops before your maximum cost per
run. If your filters remove almost every group, the Actor stops early instead of opening hundreds of pages.

**With the Promotion rules filter on**, a returned group costs much more in total, because several groups are
screened for each one that allows promotion. In our test, "shopify sellers" and "dog training london" gave 6
groups for $0.097:

- $0.005 for the start;
- $0.018 for the 6 groups;
- $0.074 for 37 screenings.

If you want the whole list anyway, leave the filter off. Every row has `promotionPolicy`, so you can sort and filter
the dataset yourself at $0.00299 per group.

To keep a keyword with no such groups from eating your budget, the Actor stops screening a keyword after about 20
groups plus 10 for every group it returns. Pages already loading finish, so it can be up to 10 more.
**Max groups in total** counts returned groups only, so with this filter use your maximum cost per run as the
hard cap.

Example without the Promotion rules filter: 100 groups cost $0.304 ($0.299 for the groups plus $0.005 for the
start).

### Use it with n8n, Make, Zapier or the API

Run the Actor from the Apify API, the JavaScript and Python clients, or the Apify integrations for n8n, Make and
Zapier, and get the dataset as JSON, CSV or Excel. In Monitor mode the webhook sends new groups to your own endpoint
after each scheduled run.

### Search Facebook groups without an account: good to know

- Facebook's own group search works only for logged-in users. This Actor finds groups through public web search
  (DuckDuckGo and Yahoo), the way a person without an account would. So it returns groups that search engines
  have indexed. Very new or hidden groups may be missing.
- For each keyword the Actor reads up to 10 DuckDuckGo and 20 Yahoo result pages. How many groups a keyword gives
  depends on what search engines have indexed and changes from run to run.
  - Our latest test with Keyword match *All words* and up to 100 per keyword: "real estate investors texas" gave
    67 groups, "shopify sellers" 45.
  - Earlier runs that read only 10 Yahoo pages: "yoga kyiv" gave 7-10, "dog training london" 5-7.
  - *Any word* gives more, but less precise.
- Speed: 70-112 groups took 1-2 minutes in our tests.
- Private groups come with their About information: members, activity, rules. Their posts are not visible without
  joining and are not collected.
- `adminsCount` is `null` when Facebook does not show it without login, which is the case for most private
  groups.
- The Actor reads only group About pages. It does not collect posts or member lists.
- If a run fails or times out, Apify sends the run record to the developer. The record has no input and no
  results. It is used only to find and fix the cause.

### FAQ

**Is it legal?** The Actor reads public group information that Facebook shows to anyone without logging in.
Facebook's terms restrict automated collection, and GDPR applies if you store personal data. Emails and links in
descriptions and rules are published by group admins and may belong to a person. You are responsible for how you
use the data.

**Why are some member counts rounded?** Facebook shows the exact number on the About page for almost every
group (`membersCountExact: true`). When only a rounded value like "6.4K" is available, `membersCountExact` is
`false`.

**Why did a keyword return fewer groups than I asked for?** Search engines had no more groups matching all words
of the keyword within the result pages the Actor reads, or your filters removed them. The run status shows how
many were filtered out. Try *Any word* or a broader keyword.

**Can I trust `promotionPolicy` blindly?** No. It is a reading of the rule text and saves you from opening hundreds
of groups. Before posting, read the rules listed in `promotionRules`. Admins can also change rules at any time.

This Actor is not affiliated with Meta or Facebook.

# Actor input Schema

## `queries` (type: `array`):

What the groups should be about, one keyword or phrase per line, for example "dog training london" or "real estate investors texas". Each keyword is searched separately. Up to 50 keywords per run.

## `searchLocations` (type: `array`):

Optional cities, regions or countries. Every keyword is searched with every location, for example "yoga" with "London" and "Manchester" gives "yoga London" and "yoga Manchester". Up to 200 keyword and location pairs per run.

## `groupUrls` (type: `array`):

Facebook groups to read directly: https://www.facebook.com/groups/<name or id>/ or a share link https://www.facebook.com/share/g/<code>/. Use it to enrich a list you already have or to track known groups in Monitor mode. Up to 1,000.

## `maxGroupsPerQuery` (type: `integer`):

Stop a keyword after this many groups are returned. Up to 100. The Actor reads up to 10 DuckDuckGo and 20 Yahoo result pages per keyword; within them our tests gave 5 to 67 groups per keyword with Keyword match All words.

## `maxItems` (type: `integer`):

Hard cap on returned group rows in this run across all keywords. 0 means no cap. Screenings by the Promotion rules filter are not rows, so with that filter on use your maximum cost per run as the cap. The run also stops before your maximum cost per run is exceeded.

## `keywordMatch` (type: `string`):

All words: keep a group only if every word of the keyword is in its name or search description (default). Any word: at least one word. Off: every group the search returns.

## `minMembers` (type: `integer`):

Skip groups smaller than this. Skipped groups are not charged.

## `maxMembers` (type: `integer`):

Skip groups larger than this, handy for small niche communities. Skipped groups are not charged.

## `privacy` (type: `string`):

Public groups show posts to anyone; private groups show only their About info (name, members, activity, rules).

## `minPostsPerMonth` (type: `integer`):

Keep only active groups. Facebook shows the number of posts in the last month on the group's About page.

## `locationContains` (type: `string`):

Keep only groups whose Facebook location contains this text, for example "Florida" or "London". Many groups have no location set. To search in a place, use Search locations instead.

## `promotionPolicy` (type: `string`):

An AI model reads each group's rules. Allowed: groups that allow promotion openly or with conditions (a promo thread or day, admin approval, in moderation, only on topic). Allowed or own listings only: also deals and buy-and-sell groups where you may post your own listings. Not forbidden: every group except the ones whose rules ban promotion. Reading rules needs the group page, so a group skipped by this filter is charged as a screening ($0.002). A keyword stops after about 20 screenings plus 10 per returned group. Other filters stay free.

## `includeContacts` (type: `boolean`):

Return websites, emails and Facebook links that the group published in its own description and rules. Turn off if you do not need them.

## `mode` (type: `string`):

Search: return every matching group. Monitor: return only groups this monitor has not returned before. Schedule a saved task to get new groups every day or week. Monitor reads the top search results, so a new group shows up once search engines rank it there.

## `monitorId` (type: `string`):

Optional name for the monitor's memory. By default a saved task keeps its own memory, and a run without a task uses its keywords, locations and URLs.

## `recheckKnownGroups` (type: `boolean`):

Monitor mode: also open every group returned earlier and return the ones whose member count or privacy changed. Groups that do not pass your current filters are not returned. Each re-check that returns no row is charged as a group check. Group URLs are always re-checked in Monitor mode.

## `webhookUrl` (type: `string`):

Monitor mode: HTTPS address that receives a POST with the new and changed groups after each run with changes.

## `telegramBotToken` (type: `string`):

Monitor mode: token of your Telegram bot (from @BotFather) to send a summary of new and changed groups.

## `telegramChatId` (type: `string`):

Monitor mode: chat that receives the summary, for example -1001234567890. Add the bot to the chat first.

## Actor input object example

```json
{
  "queries": [
    "real estate investors texas"
  ],
  "maxGroupsPerQuery": 10,
  "maxItems": 0,
  "keywordMatch": "all",
  "privacy": "any",
  "promotionPolicy": "any",
  "includeContacts": true,
  "mode": "search",
  "recheckKnownGroups": false
}
```

# Actor output Schema

## `groups` (type: `string`):

Groups found in this run.

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "queries": [
        "real estate investors texas"
    ],
    "maxGroupsPerQuery": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("firsthand/facebook-groups-search").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 = {
    "queries": ["real estate investors texas"],
    "maxGroupsPerQuery": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("firsthand/facebook-groups-search").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "queries": [
    "real estate investors texas"
  ],
  "maxGroupsPerQuery": 10
}' |
apify call firsthand/facebook-groups-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,firsthand/facebook-groups-search"
        }
    }
}
```

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

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/wit17ekJZeno7awXA/builds/6ge74d2pei37T2jH9/openapi.json
