# Facebook Video Scraper (`apt_marble/facebook-video-stats-scraper`) Actor

Get real numbers on any public Facebook video or Reel: views and plays reported separately, reactions split by emotion, comments, length, author, caption and media links. Watch, video and Reel links all work in one run. No account or login needed.

- **URL**: https://apify.com/apt\_marble/facebook-video-stats-scraper.md
- **Developed by:** [Hamza](https://apify.com/apt_marble) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 video collecteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## 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 Video Scraper

Give it a Facebook video link and get back how it actually performed: views, plays, reactions with the emotion breakdown, comments, length, dimensions, the author, the caption and direct media links. Watch links, `/videos/` links and `/reel/` links all work and can be mixed in one run — but note that **Reels publish far less publicly**: Facebook shows no view count, no play count and no emotion breakdown on that surface, so those fields arrive empty and `isReel` on every row tells you which surface it came from. Built for social teams, agencies and researchers who need real numbers on public video content instead of screenshots.

No Facebook account, no login and no personal details are involved. Paste links, press start.

### What you can do with it

- **Benchmark your video performance against competitors** using the same public figures for both.
- **Report on a campaign** by feeding in every video link from a flight and exporting one clean sheet.
- **Track how a video ages** by running the same links on a schedule and watching views, plays and reactions climb.
- **Study what earns reactions rather than just views** — the per-emotion breakdown separates a Like from a Love, a Haha from an Angry.
- **Build a content archive** with titles, captions, publish dates, lengths and thumbnails.
- **Compare Reels against regular video** on the same Page, with a flag on every row telling you which surface a number came from.

### What you get

One row per video. An abridged real record:

```
{
  "videoId": "1596135602179420",
  "postId": "1591339195694784",
  "url": "https://www.facebook.com/reel/1596135602179420/",
  "authorName": "NASA - National Aeronautics and Space Administration",
  "authorProfileId": "100044561550831",
  "authorPageId": "54971236771",
  "publishedAt": "2026-07-31T20:58:24.000Z",
  "title": "What's Up: August 2026",
  "text": "The sky is full of excitement this month! …",
  "views": 33155,
  "plays": 193813,
  "durationMs": 163349,
  "width": 1920,
  "height": 1080,
  "isLive": false,
  "reactions": 2363,
  "reactionsBreakdown": { "like": 1967, "love": 348, "care": 29, "wow": 14, "haha": 2, "angry": 2, "sad": 1 },
  "comments": 92,
  "shares": null,
  "hdUrl": "https://video.…fbcdn.net/…mp4",
  "sdUrl": "https://video.…fbcdn.net/…mp4",
  "thumbnailUrl": "https://scontent.…fbcdn.net/….jpg",
  "mediaUrlExpiresAt": "2026-08-06T05:41:19.000Z",
  "isReel": false,
  "identityMatchesRequest": true,
  "availability": "OK",
  "sourceUrl": "https://www.facebook.com/watch/?v=1596135602179420",
  "scrapedAt": "2026-08-01T20:14:02.117Z"
}
```

**Views and plays are two different measurements and both are reported.** On the video above, views were 33,155 while plays were 193,813 — nearly six times higher. Anything that reports a single "view count" for a Facebook video is quietly picking one of them for you.

### Input reference

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| Video and Reel links | list of text | empty | The videos you want. Watch links, `/videos/` links and `/reel/` links are all accepted, as is a bare numeric video id. |
| Include media links | true/false | true | Whether to include the direct video and thumbnail links in each row. |
| Browse from | choice | United States | Which country to browse from. |
| Parallel work | number (1–8) | 4 | How many videos are collected at the same time. Four is a good balance. |

### Output fields

| Field | Type | Notes |
| --- | --- | --- |
| `videoId` | text | The video's own id — the one in the link. |
| `postId` | text | The id of the post that published it. For a Reel this is a **different** number from the video id. |
| `url` | text | The video's page on Facebook. |
| `authorName` | text or empty | The publishing profile's name. |
| `authorProfileId` | text | The publishing profile's numeric id. |
| `authorPageId` | text or empty | The Page's numeric id, which is a different number in a different namespace. Both are given so neither is mistaken for the other. |
| `publishedAt` | text | Publish time in a fixed universal format. |
| `title` | text or empty | The video title, when the publisher set one. |
| `text` | text or empty | The caption. |
| `views` | number or empty | How many times it was viewed. |
| `plays` | number or empty | How many times it was played. A different measurement from views. |
| `durationMs` | number | Length in milliseconds. |
| `width`, `height` | number or empty | Pixel dimensions. |
| `isLive` | true/false or empty | Whether it is a live broadcast. |
| `reactions` | number | Total reactions. |
| `reactionsBreakdown` | object or empty | Reactions split by emotion. Covers the most common emotions, so it adds up to at most the total, never more. |
| `comments` | number | Comment count. |
| `shares` | number or empty | Only present where Facebook publishes an exact figure. |
| `hdUrl`, `sdUrl`, `thumbnailUrl` | text or empty | Direct media links. **Temporary — see below.** |
| `mediaUrlExpiresAt` | text | The exact moment the media links in this row stop working. |
| `isReel` | true/false | True when the row came from the Reels surface, where Facebook publishes fewer figures. |
| `identityMatchesRequest` | true/false | Whether the video that came back is the one you asked for. |
| `availability` | text | `OK` on every delivered row. |
| `sourceUrl` | text | The link you supplied. |
| `scrapedAt` | text | When the row was collected. |

An empty field means "Facebook does not publish this for this video", never zero.

### Pricing

You pay per video delivered — **$1.50 per 1,000 videos**, and nothing else. There is no monthly fee and no charge for a run that finds nothing.

A video that cannot be read publicly, or a link whose id does not exist, is **not charged**. It is counted in the run summary as unavailable and never appears in your results.

Worked example: a weekly competitor report covering 200 videos costs about **$0.30**. A one-off audit of 5,000 videos costs about **$7.50**.

### Limits & what this actor cannot do

- **Media links are temporary.** Every direct video and thumbnail link Facebook hands out is time-limited — roughly four days for video. Every row carries `mediaUrlExpiresAt` so you know exactly when, and the run summary repeats the earliest deadline in the batch. The links cannot be renewed or extended, so a "download it later from the saved link" workflow is not possible: download inside the run, or run again when you need the file.
- **Views and plays are different measurements.** Both are reported and neither is merged into the other. If you need one headline number, choose deliberately.
- **Reels publish much less.** No view count, no play count, no per-emotion breakdown and no exact share figure — Facebook simply does not show them publicly on that surface. Those fields arrive empty rather than as a fabricated zero, and `isReel` on every row tells you why.
- **A Reel's post id is not the id in its link.** Both are reported so records join correctly.
- Exact share counts are not published on the video and Reel surfaces. Where only a rounded label such as "1.7K" exists, the field is left empty rather than turned into a number that looks exact but is not.
- Reaction, comment, view and play counts are a live snapshot and keep moving — two readings of the same video seconds apart differed.
- The per-emotion breakdown covers the most common emotions rather than every one, so it sums to at most the total. Do not treat it as a complete split.
- Some videos are set so they are only visible to logged-in visitors, and a link with an id that does not exist looks exactly the same from the outside. Both are reported as unavailable, never as an empty result, and neither is charged.
- **Every row is the video you asked for.** A deleted or mistyped link can come back as a normal-looking page that shows a suggested video instead — same size, same layout, real numbers, wrong video. Every figure, link and author on a row is matched to the id in the link you supplied, so a page like that is reported as unavailable and not charged, rather than delivered as somebody else's numbers under your id.
- Comment text is not collected — this actor reports the comment count.
- Speed depends on the size of the job and on Facebook's own response times. No fixed throughput is promised.
- Facebook's terms prohibit automated access, and video content and its metadata can contain personal data. You are responsible for using what you collect lawfully, in line with Facebook's terms and with applicable privacy law, and for respecting the rights of the people who made the content.

### FAQ

**Do I need a Facebook account?**
No. Nothing is collected that a logged-out visitor cannot see.

**Does it need my login or personal details?**
No. There is nothing to connect and nothing to authorise.

**Can I schedule it?**
Yes. Running the same links daily is the simplest way to watch how a video ages.

**Is the data complete?**
It is complete for regular video: views, plays, reactions with the emotion breakdown, comments, length and dimensions. It is deliberately thinner for Reels, because Facebook publishes less about them — see the limits above.

**Can I download the videos later using the links in my results?**
No. Those links stop working after a few days and cannot be renewed. Every row tells you the exact deadline. Download during the run, or run again when you need the file.

**Why is `shares` empty on so many rows?**
Because Facebook does not publish an exact share count on the video and Reel surfaces. Rather than convert a rounded label into a number that looks precise, the field is left empty.

**Why does a Reel have fewer numbers than a regular video?**
Because Facebook publishes fewer numbers for Reels publicly. The `isReel` flag marks those rows so the gaps are never mistaken for zero engagement.

# Actor input Schema

## `videoUrls` (type: `array`):

Links to the Facebook videos and Reels you want. Watch links, /videos/ links and /reel/ links all work, and you can mix them freely in one run.

## `includeMedia` (type: `boolean`):

Include the direct video and thumbnail links in each record. These links are temporary: every record also carries the exact moment its links stop working.

## `country` (type: `string`):

The country to browse from. Useful when a video is shown differently in different regions.

## `concurrency` (type: `integer`):

How many videos are collected at the same time. Four is a good balance; raising it does not always finish sooner.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.facebook.com/watch/?v=1596135602179420",
    "https://www.facebook.com/reel/1629850552078859"
  ],
  "includeMedia": true,
  "country": "us",
  "concurrency": 4
}
```

# Actor output Schema

## `dataset` (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 = {
    "videoUrls": [
        "https://www.facebook.com/watch/?v=1596135602179420",
        "https://www.facebook.com/reel/1629850552078859"
    ],
    "includeMedia": true,
    "country": "us",
    "concurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/facebook-video-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 = {
    "videoUrls": [
        "https://www.facebook.com/watch/?v=1596135602179420",
        "https://www.facebook.com/reel/1629850552078859",
    ],
    "includeMedia": True,
    "country": "us",
    "concurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/facebook-video-stats-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.facebook.com/watch/?v=1596135602179420",
    "https://www.facebook.com/reel/1629850552078859"
  ],
  "includeMedia": true,
  "country": "us",
  "concurrency": 4
}' |
apify call apt_marble/facebook-video-stats-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=apt_marble/facebook-video-stats-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eHlbFXiY0mj87jRNJ/builds/82nOJDygtTk9TEexr/openapi.json
