# Facebook Post & Reel Views Scraper (No Login) (`datafinch/facebook-post-stats-scraper`) Actor

Get exact views, plays, reactions, comments and shares for any public Facebook post, reel or video link. No login. Bulk links, export to CSV or JSON.

- **URL**: https://apify.com/datafinch/facebook-post-stats-scraper.md
- **Developed by:** [Datafinch](https://apify.com/datafinch) (community)
- **Stats:** 21 total users, 9 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.79 / 1,000 link 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 Post & Reel Views Scraper (No Login)

Paste Facebook post, reel and video links and get the current **views, plays, reactions, comments and shares** for each one. One row per link, with a clear status, no Facebook account needed.

Built by **Datafinch**: exact data where Facebook publishes it, low cost, one row per input with a clear status, and fields that stay consistent so your workflows don't break.

### What it does

- **Exact views and plays for reels and videos**, not just the rounded "581K views" label.
- **Reactions, comments and shares** for posts, reels, videos and photos, with the **reaction breakdown** (Like, Love, Care, Haha, Wow, Sad, Angry) where Facebook publishes it.
- **Many links per run**, up to 1,000.
- **One row per input link**, including links that fail, so you can always match results back to your list.
- **No login, no cookies.** Only publicly visible data is collected.

Supported links: posts (`/posts/…`, `pfbid…`), reels (`/reel/…`, `/reels/…`), videos (`/videos/…`, `/watch/?v=…`), photos, `permalink.php` and `story.php`, share links (`/share/p/…`, `/share/r/…`, `/share/v/…`) and `fb.watch` short links. `www.`, `m.` and `web.` all work.

### Input

```json
{
  "urls": [
    "https://www.facebook.com/reel/930452829785006/",
    "https://www.facebook.com/somepage/posts/pfbid0ABC...",
    "https://fb.watch/abcDEF123/"
  ]
}
```

Only `urls` is required.

| Field | Default | What it does |
|---|---|---|
| `urls` | – | Facebook links, up to 1,000 per run. |
| `proxyCountry` | `US` | Country the posts are viewed from. Some posts are only available in some countries. |
| `proxyConfiguration` | Built-in | Optional: your own proxy URLs. Proxies are otherwise handled for you and included in the price. |

### Output

One row per input link:

```json
{
  "inputUrl": "https://www.facebook.com/reel/930452829785006/",
  "inputIndex": 0,
  "status": "ok",
  "postType": "reel",
  "likesCount": 15610,
  "commentsCount": 985,
  "sharesCount": 1300,
  "sharesApprox": true,
  "viewsCount": 209098,
  "viewsText": "581K views",
  "playCount": 581286,
  "postId": "1645077636987606",
  "videoId": "930452829785006",
  "timestamp": "2026-10-02T02:09:39.000Z",
  "authorName": "NASA - National Aeronautics and Space Administration",
  "url": "https://www.facebook.com/reel/930452829785006/",
  "duplicateOf": null,
  "charged": true,
  "error": null,
  "scrapedAt": "2026-10-09T12:29:54.525Z"
}
```

*A real result from 9 October 2026. Counts keep changing on Facebook.*

Every row also carries the reaction breakdown. The same NASA reel on 10 October 2026:

```json
{
  "likesCount": 15684,
  "reactionsLike": 12687, "reactionsLove": 2318, "reactionsHaha": 357, "reactionsCare": 251,
  "reactionsWow": 57, "reactionsAngry": 12, "reactionsSad": 2, "reactionsOther": 0,
  "reactionsBreakdownComplete": true,
  "topReaction": "like"
}
```

| Field | Meaning |
|---|---|
| `inputUrl` | The link exactly as you sent it. |
| `inputIndex` | Position of the link in your input list (0 = first). Rows are saved as each link finishes, so sort by this field to restore your input order. |
| `status` | Result for this link (see below). |
| `likesCount` | Total reactions (all reaction types: Like, Love, Haha and so on). |
| `reactionsLike`, `reactionsLove`, `reactionsCare`, `reactionsHaha`, `reactionsWow`, `reactionsSad`, `reactionsAngry` | Reactions per type. `null` when Facebook did not publish that type for this post. |
| `reactionsOther` | Reactions of any type not listed above (for example a temporary seasonal reaction). Usually `null` or 0. |
| `reactionsBreakdownComplete` | `true` when the per-type counts add up to `likesCount`. `false` when Facebook only published some types, so the parts add up to less. Empty (`null`) when there is no breakdown, for example on a failed link. |
| `topReaction` | The most-used reaction type (`like`, `love`, `haha`, ...). |
| `commentsCount`, `sharesCount` | Comment and share counts. `sharesApprox` is `true` when Facebook only shows a rounded share figure such as "1.7K", `false` when the share count is exact, and empty when there is no share count. It is in the API and exports, not in the Console table. |
| `viewsCount` | **Views (exact)**: Facebook's own view count for the video. On reels it is usually lower than plays; on many regular videos it equals plays. Facebook does not display this number on the page. |
| `playCount` | **Plays**: the number Facebook displays as "views" on reels and videos, as an exact figure. |
| `viewsText` | The label exactly as Facebook displays it, e.g. "581K views" (matches `playCount`, rounded). For very new reels Facebook may only publish this rounded figure; `playCount` then holds the rounded value. |
| `postId`, `videoId` | Facebook's post ID and video ID, kept separate. |
| `timestamp` | When the post was published. |
| `authorName`, `authorId`, `authorUrl` | The page or profile that published it. |
| `charged` | Whether this row was charged. |
| `error` | Plain-language reason when the status is not `ok`. |
| `duplicateOf` | Set when the same post appeared earlier in your list. The row has the same data and is charged like any other row. |

In Apify Console, the **Post stats** table shows the main counts; switch to the **Reactions** table to see all reaction types side by side.

**Empty is not zero.** A count Facebook does not publish for that post is `null`. `0` always means Facebook reported zero.

#### Status values

| Status | Meaning | Charged? |
|---|---|---|
| `ok` | Counts found. | Yes |
| `not_found` | Deleted, removed, or the link is wrong. | Yes |
| `no_data` | The page loaded but had no counts for this post. | Yes |
| `error` | Network or page error after retries. | Yes |
| `invalid_input` | Not a single post: a Page, profile or group link, or not a Facebook link. | Yes |
| `free_limit` | Over the free-plan limit for one run. | No |
| `limit_reached` | Your maximum cost per run was reached. | No |
| `blocked_stopped` | The run stopped because Facebook was blocking most requests. | No |
| `not_processed` | The run stopped (timeout or abort) before this link. | No |

### Pricing

**$1.99 per 1,000 links** (pay per result), plus Apify's small start fee per run.

**Every link you send returns a row, and every row is charged**, including links that are deleted, private, invalid or fail. Please check your links before large runs.

Not charged:

- Links over the free-plan limit.
- Links not processed because your maximum cost per run was reached, the run timed out or was aborted, or Facebook was blocking most requests (the run stops early to protect you).

Set a **maximum cost per run** in the run options to cap your spend; the run stops cleanly when it is reached.

**Free Apify plan:** up to 25 links per run, so you can try it.

### Use with n8n, Make, Zapier or the API

Start the Actor with your list of links and read the dataset. Match results to your input with `inputUrl` or `inputIndex`.

```bash
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://www.facebook.com/reel/930452829785006/"]}'
```

**Sync calls time out after 300 seconds.** The Actor handles roughly one link per second, so keep **sync requests to about 150 links**. For larger lists, start the run, wait for it to finish (or use a webhook), then fetch the dataset.

### Limits

- Up to **1,000 links per run**. Split bigger lists into several runs.
- Public content only
- Counts are a snapshot: they keep changing on Facebook. Every row has `scrapedAt`.
- Speed depends on Facebook's response that day. No fixed rate is promised.

### FAQ

**Do I need a Facebook account or cookies?** No. Only public pages are read, without logging in.

**Why are views and plays different?** Facebook records two numbers. The "views" figure you see on a reel is the play count (`playCount`), which counts every play, including replays. `viewsCount` is Facebook's separate view count, which it does not display: on reels it is usually lower than plays, on many regular videos the two are equal. We report both exactly as Facebook publishes them and never merge them. If you are comparing with the number shown on Facebook, use `playCount`.

**Do reels have a reaction breakdown?** Yes, where Facebook publishes it for the reel's video. If it doesn't, the reaction types are empty and the total is still in `likesCount`.

**Why don't the reaction types add up to the total?** Facebook often publishes only the most common reaction types for a post. The ones it doesn't publish are `null` (never a guessed 0) and `reactionsBreakdownComplete` is `false`. When it is `true`, missing types really are 0.

**Why does `sharesApprox` say true?** For some posts Facebook only publishes a rounded share figure such as "1.3K". We return it as 1300 and flag it, rather than guess.

**Why does a reel show `viewsText` but no `viewsCount`?** Facebook did not publish an exact figure for that reel; the rounded label is still returned.

**Why is my output in a different order from my input?** Rows are saved as soon as each link finishes, so you never lose finished results. Sort by `inputIndex` to restore your order.

**Can I schedule it?** Yes. Running the same links daily is a good way to track how a post's numbers grow.

**Something looks wrong?** Open an issue on the **Issues** tab with the link and the run ID.

# Actor input Schema

## `urls` (type: `array`):

Post, reel, video, photo, permalink, share and fb.watch links (www, m. and web. all work). Up to 1,000 links per run. Every link gets its own row and is charged, including repeated links.

## `proxyCountry` (type: `string`):

Two-letter country code the posts are viewed from. Some posts are only available in some countries. Default: US.

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

Optional. Add your own proxy URLs to load every link through them. Apify Proxy settings here are ignored: the Actor uses its own built-in proxy strategy, which is included in the price.

## Actor input object example

```json
{
  "urls": [
    "https://www.facebook.com/reel/930452829785006/"
  ],
  "proxyCountry": "US",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `reactions` (type: `string`):

No description

## `runStats` (type: `string`):

No description

# 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 = {
    "urls": [
        "https://www.facebook.com/reel/930452829785006/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datafinch/facebook-post-stats-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 = {
    "urls": ["https://www.facebook.com/reel/930452829785006/"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("datafinch/facebook-post-stats-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 '{
  "urls": [
    "https://www.facebook.com/reel/930452829785006/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call datafinch/facebook-post-stats-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datafinch/facebook-post-stats-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/BFzuQbzFrmACTETkA/builds/0iggK8Jq8gIjFhTKM/openapi.json
