Find public Facebook posts by keyword, phrase or hashtag, then export their text, authors, publication dates, engagement and media.
This Facebook post search scraper returns Facebook’s search results, with date filters, recent-post selection and city or place-ID filtering. No Facebook account or cookies are required.
Who is it for? Brand researchers and campaign analysts can use it to monitor public brand mentions, review campaign discussions, discover posts about a topic, or build a repeatable research dataset. Search relevance can include the author and related context, so each row distinguishes literal text matches from author-name matches.
What you can export
- Original post IDs and Facebook permalinks.
- Post text, publication timestamps and public author details.
- Reaction totals and available reaction breakdowns, comment counts and share counts.
- Photo and video attachments, image URLs and available video URLs and durations.
- Public outbound links, source ranking and collection time.
Media-only posts can have no text. Missing counts stay null; a missing count is not represented as zero.
Quick start
Enter a query and a small result limit, then run the Actor:
{ "query": "coffee shop", "resultsCount": 20, "searchType": "top" }
After the run, open the dataset and export JSON, CSV or Excel. JSON preserves nested authors, reactions and attachments. CSV users can select the nested columns they need in Apify’s export settings.
The maximum is 200 unique posts per run. The Actor can return fewer when Facebook exhausts its available results. Public search is not an exhaustive archive of every matching post.
Example output
This shortened example shows fields from an observed public result:
{
"postId": "122328142718011695",
"publishedAt": "2026-08-24T18:50:56Z",
"postText": "Monday called… and said you need a Moody Cat pick-me-up. 🐱☕️💗",
"author": {
"id": "61550350854900",
"name": "Moody Cat Coffee Shop"
},
"reactionsCount": 53,
"commentsCount": 7,
"sharesCount": 5,
"searchQuery": "coffee shop"
}
Counts and availability can change after collection. The full dataset also includes the post permalink, timestamps, media, ranking and match evidence.
Input recipes
Recent hashtag posts
{ "query": "#coffee", "resultsCount": 20, "searchType": "latest" }
Posts within a date range
{ "query": "bronco", "resultsCount": 20, "startDate": "2025-01-01", "endDate": "2025-01-31" }
Posts associated with a city
{ "query": "coffee", "resultsCount": 10, "location": "London, United Kingdom" }
An exact Facebook place ID
{ "query": "coffee", "resultsCount": 10, "location": "106078429431815" }
Input settings
| Field | Meaning |
|---|---|
query |
Required keyword, phrase or hashtag, from 1 to 100 characters. |
resultsCount |
Maximum unique posts, from 1 to 200; default 20. |
searchType |
top uses native relevance. latest selects Facebook’s recent-post filter. |
startDate |
Optional inclusive publication date, YYYY-MM-DD. |
endDate |
Optional inclusive publication date, YYYY-MM-DD. |
location |
Qualified city name, region name or numeric Facebook place ID. |
maxRunSeconds |
Processing deadline, from 30 to 600 seconds; default 110. Set the platform timeout at least 15 seconds higher. |
proxyConfiguration |
Optional Apify Proxy settings. Direct access is the default. Proxy usage adds platform costs. |
Date limits apply to the returned post or share, rather than the date of an attached original. Invalid dates, reversed ranges and unsupported inputs fail before searching or charging.
Ranking and location matching
latest means Facebook’s recent-post selection. It does not promise strictly descending timestamps. You can sort collected rows by publishedAt, but that does not make a limited sample an exhaustive chronological feed.
Use a qualified location such as London, United Kingdom or Lisbon, Portugal. An ambiguous city name fails with an explanation; the Actor never quietly removes your location filter.
A region such as Alaska selects the first matching city supplied by Facebook. The resolved name and ID appear in searchLocation; use an exact place ID when that choice matters.
Location filtering follows Facebook’s association of a post with a place. It is not a verified author residence or a radius search.
Facebook post search API usage
Use the Apify API to run the Actor and retrieve its dataset. These examples require your Apify API token; they do not require a Facebook token.
Node.js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/facebook-post-search-scraper').call({
query: 'coffee shop', resultsCount: 20
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/facebook-post-search-scraper').call(
run_input={'query': 'coffee shop', 'resultsCount': 20}
)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
cURL
curl --fail --request POST \
"https://api.apify.com/v2/acts/fetch_cat~facebook-post-search-scraper/run-sync-get-dataset-items" \
--header "Authorization: Bearer $APIFY_TOKEN" \
--header "Content-Type: application/json" \
--data '{"query":"coffee shop","resultsCount":20}'
For larger requests, start an asynchronous run and wait for its terminal status before exporting the dataset.
Use with an AI assistant
Connect your client to the official Apify MCP server. For a supported client, the Apify CLI can install its configuration:
apify mcp install cursor --tools fetch_cat/facebook-post-search-scraper
A remote MCP configuration can use OAuth:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=fetch_cat/facebook-post-search-scraper"
}
}
}
Example prompt: “Find 20 public Facebook posts about coffee shops in London, United Kingdom. Export the authors, dates and engagement. Separate literal text matches from other search matches.”
Only accounts with access to this Actor can run it. A private Actor is not publicly discoverable in the Store.
Export Facebook post search data on a schedule
Save a tested input as an Apify task and attach a schedule in your account. Use date windows to control the collection period, then deduplicate successive exports by postId.
Search ranking and visibility can change between runs. A post newly returned by a search is not necessarily newly published; use publishedAt to distinguish those events.
Limits and failure behavior
The Actor collects public results available without a Facebook login. It does not collect private posts, private-group content, restricted comments or a complete author timeline.
Access restrictions, unavailable public results, malformed source responses and processing deadlines can stop a run. Previously saved rows remain in the dataset. RUN-SUMMARY reports the final status, saved count, pages, warnings and whether work remains.
An explicitly empty search can finish with zero rows. An access denial or missing search response fails instead of pretending that the query had no matches.
Search results are deduplicated within a run. Restarted execution reuses saved IDs and checkpoints. Separate scheduled runs are independent datasets.
Support
Include the run URL, non-sensitive input JSON, expected output, actual output and a reproducible public post URL when reporting a problem. Do not send passwords, cookies or browser session data.