Facebook Search Scraper: Keyword Posts, No Login avatar

Facebook Search Scraper: Keyword Posts, No Login

Pricing

from $1.90 / 1,000 posts

Go to Apify Store
Facebook Search Scraper: Keyword Posts, No Login

Facebook Search Scraper: Keyword Posts, No Login

Facebook search scraper for public posts by keyword, phrase or #hashtag, no login: top or most recent, date window, tagged place, post type and source filters, deep month by month search. Rows: text, author, reactions by type, comments, shares, video views and media. JSON, CSV, API; pay per post.

Pricing

from $1.90 / 1,000 posts

Rating

0.0

(0)

Developer

Automation Craft

Automation Craft

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

4 days ago

Last modified

Share

Facebook Search Scraper: Keyword Posts, No Login

Facebook search scraper for public posts, with no login, no cookies and no Facebook account: give keywords, phrases, #hashtags or a pasted Facebook post search link and get the posts Facebook's own search finds for each of them, in its Top order or most recent first, inside a date window and at a tagged place if you like. Every row carries the post's text, author, time, reactions by type, comment and share counts, video views, photos and videos with their files, link previews, shared posts, the query that found it, its rank, and whether the text really holds your words. Pay per post, from $1.90 per 1,000.

Built for social listening and brand mentions, news and topic research, campaign and hashtag tracking, lead finding, academic studies and AI data sets, and for scheduled runs in n8n, Make or Zapier. Rows carry what Facebook shows a visitor who is not logged in; use them under the rules that apply to you.

At a glance

  • Search by words: up to 100 queries a run (keywords, phrases, #hashtags, or facebook.com/search/posts/?q=... links, whose most recent, date and location filters are read too), each searched on its own and named on every row.
  • Facebook's two orders: Top posts (Facebook's relevance ranking) or Most recent first.
  • Date window and place: posts on or after and on or before a day (UTC, or "7 days", "2 months"), sent as Facebook's own filter and checked again on every post; posts tagged at a place, given by Facebook location id or by its full name ("New York, New York").
  • Deep search (on by default): when a query's results end before your post number, the search goes on month by month backwards, each month a search of its own, so you get more posts than the plain search gives.
  • Filters: post type (text, photo, album, video, reel, link, share, event, listing), who posted it (a page, a business page, a person, a group post), minimum reactions, comments or shares, only posts that contain the query, words to keep and words to leave out. Posts a filter leaves out are free.
  • Each post billed once per run, however many of your queries find it. Every search gets a free coverage row that says what was read and why it ended.
  • Personal data off by default: a person author's id, profile link and picture, the ids and links of tagged people and the phones and emails lists stay empty unless you turn them on. Names and texts are delivered as Facebook shows them, and each post's own link too, except a person's post link that holds the person's profile name or id.

Quick start

  1. Open the Actor and type your queries into Search queries, one per line (the form starts with climate change).
  2. Set Posts per query (the form starts at 10; 20 when the field is left out; up to 5,000) and pick an Order. Add a date window, a tagged location or filters if you like.
  3. Run, then download the rows from the Output tab (view Posts) as JSON, CSV or Excel, or read them through the API.
  4. For a daily feed of new mentions: set Order to Most recent first and Posted on or after to 1 day, and schedule the run with Apify's scheduler.

What you get

One post row per post (type: "post"). The fill rates count the 3,043 post rows (2,024 distinct posts, on 53 queries such as climate change, nike, pizza, coffee, yoga and tesla, in Top and Most recent order, with and without windows, places and filters) of the 58 runs of the platform test matrix of 2026-10-23 (two passes, build 0.1.1); 12 rows of the compact form and 20 rows with personal data on are included.

