# Facebook Search Scraper - Pages, Posts, Videos & Groups (`automation-lab/facebook-multi-vertical-public-search-results`) Actor

Search Facebook by keyword and export public pages, posts, videos, reels and groups with IDs, names, text, authors, dates, engagement and URLs. No login or cookies.

- **URL**: https://apify.com/automation-lab/facebook-multi-vertical-public-search-results.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Social media, Lead generation
- **Security:** Limited permissions
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 search results

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

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

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Facebook Search Scraper - Pages, Posts, Videos & Groups

**Facebook Search Scraper** searches Facebook by keyword and exports public **pages, posts, videos and reels, and groups** from one run. It can also return people, places and events. Every row keeps the keyword that found it, the result type and its rank, so you can track brands, campaigns and topics over time.

No Facebook account, cookies or login are needed. The Actor reads Facebook's own logged-out search results, not Google `site:` results.

### What does Facebook Search Scraper do?

- Searches Facebook for each keyword you enter, one tab at a time: **Pages, Posts, Videos, Groups, People, Places, Events**.
- Saves one structured row per result card, with a shared set of columns across all result types.
- Pages: name, Facebook ID, URL, description snippet, website, verified badge, profile picture.
- Posts: text, permalink, author, group the post was shared in, exact publish time, reactions, comments, shares, attachment type and image.
- Videos and reels: title or caption, video ID, URL, creator, publish time, views, reactions, comments, shares, duration, thumbnail.
- Groups: the public groups that matching posts were shared in, with group ID, name, URL and how many matching posts were found there.
- Optional **Most recent first** ordering and a **date window** for posts and videos, for daily monitoring.
- Removes the unrelated popular posts Facebook adds to thin searches, so a narrow keyword does not return filler.

### Who is it for?

- **Brand and social listening teams** that check daily what is being posted about a brand, product or campaign hashtag.
- **Agencies** that need a list of pages, creators and groups around a niche before outreach or influencer research.
- **Market researchers** comparing how competitors appear in Facebook search.
- **Lead generation teams** collecting business pages and places with websites for a keyword and city, for example `dentist chicago`.
- **Community managers** looking for groups where a topic is discussed.
- **Data teams** feeding Facebook search results into dashboards, spreadsheets or AI workflows on a schedule.

### Why use this Facebook search scraper?

- **Several result types in one run.** Pick any mix of pages, posts, videos, groups, people, places and events. You don't need a separate Actor per tab.
- **No login.** Nothing to set up, no account at risk of being restricted.
- **Engagement numbers on posts and videos.** Reactions, comments, shares and video views are included whenever Facebook shows them on the result card. Some video cards have no counts, and those fields are then `null`.
- **Exact dates.** Posts and most videos have an ISO timestamp, not just "3 days ago". Some native video cards have no date (`publishedAt` is `null`).
- **Relevant results only.** By default, posts and videos must mention every word of your keyword. Facebook's filler content is dropped and not charged.
- **Recency and date filters** built for repeat monitoring jobs. Dated posts and videos outside the window are dropped; native videos without a date are kept and have `publishedAt: null`.
- **Fast HTTP extraction.** No browser and low memory. Every result is charged before it is saved, and the run never saves more than **Max total results** or your maximum cost per run allows.

### What data can you extract from Facebook search?

| Field | Pages / places | People | Events | Posts | Videos | Groups |
| --- | :-: | :-: | :-: | :-: | :-: | :-: |
| `facebookId` | ✅ | ✅ | ✅ | ✅ post ID | ✅ video ID | ✅ group ID |
| `name` | ✅ | ✅ | ✅ | | | ✅ |
| `text` (snippet, post text, video title) | ✅ | | | ✅ | ✅ | |
| `url` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `authorName`, `authorId`, `authorUrl` | | | | ✅ | ✅ | |
| `groupId`, `groupName`, `groupUrl` | | | | ✅ when posted in a group | | ✅ |
| `publishedAt` / `publishedAtText` | | | | ✅ | most | |
| `reactionCount`, `commentCount`, `shareCount` | | | | ✅ when shown | ✅ when shown | |
| `viewCount`, `durationSeconds` | | | | some | ✅ | |
| `mediaType`, `imageUrl` | picture | picture | picture | ✅ | ✅ thumbnail | |
| `isVerified` | ✅ | ✅ | | | some | |
| `websiteUrl` | ✅ when shown | | | | | |
| `location` | | ✅ "Lives in …" | | | | |
| `matchingPostCount` | | | | | | ✅ |

