# Facebook Reviews Scraper (`scraper-engine/facebook-reviews-scraper`) Actor

Scrape Facebook page reviews efficiently using this Apify actor. It collects reviewer names, ratings, comments, timestamps, and review links. Perfect for sentiment analysis, brand monitoring, or competitor research with clean, structured data exportable to JSON, CSV, or Excel formats.

- **URL**: https://apify.com/scraper-engine/facebook-reviews-scraper.md
- **Developed by:** [Scraper Engine](https://apify.com/scraper-engine) (community)
- **Categories:** Social media, Automation, Agents
- **Stats:** 106 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

$19.99/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period. You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Facebook Reviews Scraper — Text, Recommendations and Reviewer Data

Facebook Reviews Scraper extracts public review and recommendation posts from any Facebook page — review text, recommendation status, reviewer name and profile link, likes and comment counts, and the page's own published recommend percentage — as clean, structured JSON with one row per review. No Facebook login, no HTML parsing, no CSS selectors to maintain. Add a page URL or handle, set how many reviews you want, and run.

### 🧭 What is Facebook Reviews Scraper?

Facebook Reviews Scraper is an Apify Actor that collects the public review/recommendation feed of one or more Facebook pages and returns each review as an individual, ready-to-export dataset row. It does not require a Facebook account, login, or session cookie — it reads only what a page publishes publicly. It's built for brand and reputation teams, market researchers, and developers who need Facebook review data in a repeatable, structured feed instead of copy-pasting from the page.

### 🌐 What Facebook review data is publicly available to scrape?

Facebook exposes review text, recommendation status, reviewer identity, and engagement counts on any page that has recommendations switched on — none of it requires logging in.

| Data Category | Publicly Available | Restricted |
| --- | --- | --- |
| Review text & recommendation status | Yes, on pages with reviews/recommendations enabled | No — pages that switch reviews off return nothing (a page-owner setting) |
| Reviewer name, profile link, avatar | Yes, as published on the review | The reviewer's private profile content beyond what they've made public |
| Review likes & comment counts | Yes, as counts | The comment text itself is not exposed on this surface — count only |
| Page's overall recommend % and total review count | Yes, when Facebook currently shows a summary on the page | Not shown at all when the page hasn't published one |
| Reviewer's stable identity | Yes for numeric-ID accounts | Rotating `pfbid` tokens are not a durable cross-run join key |
| Private page reviews | — | Always restricted; this Actor never accesses login-gated content |

⚠️ Reviews/recommendations being switched off is a page-owner setting, not a limitation of the scraper — the only way to know is to request the page.

Facebook Reviews Scraper only returns publicly visible data — what any visitor sees. Nothing behind a login wall.

### 📋 What data can I extract with Facebook Reviews Scraper?

Facebook Reviews Scraper returns review identity and text, reviewer identity, engagement metrics, and the page's own published recommendation summary — 21 fields per row plus a nested legacy `user` object.

| Field Name | Description |
| --- | --- |
| `id` | Unique identifier of the review/recommendation post. |
| `type` | Row type — always `"review"`. |
| `isChild` | Always `false` — this Actor produces no nested/child rows. |
| `text` | Full review text. |
| `date` | Review creation date, ISO 8601 (UTC). |
| `url` | Direct link to the review post. |
| `facebookUrl` | The page URL that was scraped (resolved, `/reviews` suffix stripped). |
| `inputUrl` | The exact value you supplied for this page in `inputs`. |
| `facebookId` | Facebook's internal feedback ID for the review. |
| `postFacebookId` | Facebook's internal post ID for the review. |
| `pageName` | The page's own display name. |
| `scrapedAt` | When this row was collected, ISO 8601 (UTC). |
| `isRecommended` | Whether the reviewer recommended the page. `true`/`false`, or `null` when the recommendation sentence couldn't be read reliably — never guessed. |
| `likesCount` | Reactions on the review. `null` when unreadable, never a fabricated `0`. |
| `commentsCount` | Comment count on the review (count only). |
| `pageRecommendPercent` | The page's own published "% recommend" figure, when Facebook shows one. |
| `pageTotalReviewCount` | The page's own published total review count, when Facebook shows one. |
| `reviewerName` | Reviewer's display name. |
| `reviewerProfileUrl` | Link to the reviewer's profile. |
| `reviewerProfilePic` | Reviewer's avatar URL, when available. |
| `reviewerIdType` | `"numeric"` when the reviewer's Facebook ID is a stable numeric ID, `"pfbid"` when it's a rotating token, `null` when no ID resolved. |

#### Review, page and reviewer identity fields

`id`, `type`, `isChild`, `text`, `date`, `url`, `facebookUrl`, `inputUrl`, `facebookId`, `postFacebookId`, `pageName`, `scrapedAt`

#### Recommendation and engagement metrics

`isRecommended`, `likesCount`, `commentsCount`, `pageRecommendPercent`, `pageTotalReviewCount`, `reviewerIdType`

#### Nested `user` object (kept for backward compatibility)

Every row also carries a `user` object — `{ "id", "name", "profileUrl", "profilePic" }` — duplicating `reviewerName`, `reviewerProfileUrl`, and `reviewerProfilePic` as a nested structure alongside the flat columns.

#### 🤖 Add-on: Need additional Facebook data?

Pair this with **Facebook Event Search Scraper** for public event listings on the same pages, or **Facebook Video Transcript Extractor** if the page also posts video content you want transcribed. Both live in the same Scraper Engine catalog.

### 🆚 How does Facebook Reviews Scraper differ from the official Facebook API?

Meta's Graph API can return a page's ratings, but only to someone who already administers that page — Facebook Reviews Scraper needs only the page's public URL or handle.

According to Meta's own Graph API reference for the Page `ratings` edge (developers.facebook.com, checked 2026-08-15), reading a page's ratings requires a **page access token requested by a person who can perform `CREATE_CONTENT`, `MANAGE`, or `MODERATE`** on that page, plus the `pages_read_user_content` permission — and "parent Page access tokens cannot be used to get recommendations for child Pages." In other words, the official endpoint is built for a page owner to read their own ratings, not for a third party to read anyone's.

| Feature | Facebook Graph API (`/ratings`) | Facebook Reviews Scraper |
| --- | --- | --- |
| Access requirement | Page access token from an admin/moderator of that page, `pages_read_user_content` permission | Just the page's public URL or handle |
| Scope | Only pages you (or your app) already administer | Any public page with reviews enabled — including competitors |
| App review | Requires Meta App Review before `pages_read_user_content` works in production | No approval process |
| Output shape | Raw Graph API JSON, aggregate ratings edge | One normalized row per individual review, stable field names |
| Reviewer-level detail | Aggregate only | Per-review text, reviewer name, profile link, avatar, engagement |
| Setup time | Register a Meta app, pass App Review, mint and refresh page tokens | Provide a page reference and start the run |

Use the Graph API's `/ratings` edge if you already administer the page and only need your own aggregate rating. Use Facebook Reviews Scraper when you need individual review text and reviewer detail from any public page — including ones you don't manage.

### 🚀 How to use Facebook Reviews Scraper

Facebook Reviews Scraper runs on the Apify platform — no separate signup or API key beyond your Apify account.

1. Open **Facebook Reviews Scraper** on the Apify Console.
2. Provide `inputs` — one or more Facebook page URLs or handles (this is the only required field).
3. Optionally set `maxItems` (default `10`, up to `10,000` per page) and a `proxyConfiguration`.
4. Click **Start** to launch the run.
5. Download or stream the results as JSON, CSV, Excel, or the other export formats the Apify dataset supports.

#### How to scale to bulk review extraction

`inputs` is an array (`editor: stringList`) — add as many page URLs or handles as you like and they're all processed in the same run. Internally the Actor works through them concurrently, but caps itself at **3 pages in flight at once** (a fixed concurrency limit in the code), so a large batch of pages queues and works through in waves rather than firing every request at once.

### 💡 What can you do with Facebook review data?

- 🏢 **Brand and reputation teams** monitoring sentiment use `text` and `isRecommended` to track what customers say publicly, without manually reading every post.
- 📊 **Analysts** benchmarking competitors use `pageRecommendPercent` and `pageTotalReviewCount` across multiple pages to compare standing over time.
- 🔬 **Researchers** studying engagement use `likesCount` and `commentsCount` alongside `date` to see which reviews resonate.
- 🎧 **Support and CX teams** triage negative feedback by filtering `isRecommended: false` rows and routing `text` to the right queue.
- 🤖 **AI engineers** feed `text`, `isRecommended`, and `reviewerName` into a RAG pipeline or an LLM-based sentiment classifier as clean, pre-structured input — no parsing step needed.

### 🛡️ How does Facebook Reviews Scraper handle rate limits and blocking?

The Actor makes direct HTTP requests to Facebook's own GraphQL endpoint with browser-matched headers (User-Agent, `sec-ch-ua` client-hint triplets kept in sync) rather than driving a full headless browser. Concurrency is capped at 3 pages processed simultaneously, and each page's own review feed is paged in batches of 3 — Facebook's own server-side cap on that endpoint, not a choice this Actor makes. `proxyConfiguration` is honored exactly as given, with no silent escalation to a proxy tier you didn't select.

If a single request to fetch more reviews fails or comes back empty without pagination moving forward, the Actor retries up to 3 times with a short pause before giving up on that page and moving to the next one — a temporary failure on one page never stops the run. The Actor does not solve CAPTCHAs; if a page cannot be resolved at all, it's marked `temporarily_unavailable`, logged, and skipped.

### ⬇️ Input

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `inputs` | Yes | array of strings | One or more Facebook page links or handles, one per entry. Examples: `https://www.facebook.com/yourfavouritebrand` or `yourfavouritebrand`. Only public pages that have reviews/recommendations enabled will return rows. | `["https://www.facebook.com/mrbeast"]` |
| `maxItems` | No | integer | Maximum number of reviews to collect for each page (1–10,000). Default `10`. | `50` |
| `proxyConfiguration` | No | object | Optional Apify Proxy configuration. Leave off for the simplest setup. | `{"useApifyProxy": false}` |

#### Example input

```json
{
  "inputs": [
    "https://www.facebook.com/mrbeast",
    "dominos"
  ],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

### ⬆️ Output

Every result is typed, normalized JSON with the same field names on every row — export straight to CSV, Excel, JSON, or feed it directly into another tool. Every dataset row is a real, collected review; the Actor pushes no separate accounting or error rows to the dataset.

#### Example output

```json
{
  "id": "UzpfSTYxNTg0MzE3MjA0OTY4OjEyMjEwOTkzMzE4OTE0MzkwNjoxMjIxMDk5MzMxODkxNDM5MDY=",
  "type": "review",
  "isChild": false,
  "facebookUrl": "https://www.facebook.com/mrbeast",
  "inputUrl": "https://www.facebook.com/mrbeast",
  "user": {
    "id": "100004512398765",
    "name": "Jordan Ellis",
    "profileUrl": "https://www.facebook.com/jordan.ellis.94",
    "profilePic": "https://scontent.xx.fbcdn.net/v/t39.30808-1/example_profile.jpg"
  },
  "reviewerName": "Jordan Ellis",
  "reviewerProfileUrl": "https://www.facebook.com/jordan.ellis.94",
  "reviewerProfilePic": "https://scontent.xx.fbcdn.net/v/t39.30808-1/example_profile.jpg",
  "reviewerIdType": "numeric",
  "date": "2026-07-14T09:32:11.000Z",
  "url": "https://www.facebook.com/permalink.php?story_fbid=pfbid02exampleStoryId&id=61584317204968",
  "isRecommended": true,
  "text": "Great customer service and the product arrived earlier than expected. Would order again.",
  "likesCount": 4,
  "commentsCount": 1,
  "facebookId": "ZmVlZGJhY2s6MTIyMTA5OTMzMTg5MTQzOTA2",
  "postFacebookId": "122109933189143906",
  "pageName": "MrBeast",
  "pageRecommendPercent": 96,
  "pageTotalReviewCount": 5190,
  "scrapedAt": "2026-08-15T10:04:22.000Z"
}
```

### ⚙️ How does it work?

Facebook Reviews Scraper fetches the page's public reviews surface over HTTP with browser-matched headers, then reads two things already embedded in that one page load: a first batch of reviews and a pagination cursor buried in Facebook's own `@defer` chunks, plus the GraphQL `doc_id` needed to ask for more. It then pages through Facebook's internal GraphQL endpoint using that cursor until it reaches your `maxItems` limit or the feed runs out. Whether a page reference resolves to a real page with reviews on, a real page with reviews switched off, or no page at all is decided from page content markers, not the HTTP status code alone — Facebook can answer 200 for all three. Only publicly visible data is returned, and the output schema stays stable regardless of Facebook UI changes.

### 🔌 Integrations

Facebook Reviews Scraper runs on Apify, so it works with anything that can call the Apify API or use the `apify-client` SDK.

#### Calling Facebook Reviews Scraper programmatically

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_API_TOKEN>")

run = client.actor("<YOUR_USERNAME>/facebook-reviews-scraper").call(run_input={
    "inputs": ["https://www.facebook.com/mrbeast"],
    "maxItems": 50,
})

for review in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(review["reviewerName"], review["isRecommended"])
```

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.

#### No-code tools (n8n, Make, LangChain)

In **n8n**, point the HTTP Request node at the Actor's run-sync endpoint with your input JSON as the body. In **Make**, use the Apify app's "Run an Actor and Get Dataset Items" module and map `inputs`/`maxItems` from your scenario. In **LangChain**, wrap the run with Apify's dataset loader to pull `text` and `isRecommended` straight into a document store for retrieval.

### ⚖️ Is it legal to scrape Facebook reviews?

Scraping publicly available data is generally lawful; what you can lawfully do with it depends on what that data contains and where your users are. Facebook Reviews Scraper returns only publicly visible reviews — nothing behind a login. Because a review row includes personal data about an identifiable person (`reviewerName`, `reviewerProfileUrl`, `reviewerProfilePic`), storing or processing it falls under data-protection regimes like GDPR (EU) and CCPA (California) if your users or subjects are covered by them — you need a lawful basis for storing and using it, and reasonable limits on retention. Consult legal counsel if your use case involves bulk storage of personal data.

### ❓ Frequently asked questions

#### What Facebook review fields does Facebook Reviews Scraper return?

The core fields are `text`, `isRecommended`, `reviewerName`, `date`, and `likesCount` — see the [full field table](#-what-data-can-i-extract-with-facebook-reviews-scraper) above for all 21 fields plus the nested `user` object.

#### Does Facebook Reviews Scraper require a Facebook account or login?

No. The Actor fetches the page's public reviews surface directly with browser-matched HTTP headers — no login, cookies, or session are used at any point.

#### How many reviews can I extract in one run?

Set `maxItems` per page — from 1 up to 10,000 — and add as many pages as you like to `inputs` in the same run. Concurrency is capped at 3 pages processed at once internally.

#### What happens if a page has reviews disabled or doesn't exist?

The Actor tells these apart from page content, not the HTTP status code: a page with no reviews feed and no recommendation summary returns zero rows and is logged as `reviews_disabled` if the page itself resolved, or `page_not_found` if it didn't. Either way it logs a warning and moves on to the next page in your `inputs` list — it never fabricates rows for a page it couldn't read.

#### Can I scrape multiple Facebook pages at once?

Yes — add multiple entries to `inputs` and they're all collected in the same run, processed concurrently up to 3 pages at a time.

#### Does Facebook Reviews Scraper work with Claude, ChatGPT, and other AI agent tools?

Yes, as an HTTP endpoint. It's callable by any agent framework that can call the Apify API — pass `inputs` and `maxItems` as the run input and read the resulting dataset.

#### How does Facebook Reviews Scraper compare to other Facebook review scrapers?

No third-party comparison data was verified for this listing as of 2026-08-15. What's verifiable from the source: `isRecommended`, `likesCount`, and `commentsCount` are returned as `null` rather than a guessed value whenever they can't be reliably read, and a page's status (`reviews_available`, `reviews_disabled`, `page_not_found`, `temporarily_unavailable`) is decided from page content rather than the HTTP status code alone, so a nonexistent handle and a real page with reviews switched off aren't confused with each other.

#### Does Facebook Reviews Scraper return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with consistent field names across runs — no HTML parsing or selectors needed. Pass it directly to an LLM, index it into a vector store, or feed it to an agent tool.

#### What happens when Facebook changes its layout or anti-bot system?

The Actor is maintained and the output schema is designed to stay stable across Facebook UI changes. No specific update turnaround time is published.

#### Can I use Facebook Reviews Scraper without managing proxies or browser infrastructure?

Yes. The Actor makes its own HTTP requests directly — it doesn't require you to run a browser. `proxyConfiguration` is entirely optional; leave it off and the Actor runs without one.

#### Which Facebook review fields work best for AI training data and RAG indexing?

For RAG, index `text` as the primary passage, with `reviewerName`, `date`, and `isRecommended` as metadata. For training or scoring data, `isRecommended`, `likesCount`, `commentsCount`, `pageRecommendPercent`, and `pageTotalReviewCount` are the fields with the most consistent structure across records, returned as typed primitives (booleans and integers, not strings).

### 🔗 Related scrapers

| Scraper Name | What it extracts |
| --- | --- |
| Facebook Event Search Scraper | Public Facebook event listings |
| Facebook Video Transcript Extractor | Transcripts from Facebook video posts |
| Airbnb Review Scraper | Public guest reviews from Airbnb listings |
| Walmart Reviews Scraper | Public product reviews from Walmart |
| Udemy Course Reviews Scraper | Public course reviews from Udemy |

### 💬 Your feedback

Found a bug or missing a field? Let us know through the Issues tab on the Actor's Apify Console page or by messaging Scraper Engine support — reports like these are how the field list and edge-case handling keep improving.

# Actor input Schema

## `inputs` (type: `array`):

One or more Facebook page links or handles, one per entry.

Examples:

- https://www.facebook.com/yourfavouritebrand
- yourfavouritebrand

Only public pages that have reviews/recommendations enabled will return rows.

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

Maximum number of reviews to collect for each page (1-10,000).

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

Optional Apify Proxy configuration. Leave off for the simplest setup.

## Actor input object example

```json
{
  "inputs": [
    "https://www.facebook.com/mrbeast"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped Facebook page reviews in the default dataset, one item per review.

# 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 = {
    "inputs": [
        "https://www.facebook.com/mrbeast"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper-engine/facebook-reviews-scraper").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 = {
    "inputs": ["https://www.facebook.com/mrbeast"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("scraper-engine/facebook-reviews-scraper").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 '{
  "inputs": [
    "https://www.facebook.com/mrbeast"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call scraper-engine/facebook-reviews-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/2srl0LmdZEJFVUsTd/builds/GYhSQRykL471PbB4k/openapi.json