FieldWhat it holdsFilled
postId, url, createdAt, createdAtUnixThe post's id, its own link as Facebook serves it, and its creation time (UTC). With personal data off a person's post link is empty when it holds the person's profile name or id (facebook.com/<name>/posts/...); group, photo, video and reel links staypostId, createdAt 100%; url 100% of page posts (createdAtUnix 99.6%: not in compact rows)
query, searchRank, searchPage, sortByThe query that found the post, its place in Facebook's results (1 = first), the results page it came on, the order100% (searchPage, sortBy 99.6%)
searchWindow, searchLocationThe date window and the location id the search was sent withon every row of a search that sets them
matchesQuery, matchedWordsWhether the text (or shared text, link, listing or event title) holds every word of the query as a whole word, and which words it holds100%; true on 2,537 rows (83.4%), at least one word on 88.2%
textThe post's text in full, exactly as Facebook serves it99.3% (2,963 of 2,984 posts that are not shares)
titleThe post's header line when it has one ("X is at Y", "X is with Y")9.5%
postTypetext, photo, album, video, reel, link, share, event, listing or unavailable_attachment100%
authorName, authorTypeThe author's name and kind (page or person)100% (2,438 pages, 605 persons)
authorId, authorUrl, authorProfilePictureUrlThe author's id, link and picture: a page's always, a person's with personal data on2,433 of 2,433 page posts in full rows; empty for persons with personal data off
authorPageId, authorIsBusinessPageA page's classic page id (the one the Ad Library and the Graph API know) and whether its business page is active2,433 of 2,438 page posts (not in compact rows)
groupId, groupName, groupUrl, isGroupPostThe public group a post was made in537 group posts (17.6%), every one named
reactionCount, reactionsAll reactions, and each type (like, love, care, haha, wow, sad, angry)100%; the breakdown on 2,816 of 2,827 posts with a reaction, adding up to the total on all 2,816
commentCount, shareCount, engagementCountComments and shares as Facebook counts them, and the three counts added100% (engagementCount 99.6%)
videoViewCount, videoDurationSecondsOn videos and reels347 of 347 video and reel posts (duration on 346)
media, mediaCount, mediaListed, additionalMediaCount, albumCompletePhotos and videos: type, id, imageUrl, videoUrl (HD) and videoUrlSd, width, height, durationSeconds, altText (Facebook's own picture description), captionsUrl; how many items the post holds and how many the search lists2,740 of 2,740 photo, album, video and reel posts; imageUrl and size on 6,123 of 6,123 photos, altText on 6,100; videoUrl on 346 of 358 videos; 503 of 1,132 albums hold more items than the search lists (the Complete albums add-on reads the rest from the post's photo set page)
linkA link preview: url, title, description, domain, imageUrl149 of 149 link posts
sharedPostA share's original post: postId, postUrl, authorName, authorType, text, createdAt58 of 59 shares
listingA sale post's listing: listingId, title, priceText, price, currency, isSold, isOnMarketplace, locationText, marketplaceUrl7 of 7 listing posts
eventAn event post's event: name, when, place, url, canceledwhere present (none among the posts measured)
hashtags, mentions, taggedPlace, taggedProfilesHashtags in the text; pages and people the text links to; the place and the people or pages the header tags (a person's id and link with personal data on)hashtags 40.7%, mentions 3.7%, tagged place 5.7%, tagged profiles 2.7% (where the post has them)
audience, isAiLabelledThe audience Facebook shows ("Public"), and whether Facebook marks the post as made or edited with AI99.6%; AI label on 210 posts
phones, emailsPhone numbers and e-mail addresses written in the post, as lists (personal data on)empty with personal data off
storyId, feedbackId, attachmentKinds, subjectKey, searchKey, albumExpanded, scrapedAtFacebook's own story and feedback ids (a person author's story id with personal data on only), the attachment styles, the search the row belongs to as given and as one search (a place's name and id are one search), whether the Complete albums add-on read the post's photo set, the time of the runpage posts 100%

Compact rows (Row form set to Compact, for AI agents and sheets) carry one level only: type, postId, url, query, searchRank, matchesQuery, createdAt, text, postType, authorName, authorType, authorUrl, groupName, reactionCount, commentCount, shareCount, videoViewCount, imageUrl, videoUrl, linkUrl, sharedPostUrl, taggedPlace, searchLocationId, searchLocationInput, subjectKey, searchKey, scrapedAt.

Comment rows (add-on)

With Comments per post above 0, one comment row per comment of each delivered post (type: "comment", the Comment event), oldest first, up to 1,000 a post, replies too with Include replies: commentId, postId, postUrl, query, parentCommentId, threadCommentId, depth, text, language, createdAt, authorName, authorIsPostAuthor, authorBadges, reactionCount, reactions, replyCount, attachments, isEdited, mentions, commentUrl (a person commenter's authorId and authorUrl with personal data on).

Coverage, status and summary rows (free)

  • Coverage (type: "coverage"), one per search: query, sortBy, window, location, pagesRead, monthWindowsWalked, postsRead, postsDelivered, postsCharged, repeated, deliveredByAnotherSearch, beyondCap, filtered (by window, type, source, counts, query and keywords), reachedEndOfResults, newestPostAt, oldestPostAt, stopReason (max_posts_per_query, end_of_results, max_pages_per_query, max_posts, charge_limit, location_not_found and others), complete, and resumeEntry (this search's part of the run's resume token, below; resumed and deliveredInEarlierRun on a search resumed with a token).
  • Status (type: "status"): invalid (an input that cannot be used as given: nothing is fetched, only the start fee is charged), values_skipped (query values that cannot be used, beside usable ones), location_not_found (a place name that names no single place, with Facebook's suggestions; its searches are not run), lookup_failed, skipped (searches not started because the run stopped), place_changed (a place name of a resume token that now names another place: that search is not read), addon_unavailable, comments_incomplete.
  • Summary (type: "summary"), the last row: every counter, the requests made, the billing the platform confirmed, and resumeToken when a search stopped before Facebook's end.

Example post row

The first result of the prefill search (climate change, Top order) on 2026-10-23, a page's post; the two image links are shortened here:

{
"type": "post",
"postId": "1509521447706382",
"url": "https://www.facebook.com/NBCNews/posts/pfbid02Y3Cjk5s3LLiu8Q6LU4iJCbkP6aNf9VQAfWXZahSoyE5KwAczgjMqkg8Ac7KQmcXul",
"query": "climate change",
"sortBy": "top",
"searchLocation": null,
"searchRank": 1,
"searchPage": 1,
"searchWindow": null,
"matchesQuery": true,
"matchedWords": ["climate", "change"],
"createdAt": "2026-10-22T17:00:05.000Z",
"createdAtUnix": 1792688405,
"text": "Losing more ground in the fight against climate change, humanity is heading for a hotter world than experts projected last year, and the U.S. is a big reason for that, a new U.N. report says.",
"title": null,
"hashtags": [],
"mentions": [],
"postType": "link",
"authorName": "NBC News",
"authorId": "100059456233501",
"authorUrl": "https://www.facebook.com/NBCNews",
"authorType": "page",
"authorPageId": "155869377766434",
"authorIsBusinessPage": false,
"authorProfilePictureUrl": "https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-1/402884174_736334248358443_4969975308185333169_n.jpg?...",
"groupId": null,
"groupName": null,
"groupUrl": null,
"isGroupPost": false,
"taggedPlace": null,
"taggedProfiles": [],
"audience": "Public",
"isAiLabelled": false,
"reactionCount": 9100,
"reactions": { "haha": 6778, "sad": 1000, "like": 841, "angry": 410, "wow": 38, "care": 24, "love": 9 },
"commentCount": 3012,
"shareCount": 466,
"engagementCount": 12578,
"videoViewCount": null,
"videoDurationSeconds": null,
"media": [],
"mediaCount": 0,
"mediaListed": 0,
"additionalMediaCount": 0,
"albumComplete": true,
"albumExpanded": false,
"link": {
"url": "https://www.nbcnews.com/news/us-news/us-big-reason-world-losing-ground-fight-climate-change-un-report-says-rcna604944?cid=sm_npd_nn_fb_ma&utm_campaign=trueanthem&utm_medium=social&utm_source=facebook",
"title": "U.S. is a big reason the world is losing ground in the fight against climate change, U.N. report says",
"description": null,
"domain": "nbcnews.com",
"imageUrl": "https://external-lax3-2.xx.fbcdn.net/emg1/v/t13/11557256023761094427?..."
},
"event": null,
"sharedPost": null,
"listing": null,
"phones": null,
"emails": null,
"attachmentKinds": ["Share"],
"storyId": "UzpfSTEwMDA1OTQ1NjIzMzUwMToxNTA5NTIxNDQ3NzA2MzgyOjE1MDk1MjE0NDc3MDYzODI=",
"feedbackId": "ZmVlZGJhY2s6MTUwOTUyMTQ0NzcwNjM4Mg==",
"subjectKey": "s:cd2940051ce5db57",
"scrapedAt": "2026-10-23T08:39:10.171Z"
}

How fast and how deep

Measured on Apify runs of 2026-10-23 (256 MB, the Apify datacenter pool): the prefill (10 posts) in 7 seconds; 1,000 posts of one query (nike) in 475 and 530 seconds, each delivered once; 150 posts of pizza recipe, whose plain search ends at about 74, in 74 and 109 seconds with Deep search walking two months back; 3 queries of 10 posts each in 6 and 18 seconds with 3 searches at once; 50 queries of one post each in 146 and 175 seconds. Facebook answers about 5 posts a results page (4.7 to 5.5 on the final build's walks). Where a plain search ends depends on the query and on Facebook: climate change ended at 91 to 93 posts on four walks, nike at 184 to 320.

Pay per event: you pay for the posts delivered (and the add-ons you turn on), never for a repeat, a post a filter leaves out, a failed call, a place name that names no place or an input that cannot be used.

EventFreeBronzeSilverGold
Post (post), per 1,000 posts$2.66$2.43$2.20$1.90
Comment (comment), per 1,000 comments, add-on$0.27$0.24$0.22$0.19
Complete album (complete_album), per 1,000 albums, add-on$0.42$0.38$0.35$0.30
Actor start (apify-actor-start), once per run$0.0065$0.0065$0.0065$0.0065

Platinum and Diamond plans pay the Gold price. There is no discount on the Actor start event. The Store pricing card shows these same prices per 1,000 events: "$2.66 / 1,000" on the Post row means one post costs about a quarter of a cent on the Free plan ($0.00266), and "$1.90 / 1,000" means one post costs about a fifth of a cent on the Gold plan ($0.0019).

  • Post is charged once per post per run: a post that two of your queries find is delivered and charged once. Posts left out by the date window, the post type, the source, the minimum counts, the query match or your words are not charged and get no row.
  • Comment is charged per comment or reply row, only with Comments per post above 0.
  • Complete album is charged only with Complete albums on, and only when the post's photo set added photos or videos the search result did not list.

Worked examples, start fee included:

RunFreeBronzeSilverGold
The prefill: 10 posts of one query$0.0331$0.0308$0.0285$0.0255
1,000 posts$2.6665$2.4365$2.2065$1.9065
A daily scheduled run of 20 queries x 20 posts (400 posts a run)$1.0705 a day$0.9785 a day$0.8865 a day$0.7665 a day
The same daily run for 30 days$32.115$29.355$26.595$22.995
100 posts with 20 comments each (2,000 comment rows)$0.8125$0.7295$0.6665$0.5765

Every run reads its searches fresh: a post a scheduled run delivered yesterday is delivered and charged again today when the search finds it again. Narrow a daily run with Posted on or after (for example 1 day) and Most recent first to keep repeats down, and dedupe on postId in your own sheet or workflow.

The work allowance

Work that earns nothing (searches whose posts every filter leaves out, refused calls, long stretches of repeats) is bounded by an allowance in real cost that grows with every event the run bills. When it is spent the run stops: the search it was reading ends with work_allowance in its coverage row, the searches not started get one free skipped row, and every row already delivered is kept. The Complete albums add-on reads from a small allowance of its own, so album reads that fail never stop the search they serve; when that allowance has no room the add-on stops for the rest of the run with a free addon_unavailable row while the posts keep coming.

Input

FieldWhat it doesDefault
searchQueriesUp to 100 queries, one per line: a keyword or phrase, a #hashtag, or a Facebook post search link (facebook.com/search/posts/?q=coffee; its most recent, date and location filters are read too). A query in double quotes must stand as that exact phrase for the query match. A value written as a link that is not a Facebook post search link (another site, fb.watch/..., mailto:, tel:) is skipped free and named in a values_skipped row, never searched as words. Also read: query, queries, searchTerms.none (the form starts with climate change)
sortBytop (Facebook's relevance ranking) or recent (newest first). Also read: searchType (latest and newest read as recent).top, or the order a pasted link names
maxPostsPerQueryThe most posts delivered per query (and per location), 1 to 5,000. Also read: resultsCount, maxResults, resultsLimit.20 (the form starts at 10)
maxPostsA cap of post rows for the whole run, across queries. Also read: maxItems.no cap
startDate, endDateThe date window, UTC: YYYY-MM-DD, today, yesterday, or a time back such as 7 days, 3 weeks, 2 months, 1 year. Sent as Facebook's date filter and checked on every post. Also read: postedAfter, dateFrom, postedBefore, dateTo.no window (the end is today)
locationsUp to 20 places, one per line: a Facebook location id (108424279189115 is New York, New York) or a place's full name as Facebook writes it (London, United Kingdom). Each query is searched once per location, at most 300 searches a run. Also read: location, locationUid, locationId.none
deepSearchWhen a query's results end before its post number, go on month by month backwards (back to the start date, or 24 months), each month a new search; a deep walk ends after 3 months in a row that bring no new post.on
postTypesOnly these kinds: text, photo, album, video, reel, link, share, event, listing, unavailable_attachment.every kind
postSourcesOnly posts by page, business_page, person or group (a post made in a public group).every source
minReactions, minComments, minSharesOnly posts with at least this many.none
mustContainQueryKeep only posts whose text holds every word of the query as a whole word (case and accents aside).off
includeKeywords, excludeKeywordsUp to 50 words or phrases to keep (any of them) and to leave out (any of them), as whole words, case aside. Also read: keywordFilter.none
maxPagesPerQueryThe most result pages read per search (about 5 posts a page), 1 to 1,000.no page limit
maxCommentsPerPost, includeRepliesComments of each delivered post, oldest first, up to this many (0 to 1,000), each as its own row (Comment event); replies too.0 (off), off
includeAllPhotosThe photos and videos of a post that its search result does not list, read from the post's photo set page (Complete album event; albumComplete says whether every item was read). Needs full rows. Also read: scrapePhotos.off
outputFormatfull or compact (one level rows). Also read: compact (true or false).full
includePersonalDataThe personal data switch (below).off
maxConcurrencyHow many searches are read at the same time, 1 to 5, each on its own exit. Prices do not change.1
requestDelayMsThe pause between two calls of one search, 300 to 10,000 ms.400
maxRunSecondsStop starting new work after this many seconds (60 to 86,400) and end with the coverage rows and the summary.the run's own timeout
proxyConfigurationApify Proxy: the datacenter pool (default), the RESIDENTIAL group with a two letter country, your own proxies (http(s)://user:password@host:port links, each new exit takes the next one; never shown in logs or rows), or no proxy (the run's own address).Apify datacenter pool
resumeTokenThe resumeToken of an earlier run's summary row, to go on with its searches where they stopped (below).none

Resume tokens

When a search of a run stops before Facebook's end (its post number, its page limit, the charge limit, the run deadline, a refusal), the run's summary row carries a resumeToken. Run the same searches again, given the same way (the same words, order, date window, and the same place ids or place names), with that token in resumeToken: each search starts where it stopped, a search that run read to its end is not read again, and each search skips, free, the posts IT delivered in that run. Posts it read but did not deliver (past its post number or the charge limit) are delivered now. A post another search of the earlier run delivered can come again, as in any two separate runs, and a search the input adds beside the token starts fresh. The token is yours to keep: nothing is stored on Apify between runs, and the token of the resumed run carries the posts of both runs, search by search. A token with a search that is not in the input refuses the run with one free row; a relative window (7 days) names other dates on another day, so resume with the dates of the first run. With personal data off, a token holds no person's id.

{ "searchQueries": ["climate change"], "maxPostsPerQuery": 100, "resumeToken": "fbr1.eyJ2..." }

A value sent as null or "" counts as left out. Two keys of one meaning sent together, a setting name the Actor does not know, or a value it cannot use as given refuse the input with one free invalid row (only the start fee is charged).

Examples:

{ "searchQueries": ["climate change", "#climateaction"], "maxPostsPerQuery": 50 }
{
"searchQueries": ["electric scooter"],
"sortBy": "recent",
"startDate": "7 days",
"postSources": ["page", "group"],
"minReactions": 10,
"mustContainQuery": true
}
{
"searchQueries": ["pizza"],
"locations": ["New York, New York", "106078429431815"],
"maxPostsPerQuery": 100,
"excludeKeywords": ["delivery"],
"maxCommentsPerPost": 20
}

Personal data

Off by default. Rows then carry the names of post authors and commenters as Facebook shows them (they are part of the content) and each post's and comment's own link, and leave empty the fields that name or reach a private person: a person author's id, profile link and picture (authorId, authorUrl, authorProfilePictureUrl), a person author's storyId, a person's post link (and its photo, video and comment links, and a shared person's post link) when it holds the person's profile name or id, the ids and links of people tagged or mentioned and of commenters, a listing's seller, the phones and emails lists, and a link field that points to a person's profile or is a contact link. A person in Facebook's professional mode is a person here (only an author Facebook flags as a Page is a page), and a post whose author Facebook does not name has its links judged as a person's. Texts are never masked: what someone wrote in a post or comment is delivered exactly as Facebook serves it. A page's id and link are not personal data and are always delivered. With Include personal data (includePersonalData: true) those fields are filled; you are responsible for a lawful use of personal data (GDPR included).

What this Actor does NOT do

  • No login, no cookies and no Facebook account: it reads what Facebook's search shows a visitor who is not logged in.
  • No private or friends only posts, and no posts of private groups: only public posts are reachable logged out.
  • No other search tabs: people, pages, groups, videos, places and Marketplace results are not read, only the posts tab. Video search is a separate listing (Facebook Video Search Scraper), and hashtag feeds a separate listing we plan.
  • Facebook decides the ranking and how many posts a query has: results end where Facebook's search ends (Deep search goes past that end with month windows, and still ends where those months end).
  • No monitor or "new posts only" mode across runs (owner decision); every run reads its searches fresh; schedule runs with Apify's scheduler and dedupe on postId in your own sheet or workflow. Inside one run each post is delivered once. An input with memoryName, monitorStoreName, resetMemory or onlyNewPosts is refused with a free row that says so.
  • No Google results mode: the Actor reads Facebook's own search, never a search engine's results.
  • Facebook's search is fuzzy: it also answers posts that do not hold every word of your query. Each row says whether it does (matchesQuery), and Only posts that contain the query keeps only those.
  • A date window is sent as Facebook's filter, which is soft: posts outside the window that Facebook still answers are left out in code and not charged, so a narrow window can end with fewer posts than asked for.
  • An album lists the items the search result shows; mediaCount says how many it holds, and Complete albums reads the rest from the post's photo set page (one page of the set; albumComplete says whether every item was read).
  • No speech is turned into text and no text is read from images (Facebook's own alt text and caption links are delivered).
  • Counts (reactions, comments, shares, views) are the ones Facebook shows at the moment of the run.
  • No language model filter: the Actor makes no call to an outside model; filter by your own words.

API examples

Run and get the rows (replace <APIFY_TOKEN>):

curl -X POST "https://api.apify.com/v2/acts/automation_craft~facebook-search-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"searchQueries":["climate change"],"maxPostsPerQuery":20}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('automation_craft/facebook-search-scraper').call({ searchQueries: ['#climateaction'], sortBy: 'recent', startDate: '7 days', maxPostsPerQuery: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((r) => r.type === 'post'));
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("automation_craft/facebook-search-scraper").call(run_input={"searchQueries": ["pizza"], "locations": ["New York, New York"], "maxPostsPerQuery": 30})
posts = [r for r in client.dataset(run["defaultDatasetId"]).iterate_items() if r["type"] == "post"]

FAQ

Can I search Facebook posts by keyword without logging in?

Yes. This Actor runs Facebook's own post search as a visitor who is not logged in: no account, no cookies and no login. It returns the public posts Facebook's search shows for your words; posts shared only with friends or a group's members are not reachable this way.

Can I search Facebook for a hashtag?

Yes. Put the hashtag with its # in Search queries (for example #climateaction), one query per line. Each row lists the hashtags in its text (hashtags), and Only posts that contain the query keeps only the posts whose text holds it as a whole word.

How do I get Facebook posts from a date range, or only the most recent ones?

Set Posted on or after and Posted on or before (YYYY-MM-DD, or a time back such as 7 days); the window is sent as Facebook's own date filter and checked again on every post, so posts outside it are left out and not charged. For the newest posts first, set Order to Most recent first.

Why does a Facebook search stop after a few hundred posts?

Facebook ends each search where its own results end, and it decides the ranking: in our tests climate change ended at 91 to 93 posts and pizza recipe at 74. With Deep search on (the default) the Actor then searches month by month backwards with Facebook's date filter, which reaches posts the plain search did not show; pizza recipe gave 150 posts that way.

How do I export Facebook search results to CSV or Excel?

Run the Actor, open the Output tab and download the Posts view as CSV or Excel: one row per post with the query, rank, time, author, text and counts as columns. The same rows are available as JSON through the API, and Row form set to Compact gives one level rows for sheets.

Why does this Actor run with limited permissions?

It runs with the least privilege Apify offers: it reads and writes only its own run's dataset and key-value store. It cannot see your other Actors, datasets or account data.

More data tools by Automation Craft

Changelog

  • 0.1 (2026-10-24): a search that reached Facebook's end with a post passed over in a race between two searches is no longer marked complete (a restarted run or a resume token reads it again); mentions and tags after an emoji keep their whole name; hashtags and the query match keep whole words in scripts with vowel signs (Hindi, Bengali, Thai, Tamil); a post stored twice by a retry counts once toward its search's number after a restart; inputs written with query, queries or searchTerms are no longer refused by the form; photo set pages whose parts arrive out of order keep each item's picture, and the Complete albums texts say the add-on reads the post's photo set page; the resume token and personal data field texts say exactly what is skipped and what is emptied; a resume token keeps the dates and months of the run that wrote it when it is used on a later day.
  • 0.1 (2026-10-23): first build: public Facebook posts by keyword, phrase, #hashtag or pasted post search link, logged out; Top or Most recent order, a date window, tagged locations by id or name, post type, source, count and word filters, deep search by month windows, comments and complete albums as add-ons, personal data off by default.