Every row also has `query`, `resultType`, `rank`, `searchModule` and `scrapedAt`. Fields that do not apply to a result type are `null`.

### How much does it cost to scrape Facebook search results?

This Actor uses pay-per-event pricing. You pay a small fee when a run starts and then for each result saved to the dataset. Platform usage is included.

| Event | Price |
| --- | --- |
| Run started (once per run) | $0.002 |
| Search result, Free and Starter plans | $0.00313 |
| Search result, Scale plan | $0.002817 |
| Search result, Business plan and above | $0.002504 |

Examples at the Starter plan price:

- 1 keyword × 4 result types × 25 results = 100 results → about **$0.32**.
- 10 brand keywords monitored daily with 20 recent posts each = 200 results → about **$0.63 per day**.
- 1,000 results → about **$3.13**.

Apify's free plan includes $5 of monthly credit, enough for about 1,500 results. The $0.002 start fee is charged once for every run with valid input, even when Facebook returns nothing. Result fees are charged only for rows saved to the dataset, so rows dropped by the keyword filter, empty searches and failed requests have no result fee. Invalid input fails before any charge.

To cap the cost of a run, use **Max total results** or set a maximum cost per run in the run options. The Actor charges each result before saving it and stops cleanly when either limit is reached, so you never get more rows than you allowed and never get rows that were not charged. The status message then says how many results were delivered and why the run stopped.

### How to scrape Facebook search results

