Facebook Business Page Recommendation & Review Scraper
Get Facebook business page reviews by direct URL, business name search, or Page ID, with Recommended/Not Recommended status, owner replies, and filters for date, keyword, and recommendation status.
Input schema
Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.
| Field | Type | Required | Description |
|---|---|---|---|
startUrls | array | optional | Facebook business page URLs or /reviews URLs (e.g. https://www.facebook.com/mcdonalds/reviews). /reviews is added automatically when missing. Invalid or dead page URLs fail fast instead of being guessed. |
pageIds | array | optional | Numeric Facebook Page IDs (e.g. 100064458773195) or page usernames (e.g. mcdonalds). Use this when you do not have a full URL. |
maxItems | integer | optional | Maximum number of review rows to return across all pages (1-2000). Facebook returns roughly 2-3 reviews per request (about 2.7 on average) even when a larger count is requested, so 100 reviews needs about 35-40 requests. |
Show all input fields
| Field | Type | Required | Description |
|---|---|---|---|
startUrls | array | optional | Facebook business page URLs or /reviews URLs (e.g. https://www.facebook.com/mcdonalds/reviews). /reviews is added automatically when missing. Invalid or dead page URLs fail fast instead of being guessed. |
pageIds | array | optional | Numeric Facebook Page IDs (e.g. 100064458773195) or page usernames (e.g. mcdonalds). Use this when you do not have a full URL. |
maxItems | integer | optional | Maximum number of review rows to return across all pages (1-2000). Facebook returns roughly 2-3 reviews per request (about 2.7 on average) even when a larger count is requested, so 100 reviews needs about 35-40 requests. |
maxPerPage | integer | optional | Optional cap per Facebook page for multi-page runs. Leave empty to share the global Max Reviews cap across pages. |
includeReplies | boolean | optional | Include the visible top comments and business owner replies inside each review row. When disabled, commentCount is still returned. |
includePageSummary | boolean | optional | Emit one recordType=page row per page with the recommendation percentage, total review count, followers, and talking-about count. This adds no extra requests. |
onlyNew | boolean | optional | Return only reviews not seen in the saved state for this page. The state is stored in a named key-value store that persists across runs, so scheduled runs can monitor for new reviews. |
stateKey | string | optional | Optional prefix for the key-value store key used by monitor mode. Each page's state is stored separately. Leave empty to use the page ID. |
recommendation | string | optional | Only return reviews with the selected recommendation status. Facebook uses binary Recommended / Not Recommended, not star ratings. |
dateFrom | string | optional | Only return reviews posted on or after this date. Reviews are newest-first, so collection stops when it passes this date. |
dateTo | string | optional | Only return reviews posted on or before this date. |
keyword | string | optional | Only return reviews whose text contains this word or phrase (case-insensitive). |
requestDelayMs | integer | optional | Pause between review requests. 500-800 ms is a polite pace and keeps long runs stable. |
maxRuntimeSecs | integer | optional | Stop collecting after this many seconds and return what has been collected so far. |
failOnEmpty | boolean | optional | Mark the run as failed when no review rows are returned. Monitor-mode runs that legitimately have no new reviews never fail. |
proxyConfiguration | object | optional | Optional. Leave empty to let the actor choose automatically: it tries a direct connection first and only escalates through Apify Proxy if Facebook blocks the request. Change this only if you need a specific proxy setup. |
cookies | array | optional | Optional Facebook cookies exported from a logged-in browser. They are not required and do not increase how many reviews Facebook serves per request; the actor returns real reviews without them. |
Download the published input schema
View complete JSON
{
"description": "Scrape public Facebook business page recommendations and reviews by page URL, numeric Page ID, or username. Returns review rows plus one page-summary row per page.",
"properties": {
"cookies": {
"default": [],
"description": "Optional Facebook cookies exported from a logged-in browser. They are not required and do not increase how many reviews Facebook serves per request; the actor returns real reviews without them.",
"editor": "json",
"title": "Optional Facebook Cookies",
"type": "array"
},
"dateFrom": {
"description": "Only return reviews posted on or after this date. Reviews are newest-first, so collection stops when it passes this date.",
"editor": "textfield",
"title": "Date From (YYYY-MM-DD)",
"type": "string"
},
"dateTo": {
"description": "Only return reviews posted on or before this date.",
"editor": "textfield",
"title": "Date To (YYYY-MM-DD)",
"type": "string"
},
"failOnEmpty": {
"default": false,
"description": "Mark the run as failed when no review rows are returned. Monitor-mode runs that legitimately have no new reviews never fail.",
"prefill": false,
"title": "Fail When Nothing Is Found",
"type": "boolean"
},
"includePageSummary": {
"default": true,
"description": "Emit one recordType=page row per page with the recommendation percentage, total review count, followers, and talking-about count. This adds no extra requests.",
"prefill": true,
"title": "Include Page Summary Row",
"type": "boolean"
},
"includeReplies": {
"default": true,
"description": "Include the visible top comments and business owner replies inside each review row. When disabled, commentCount is still returned.",
"prefill": false,
"title": "Include Comments and Owner Replies",
"type": "boolean"
},
"keyword": {
"description": "Only return reviews whose text contains this word or phrase (case-insensitive).",
"editor": "textfield",
"title": "Keyword Filter",
"type": "string"
},
"maxItems": {
"default": 100,
"description": "Maximum number of review rows to return across all pages (1-2000). Facebook returns roughly 2-3 reviews per request (about 2.7 on average) even when a larger count is requested, so 100 reviews needs about 35-40 requests.",
"editor": "number",
"maximum": 2000,
"minimum": 1,
"prefill": 5,
"title": "Max Reviews",
"type": "integer"
},
"maxPerPage": {
"description": "Optional cap per Facebook page for multi-page runs. Leave empty to share the global Max Reviews cap across pages.",
"editor": "number",
"maximum": 2000,
"minimum": 1,
"title": "Max Reviews Per Page",
"type": "integer"
},
"maxRuntimeSecs": {
"default": 1800,
"description": "Stop collecting after this many seconds and return what has been collected so far.",
"editor": "number",
"maximum": 7200,
"minimum": 30,
"prefill": 1800,
"title": "Run Time Budget (seconds)",
"type": "integer"
},
"onlyNew": {
"default": false,
"description": "Return only reviews not seen in the saved state for this page. The state is stored in a named key-value store that persists across runs, so scheduled runs can monitor for new reviews.",
"prefill": false,
"title": "Only New Reviews (Monitor Mode)",
"type": "boolean"
},
"pageIds": {
"default": [],
"description": "Numeric Facebook Page IDs (e.g. 100064458773195) or page usernames (e.g. mcdonalds). Use this when you do not have a full URL.",
"editor": "stringList",
"prefill": [],
"title": "Facebook Page IDs or Usernames",
"type": "array"
},
"proxyConfiguration": {
"description": "Optional. Leave empty to let the actor choose automatically: it tries a direct connection first and only escalates through Apify Proxy if Facebook blocks the request. Change this only if you need a specific proxy setup.",
"editor": "proxy",
"title": "Proxy Configuration",
"type": "object"
},
"recommendation": {
"default": "all",
"description": "Only return reviews with the selected recommendation status. Facebook uses binary Recommended / Not Recommended, not star ratings.",
"editor": "select",
"enum": [
"all",
"recommended",
"not"
],
"enumTitles": [
"All Reviews",
"Recommended Only",
"Not Recommended Only"
],
"prefill": "all",
"title": "Recommendation Filter",
"type": "string"
},
"requestDelayMs": {
"default": 600,
"description": "Pause between review requests. 500-800 ms is a polite pace and keeps long runs stable.",
"editor": "number",
"maximum": 5000,
"minimum": 0,
"prefill": 600,
"title": "Delay Between Requests (ms)",
"type": "integer"
},
"startUrls": {
"default": [],
"description": "Facebook business page URLs or /reviews URLs (e.g. https://www.facebook.com/mcdonalds/reviews). /reviews is added automatically when missing. Invalid or dead page URLs fail fast instead of being guessed.",
"editor": "requestListSources",
"items": {
"properties": {
"url": {
"description": "Facebook business Page URL or /reviews URL.",
"title": "Page URL",
"type": "string"
}
},
"required": [
"url"
],
"type": "object"
},
"prefill": [
{
"url": "https://www.facebook.com/mcdonalds/reviews"
}
],
"title": "Facebook Page URLs",
"type": "array"
},
"stateKey": {
"description": "Optional prefix for the key-value store key used by monitor mode. Each page's state is stored separately. Leave empty to use the page ID.",
"editor": "textfield",
"title": "Monitor State Key",
"type": "string"
}
},
"schemaVersion": 1,
"title": "Facebook Business Page Review Scraper Input",
"type": "object"
}
Output schema
Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.
| Field | Type | Required | Description |
|---|---|---|---|
reviews | string | optional | Dataset containing review rows, page-summary rows (recordType=page), and error rows (recordType=error). |
Download the published output schema
View complete JSON
{
"actorOutputSchemaVersion": 1,
"description": "Review rows with recommendation status, author details, reactions, tags, comments and owner replies, plus one page-summary row per page and error rows.",
"properties": {
"reviews": {
"description": "Dataset containing review rows, page-summary rows (recordType=page), and error rows (recordType=error).",
"template": "{{links.apiDefaultDatasetUrl}}/items",
"title": "Facebook Reviews Dataset",
"type": "string"
}
},
"title": "Facebook Business Page Recommendation & Review Scraper Output"
}
Dataset schema
Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.
Download the published dataset schema
View complete JSON
{
"actorSpecification": 1,
"title": "Facebook Reviews Data",
"views": {
"detailed": {
"display": {
"component": "table",
"properties": {
"authorName": {
"format": "text",
"label": "Author"
},
"authorProfileUrl": {
"format": "link",
"label": "Profile URL"
},
"commentCount": {
"format": "number",
"label": "Comments"
},
"createdAt": {
"format": "text",
"label": "Date"
},
"errorType": {
"format": "text",
"label": "Error Type"
},
"followerCount": {
"format": "number",
"label": "Followers"
},
"isRecommended": {
"format": "boolean",
"label": "Recommended"
},
"ownerReplies": {
"format": "array",
"label": "Owner Replies"
},
"pageId": {
"format": "text",
"label": "Page ID"
},
"pageName": {
"format": "text",
"label": "Page"
},
"reactionBreakdown": {
"format": "array",
"label": "Reaction Breakdown"
},
"reactionCount": {
"format": "number",
"label": "Reactions"
},
"recommendPercent": {
"format": "number",
"label": "Recommend %"
},
"recordType": {
"format": "text",
"label": "Record Type"
},
"reviewCount": {
"format": "number",
"label": "Page Review Count"
},
"reviewId": {
"format": "text",
"label": "Review ID"
},
"reviewTags": {
"format": "array",
"label": "Recommendation Tags"
},
"reviewUrl": {
"format": "link",
"label": "Review URL"
},
"scrapedAt": {
"format": "text",
"label": "Scraped At"
},
"talkingAboutCount": {
"format": "number",
"label": "Talking About"
},
"text": {
"format": "text",
"label": "Review Text"
},
"timestamp": {
"format": "number",
"label": "Timestamp (Unix)"
},
"topComments": {
"format": "array",
"label": "Top Comments"
}
}
},
"title": "Full Record Details",
"transformation": {
"fields": [
"recordType",
"reviewId",
"pageId",
"pageName",
"pageUrl",
"authorName",
"authorProfileUrl",
"authorProfileImageUrl",
"authorIdType",
"isRecommended",
"text",
"reviewTags",
"createdAt",
"timestamp",
"reactionCount",
"reactionBreakdown",
"shareCount",
"commentCount",
"topComments",
"ownerReplies",
"reviewPhotos",
"reviewUrl",
"recommendPercent",
"reviewCount",
"followerCount",
"talkingAboutCount",
"page",
"errorType",
"error",
"scrapedAt"
]
}
},
"overview": {
"display": {
"component": "table",
"properties": {
"authorName": {
"format": "text",
"label": "Author"
},
"commentCount": {
"format": "number",
"label": "Comments"
},
"createdAt": {
"format": "text",
"label": "Date"
},
"isRecommended": {
"format": "boolean",
"label": "Recommended"
},
"pageName": {
"format": "text",
"label": "Page"
},
"reactionCount": {
"format": "number",
"label": "Reactions"
},
"recordType": {
"format": "text",
"label": "Record Type"
},
"reviewUrl": {
"format": "link",
"label": "URL"
},
"text": {
"format": "text",
"label": "Review Text"
}
}
},
"title": "Reviews Overview",
"transformation": {
"fields": [
"recordType",
"pageName",
"authorName",
"isRecommended",
"text",
"createdAt",
"reactionCount",
"commentCount",
"reviewUrl"
]
}
}
}
}
Key-value schema
Published key-value store definitions, when provided by this build.
This definition is not present in the default published build. See the published README for available documentation.
Published README
Read the full published documentation
Facebook Business Page Recommendation & Review Scraper
Extract Facebook business page recommendations and reviews from public pages without logging in. Paste a page URL, a numeric Page ID, or a username, and get review text, Recommended / Not Recommended status, author details, reactions, recommendation tags, comments and owner replies — plus a page-summary row with the recommendation percentage, review count, follower count and talking-about count. Reviews are collected newest-first, deduplicated by review ID, and can be filtered by date, keyword, or recommendation status.
What this actor does
- Two input styles: full Facebook page or
/reviewsURLs, and numeric Page IDs or page usernames - Deep review history: returns up to 2,000 reviews per run; Facebook serves roughly 2–3 reviews per request, so depth comes from pagination rather than a login session
- Rich review fields: recommendation status, full text, author name/profile/photo, reaction counts and breakdowns, recommendation tags, share and comment counts, top comments, and business owner replies
- Page-summary row: one
recordType: pagerecord per page with recommend %, total review count, followers, and talking-about count - Filters and monitor mode: date range, keyword, Recommended / Not Recommended, and an incremental mode that returns only reviews newer than the saved state
- Empty fields are omitted: missing values are left out instead of being returned as
null
Output per review
reviewId— stable Facebook review IDpageId,pageName,pageUrl— the page the review belongs totext— full review textisRecommended—truefor Recommended,falsefor Not RecommendedcreatedAt— ISO-8601 UTC timestamptimestamp— Unix timestamp in secondsauthorName,authorProfileUrl,authorProfileImageUrl,authorIdType— author identity;authorIdTypeispfbidornumericreactionCount,reactionBreakdown— total reactions and per-type counts (Like, Love, Wow, Haha, Sad, Angry, Care)shareCount,commentCountreviewTags— structured tags such asDisappointing foodorFast deliverytopComments— visible comments (with attachedphotoswhen present), includingisOwnerReplyon business repliesownerReplies— the subset of comments written by the business itselfreviewUrl— permalink to the review postreviewPhotos— present only when Facebook exposes review media (currently rare on this surface)page— page metadata object retained for compatibilityrecordType: "review",scrapedAt
Output per page
One row per page with recordType: "page":
pageId,pageName,pageUrlrecommendPercent— Facebook's own recommendation percentage (not recalculated from returned reviews)reviewCount— total reviews shown by Facebook for the pagefollowerCounttalkingAboutCountscrapedAt
Error rows
Unavailable pages produce a row with recordType: "error", an errorType, a readable error, the page identity when known, and scrapedAt. Error types include INVALID_INPUT, PAGE_UNAVAILABLE, PAGE_NOT_FOUND, BLOCKED, DOC_ID_UNAVAILABLE, REQUEST_FAILED, NO_REVIEWS, TIME_BUDGET_EXCEEDED, and SCRAPE_ERROR.
Input
| Field | Type | Default | Description |
|---|---|---|---|
startUrls |
array | [] |
Facebook page URLs or /reviews URLs. /reviews is added automatically when missing |
pageIds |
array | [] |
Numeric Page IDs or page usernames |
maxItems |
integer | 100 |
Maximum review rows across all pages (1–2000) |
maxPerPage |
integer | – | Optional per-page cap for multi-page runs (1–2000) |
includeReplies |
boolean | true |
Include top comments and owner replies |
includePageSummary |
boolean | true |
Emit one page-summary row per page |
onlyNew |
boolean | false |
Monitor mode: return only reviews not in the saved state |
stateKey |
string | – | Optional prefix for the monitor state key |
recommendation |
string | all |
all / recommended / not |
dateFrom |
string | – | Only reviews on or after this date (YYYY-MM-DD) |
dateTo |
string | – | Only reviews on or before this date (YYYY-MM-DD) |
keyword |
string | – | Only reviews containing this word or phrase (case-insensitive) |
requestDelayMs |
integer | 600 |
Pause between requests in milliseconds (0–5000) |
maxRuntimeSecs |
integer | 1800 |
Stop collecting after this many seconds |
failOnEmpty |
boolean | false |
Fail the run when no review rows are returned |
proxyConfiguration |
object | automatic | Optional connection override; leave empty and the actor picks a working connection, escalating only when Facebook blocks a request |
cookies |
array | [] |
Optional Facebook cookies; not required and not needed for depth |
Legacy keys from earlier versions (maxReviews, maxReviewsPerPage, filterByRecommendation, filterByDateFrom, filterByDateTo, filterByKeyword) are still accepted and mapped internally. Business-name-plus-city search has been removed because it resolved to guessed, often dead page URLs.
Example: scrape one page
{
"startUrls": [{ "url": "https://www.facebook.com/mcdonalds/reviews" }],
"maxItems": 200
}
Example: multiple pages by Page ID or username
{
"pageIds": ["100064458773195", "portosbakery"],
"maxItems": 500,
"maxPerPage": 50,
"includeReplies": true
}
Example: only negative reviews from a date range
{
"startUrls": [{ "url": "https://www.facebook.com/IHOP/reviews" }],
"recommendation": "not",
"dateFrom": "2026-06-01",
"maxItems": 100
}
Example: daily monitor for new reviews
{
"pageIds": ["100064458773195"],
"onlyNew": true,
"stateKey": "mcdonalds-monitor",
"maxItems": 200
}
Use cases
- Reputation monitoring — track new Recommended / Not Recommended reviews and owner replies for a brand or franchise location
- Competitor analysis — compare recommendation percentages, review volume, and recurring complaint keywords across competing businesses
- Local business research — pull reviews for restaurants, hotels, or service providers before choosing where to eat, stay, or book
- Customer feedback analysis — export review text and recommendation tags for sentiment or NLP pipelines
- Franchise tracking — scrape many location-specific Page IDs in one run and compare performance
- Market research — measure follower and talking-about counts alongside review trends
FAQ
Does this require a Facebook account or cookies? No. The actor reads publicly visible reviews from public business pages without logging in. Cookies are optional. They do not increase review depth: Facebook serves the same 2–3 reviews per request either way.
How many reviews can I get? Up to 2,000 per run. Facebook returns about 2–3 reviews per request even when asked for more, so 100 reviews typically needs around 35–40 requests. Earlier versions of this actor described a 10–15-review limit; that was a browser-UI ceiling, not a server-side cap, and no longer applies to this collection path.
Why is there no star rating?
Facebook business pages use binary Recommended / Not Recommended, so there is no per-review star rating. isRecommended tells you which one the reviewer chose.
Does recommendPercent match the reviews I received?
No. It is Facebook's own page-level figure and is not recalculated from the returned sample, which may be a small slice of the page's full review history.
Can I get the business's replies?
Yes. Visible comments appear in topComments, and ownerReplies contains only the comments written by the page itself. Both are omitted when includeReplies is off, while commentCount remains.
Can I get review photos, a language filter, or a rating distribution? Not from this surface today. Review photos are effectively absent on current Facebook review pages, review text has no language metadata, and no rating distribution is exposed — only the recommendation percentage and total review count. The actor does not fabricate those fields.
Do I need to configure a proxy?
No. The actor works without a proxy and selects a working connection automatically. The proxyConfiguration field is only for users who need a specific setup.
How does monitor mode know what is new?
It stores the review IDs it has seen in a named key-value store that persists across runs, one key per page. Scheduled runs with onlyNew return only reviews that were not in that saved set. Use stateKey if you want separate monitor streams for the same page.
What happens for a dead or private page?
The actor validates the page before collecting and writes a single recordType: "error" row. It does not guess a page URL from a business name, and it does not retry a dead page repeatedly.
Limitations
- 2,000-review cap per run — a deliberate ceiling that keeps one run bounded
- Public business pages only — private pages, personal profiles, groups, and Marketplace listings are not supported
- No rating distribution or language filter — Facebook does not expose either on the reviews surface
- Review photos are rare — the field is kept for compatibility but is usually absent
- Reviewer identity is not always stable —
authorIdTypereports whether the author ID is a stable numeric ID or a rotatingpfbidtoken - Facebook can change its internal review operation — the actor detects a rotated operation identifier and refreshes it, but a major upstream change can still require an actor update
Python quickstart
Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.
Source build mOLyljzUlnPCEScHZ. Documentation is regenerated from the default published build; private drafts are not included.