1. Open the Actor and enter one or more **Search keywords**, for example `nike`, `coffee shop chicago` or `#blackfriday`.
2. Choose the **Result types** you need. Pages, posts, videos and groups are selected by default.
3. Set **Max results per keyword and type**, for example 20.
4. Optional: turn on **Most recent first** and set a **date window** for posts and videos.
5. Click **Start** and wait for the run to finish. A few hundred results usually take a minute or two.
6. Download the results as JSON, CSV, Excel or XML, or open the **Posts and videos** and **Pages, groups, people, places and events** views.

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `searchQueries` | array of strings | required | Keywords, brand names, hashtags or phrases. Up to 100 per run. |
| `resultTypes` | array | `pages, posts, videos, groups` | Any of `pages`, `posts`, `videos`, `groups`, `people`, `places`, `events`. |
| `maxResultsPerType` | integer | 20 | Unique results per keyword and result type (1–500). |
| `maxItems` | integer | 1000 | Hard cap on results for the whole run, across all keywords and types, also when keywords run in parallel. |
| `sortPostsByRecent` | boolean | false | Newest posts and videos first. |
| `postsDateFrom` | date | – | Drop dated posts and videos before this day (`YYYY-MM-DD`, a real calendar date). Native videos without a date are kept. |
| `postsDateTo` | date | – | Drop dated posts and videos after this day. Native videos without a date are kept. |
| `requireKeywordMatch` | boolean | true | Keep posts, videos and groups only when every word of the keyword appears in the visible post text, video title, author name or group name. See [How keyword matching works](#how-keyword-matching-works). |
| `proxyConfiguration` | object | Apify datacenter proxy | Proxy for Facebook requests. The default works well. |

Example input for daily brand monitoring:

```json
{
    "searchQueries": ["nike air max", "#justdoit"],
    "resultTypes": ["posts", "videos", "groups"],
    "maxResultsPerType": 30,
    "sortPostsByRecent": true,
    "postsDateFrom": "2026-11-01"
}
```

### Output example

A page result:

```json
{
    "query": "nike",
    "rank": 10,
    "resultType": "pages",
    "facebookId": "100044519945902",
    "name": "Nike Football",
    "text": "Don't change your dream. Change the world. #justdoit",
    "url": "https://www.facebook.com/nikefootball",
    "isVerified": true,
    "websiteUrl": null,
    "searchModule": "ENTITY_PAGES",
    "scrapedAt": "2026-11-04T07:36:49.855Z"
}
```

A post result:

```json
{
    "query": "nike",
    "rank": 1,
    "resultType": "posts",
    "facebookId": "1058803598947682",
    "text": "They’re ready to put the world on notice. 🗣️ From basement parties in the Bronx to the biggest stage in Paris this summer, breaking is re…",
    "url": "https://www.facebook.com/nike/posts/pfbid07zAJEC1jCvirZK6m5Rm8bqoBeK1chFnJhDJohdB4fZDPiCFyZgpRHSbet8eo9QgMl",
    "authorName": "Nike",
    "authorId": "100044541544829",
    "authorUrl": "https://www.facebook.com/nike",
    "groupId": null,
    "publishedAt": "2024-07-16T21:10:15.000Z",
    "reactionCount": 2181,
    "commentCount": 221,
    "shareCount": 241,
    "mediaType": "photo",
    "imageUrl": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.30808-6/...",
    "searchModule": "TOP_PUBLIC_POSTS",
    "scrapedAt": "2026-11-04T07:36:53.257Z"
}
```

A video result:

```json
{
    "query": "nike",
    "rank": 1,
    "resultType": "videos",
    "facebookId": "1993703551290009",
    "text": "Nike Outlet clearance is GOOD right now. I stopped by my local Nike Factory Store and found some ser…",
    "url": "https://www.facebook.com/reel/1993703551290009/",
    "authorName": "Mama Deals",
    "authorUrl": "https://www.facebook.com/mamadeals1",
    "publishedAt": "2026-08-22T13:16:01.000Z",
    "reactionCount": 509,
    "commentCount": 14,
    "shareCount": 23,
    "viewCount": 31188,
    "durationSeconds": 26.8,
    "mediaType": "video",
    "searchModule": "VIDEOS_MBR_ENGAGEMENT"
}
```

A group result:

```json
{
    "query": "nike",
    "rank": 2,
    "resultType": "groups",
    "facebookId": "1151067687031994",
    "name": "Nike Sneaker Exchange – Buy, Sell, Trade & Talk",
    "url": "https://www.facebook.com/groups/1151067687031994/",
    "groupId": "1151067687031994",
    "matchingPostCount": 1,
    "searchModule": "POSTS_IN_GROUP",
    "scrapedAt": "2026-11-04T07:37:06.212Z"
}
```

The example rows are shortened; real rows contain every field listed above, with `null` where a value does not apply.

### How keyword matching works

With **Only results that mention the keyword** on (the default), each post, video and group row must match your keyword:

- The keyword is split into words at spaces and punctuation, so `coffee shop chicago` needs `coffee`, `shop` **and** `chicago`, and `#blackfriday` needs `blackfriday`.
- Matching ignores case and accents: `café` matches `Cafe`, and styled Unicode letters such as `𝐗` match `x`.
- Words of 3 or more characters match anywhere in the text, so `nike` also matches `#nikerunning`.
- Words of 1 or 2 characters, such as `x`, `ai` or `f1`, must appear as a whole word, so `x` does not match `next`.
- The words are checked in the post text, video title, author name and group name. Links are not checked.
- A keyword with no letters or digits at all (for example `!!!`) cannot be matched, and the run stops with a clear error before any charge. Turn the option off to search it anyway.

Pages, people, places and events are matched by Facebook itself on their names and are not filtered.

### Why a run stops and how to read the result

The run stops collecting a keyword and type for one of these reasons, and the final status message says how many results were delivered out of the number requested:

- **per-type limit reached:** **Max results per keyword and type** was filled.
- **Facebook had no more results:** Facebook's result list ended.
- **two pages in a row without a matching result:** Facebook kept returning only filler content, so the Actor stopped early.
- **page limit for this type reached:** the Actor read its page limit for that type (about one page of 10 cards per 8 requested results, up to 60 pages).
- **group scan limit reached:** see the group note below.
- **Max total results reached** or **maximum cost per run reached:** the whole run stopped; later keywords may not be searched.
- **keyword failed:** Facebook kept failing for that keyword after retries; the other keywords still run.

The full breakdown per keyword and type is saved as `RUN_SUMMARY` in the run's key-value store, with `delivered`, `requested`, `stopReason`, `failedKeywords` and one line per keyword and type.

### Tips and limits

- **Groups come from matching posts.** Facebook does not show its group search to logged-out visitors, so this is not Facebook's Groups tab. Groups are collected from the matching public posts that were shared in a group, during a bounded scan of post results. With only **Groups** selected, the scan covers about three times your per-type limit, at most 25 result pages per keyword. If you also select **Posts**, groups are collected throughout the longer post scan, which can run up to 60 pages per keyword at large per-type limits. Facebook shows a varying number of posts per page, so the number of posts scanned is approximate. The scan uses the same **Most recent first** and date settings as posts, so those settings change which groups you get. You often get fewer groups than the limit, and only groups with public posts. Use a specific topic keyword to find more.
- **Logged-out results.** Facebook shows logged-out visitors a smaller result set than a signed-in user sees, and its ranking differs. For a brand name, small look-alike pages can rank above the official page, so check `isVerified` and fetch a few more results than you need. Very deep searches stop when Facebook has no more results.
- **Date windows** are applied by Facebook at month level and then exactly by this Actor for every dated post and video. Native video cards that show no date cannot be placed in the window, so they are kept with `publishedAt: null`. Filter on `publishedAt` if you need dated rows only.
- **Keyword filter.** Turn off **Only results that mention the keyword** if you want everything Facebook returns for posts and videos, for example for misspellings or for posts that only show your brand in an image.
- **Image links expire.** Facebook image URLs are signed and stop working after some days. Download images soon if you need them.
- **Failures.** Each request is retried up to five times with a fresh anonymous session. If a keyword still fails, the run continues with the next keyword and reports the failed keyword in the log, the status message and the RUN_SUMMARY record. If charging or saving a result fails on the platform, the run fails with a message saying how many results were delivered, instead of saving uncharged rows.
- **Public data only.** Private profiles, private group posts and logged-in-only content are not returned.

### Integrations and workflows

- **Daily brand monitoring:** schedule the Actor with `sortPostsByRecent: true` and yesterday's date as `postsDateFrom`, then send new rows to Slack or email with an Apify integration or webhook.
- **Google Sheets dashboard:** connect the dataset to Google Sheets and chart reactions and comments per keyword over time.
- **Lead lists:** search `pages` and `places` for `<service> <city>` keywords and push the rows with a `websiteUrl` into your CRM through Make, Zapier or n8n.
- **Creator research:** search `videos` for a niche topic, sort by `viewCount`, then enrich the top creators with [Facebook Pages Scraper](https://apify.com/automation-lab/facebook-pages-scraper).
- **Group discovery:** collect `groups` for a topic, then read their posts with [Facebook Group Posts Scraper](https://apify.com/automation-lab/facebook-group-posts-scraper).
- **AI summaries:** feed post `text` and engagement fields into an LLM step to summarise what people say about a campaign.

### Use the Facebook Search Scraper with the Apify API

Run the Actor and get results with cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~facebook-multi-vertical-public-search-results/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["nike"],"resultTypes":["pages","posts","videos","groups"],"maxResultsPerType":10}'
```

JavaScript (Node.js) with the `apify-client` package:

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('automation-lab/facebook-multi-vertical-public-search-results').call({
    searchQueries: ['nike', 'adidas'],
    resultTypes: ['pages', 'posts', 'videos', 'groups'],
    maxResultsPerType: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((item) => item.resultType === 'posts'));
```

Python with the `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("automation-lab/facebook-multi-vertical-public-search-results").call(run_input={
    "searchQueries": ["nike"],
    "resultTypes": ["posts", "videos"],
    "sortPostsByRecent": True,
    "maxResultsPerType": 25,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["resultType"], item["url"], item.get("reactionCount"))
```

### Use with AI agents through MCP

You can use this Actor from Claude, Cursor and other MCP clients through the [Apify MCP server](https://mcp.apify.com).

Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/facebook-multi-vertical-public-search-results"
```

Claude Desktop, Cursor or VS Code (JSON configuration):

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com?tools=automation-lab/facebook-multi-vertical-public-search-results"
        }
    }
}
```

Selecting this Actor also adds the helper tools `get-actor-run`, `get-dataset-items`, `get-key-value-store-record` and `abort-actor-run`. A good agent workflow:

1. Start one run with `call-actor` and keep the returned run ID and dataset ID.
2. If the run is still running after the wait, check the same run with `get-actor-run` using short backoff (for example 2, 4, 8 seconds, up to 10) and a total deadline such as 120 seconds. Don't start a second run just to check progress.
3. If the run is still running at the deadline, stop polling and tell the user the run ID and that results are pending. Don't start another run; offer to check the same run later.
4. When it succeeds, read rows with `get-dataset-items` in pages using `offset` and `limit`: first `offset=0, limit=20`, then `offset=20`, `offset=40` and so on, asking only for the fields you need (`fields=resultType,url,text,reactionCount`).
5. Keep two budgets while reading: at most 100 rows, and a total size budget for the rows you put in the conversation, for example 50 KB of serialized UTF-8 JSON. Use a smaller budget if your host or client has a lower context or tool-response limit. If a single page is already larger than the remaining budget, lower `limit` (down to 1 row) or drop long fields such as `text`, and skip a row that alone exceeds the budget.
6. Stop when either budget is used up or a page returns fewer rows than `limit`. Tell the user how many rows you read, the `offset` to continue from, and that the full result set is in the run's dataset (dataset ID, or download it as JSON, CSV or Excel from the run in Apify Console). Report partial results honestly if the run failed or you stopped early.
7. To explain missing results, read the `RUN_SUMMARY` record with `get-key-value-store-record` from the run's default key-value store.

Example prompts:

- "Search Facebook for 'oat milk' posts from the last week, most recent first, and summarise the top complaints."
- "Find 20 Facebook pages and places for 'yoga studio austin' and list the ones with a website."
- "Which Facebook groups are discussing 'tesla cybertruck'? Give me names, URLs and how many matching posts each had."

### Is it legal to scrape Facebook search results?

This Actor collects only data that Facebook shows publicly to logged-out visitors. It does not log in, bypass privacy settings or access private groups or profiles. Web scraping of public data is generally lawful, but results can include personal data such as names of people who posted publicly. You are responsible for using the data lawfully, for example under GDPR or CCPA, and in line with Facebook's terms and your own purpose. Do not use the results for spam or harassment. If you're unsure, ask a lawyer. This Actor is not affiliated with or endorsed by Meta or Facebook.

When a run fails, the Actor sends sanitized diagnostic input, the error and the Actor, build and run IDs to our private GlitchTip error tracker so we can fix it. Secret fields and URL query strings are removed, and reports are kept for 30 days. The Actor does not use AI and does not send your input or results to an AI provider.

### FAQ

**Do I need a Facebook account or cookies?**
No. The Actor uses Facebook's public, logged-out search. You never provide credentials.

**Why did I get fewer results than I asked for?**
Facebook returns fewer results to logged-out visitors, narrow keywords have fewer matches, and the keyword filter removes unrelated filler posts. Groups usually return fewer rows because they come only from a bounded scan of matching public posts. The status message and the `RUN_SUMMARY` record give the exact stop reason for every keyword and type.

**Why are some posts old even with "Most recent first" off?**
By default Facebook ranks posts by relevance and popularity. Turn on **Most recent first** or set a date window for monitoring.

**A run failed or returned nothing. What should I do?**
Check the log. "Rate limit exceeded" messages are retried automatically with new sessions. If every keyword fails, keep the default Apify proxy, or try the `RESIDENTIAL` proxy group, and run again. Nonsense or very rare keywords can return zero results without an error.

**Can I search Facebook Marketplace or ads?**
No. Use [Facebook Marketplace Public Listings Scraper](https://apify.com/automation-lab/facebook-marketplace-public-listings-scraper) or [Facebook Ads Library Scraper](https://apify.com/automation-lab/facebook-ads-library).

**Is the data real-time?**
Each run reads Facebook search when it runs. Schedule it to keep data fresh.

### Related Facebook scrapers

- [Facebook Pages Scraper](https://apify.com/automation-lab/facebook-pages-scraper) – full details of pages you found in search.
- [Facebook Pages Posts Scraper](https://apify.com/automation-lab/facebook-pages-posts-scraper) – the latest posts of specific pages.
- [Facebook Group Posts Scraper](https://apify.com/automation-lab/facebook-group-posts-scraper) – posts from public groups.
- [Facebook People Search Scraper](https://apify.com/automation-lab/facebook-people-search-scraper) – deeper people directory search.
- [Facebook Public Video Search Results](https://apify.com/automation-lab/facebook-public-video-search-results) – video-only search.
- [Facebook URL to ID Resolver](https://apify.com/automation-lab/facebook-url-to-id-resolver) – convert Facebook URLs to numeric IDs.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/facebook-multi-vertical-public-search-results/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords, brand names, hashtags or phrases to search on Facebook. Each keyword is searched separately and every result keeps the keyword that found it.

## `resultTypes` (type: `array`):

Facebook search tabs to export. Groups are not Facebook's Groups tab: they are the public groups that matching posts were shared in, found in a bounded post scan. People, places and events are optional extra tabs.

## `maxResultsPerType` (type: `integer`):

Stop each result type for a keyword after this many unique results. Facebook may return fewer results for narrow keywords.

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

Stop the whole run after this many results across all keywords and types. It is a hard cap, also when keywords run in parallel. Use it, or a maximum cost per run, to cap the cost of a run.

## `sortPostsByRecent` (type: `boolean`):

Ask Facebook for the newest posts and videos first instead of its default ranking. Useful for daily brand monitoring. Pages, people, places and events are not affected.

## `postsDateFrom` (type: `string`):

Drop dated posts and videos published before this date (YYYY-MM-DD, a real calendar date). Native videos that show no date are kept with publishedAt empty. Also applies to the post scan that finds groups.

## `postsDateTo` (type: `string`):

Drop dated posts and videos published after this date (YYYY-MM-DD, a real calendar date). Native videos that show no date are kept with publishedAt empty.

## `requireKeywordMatch` (type: `boolean`):

Keep a post, video or group only when every word of the keyword appears in the visible post text, video title, author name or group name (case and accents ignored; links are not checked). Words of 1–2 characters such as x or f1 must appear as a whole word; longer words match anywhere. Facebook fills thin searches with unrelated popular posts; this removes them. A keyword with no letters or digits needs this turned off. Pages, people, places and events use Facebook's own name matching.

## `proxyConfiguration` (type: `object`):

Apify datacenter proxy works well for Facebook public search and is the default. Each failed request is retried with a fresh anonymous session.

## Actor input object example

```json
{
  "searchQueries": [
    "nike"
  ],
  "resultTypes": [
    "pages",
    "posts",
    "videos",
    "groups"
  ],
  "maxResultsPerType": 10,
  "maxItems": 20,
  "sortPostsByRecent": false,
  "requireKeywordMatch": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

All results across keywords and result types: names, text, URLs, authors, dates and engagement.

## `posts` (type: `string`):

Post and video rows with text, author, group, publish time, reactions, comments, shares, views and media.

## `entities` (type: `string`):

Page, group, people, place and event rows with names, URLs, snippets, websites, locations and verified badges.

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

Delivered versus requested results and the stop reason for every keyword and result type.

# 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 = {
    "searchQueries": [
        "nike"
    ],
    "resultTypes": [
        "pages",
        "posts",
        "videos",
        "groups"
    ],
    "maxResultsPerType": 10,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/facebook-multi-vertical-public-search-results").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 = {
    "searchQueries": ["nike"],
    "resultTypes": [
        "pages",
        "posts",
        "videos",
        "groups",
    ],
    "maxResultsPerType": 10,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/facebook-multi-vertical-public-search-results").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 '{
  "searchQueries": [
    "nike"
  ],
  "resultTypes": [
    "pages",
    "posts",
    "videos",
    "groups"
  ],
  "maxResultsPerType": 10,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call automation-lab/facebook-multi-vertical-public-search-results --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/facebook-multi-vertical-public-search-results"
        }
    }
}
```

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/uVtjt1zi4GKPplW1a/builds/LcXQo7vfzvKMQ4ZwW/openapi.json
