# Facebook Posts Scraper (`harpoon/fb-posts-scraper`) Actor

Scrape posts from Facebook profiles and pages by URL or numeric id. Pushes one dataset item per fetched feed batch.

- **URL**: https://apify.com/harpoon/fb-posts-scraper.md
- **Developed by:** [Harpoon](https://apify.com/harpoon) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 posts

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?

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 Posts Scraper

Extract posts from Facebook profiles, pages, and public groups — captions, media, publish time, and full engagement (reactions, comments, shares, views) — as clean, ready-to-use rows.

- **Every post, not just the latest.** Walk a profile's history forward or bound it to a date range.
- **Public groups too.** Add a group URL to the same list and pull its discussion feed the same way.
- **Public data only.** No login, cookies, or account required.
- **Engagement included.** Reactions, comments, shares, views, media URLs, and author details in the same row.
- **One row per post.** Export to JSON, CSV, Excel, or XML straight from the dataset.

> Built for content research, competitor tracking, influencer analysis, community research, brand monitoring, and AI/LLM datasets.

### What can Facebook Posts Scraper do?

| Target | What it does |
|--------|--------------|
| `users` (profile / page / public group URLs) | Fetch posts from profiles, pages, and public groups. |
| Numeric ids | Target a profile or page by its numeric Facebook id. |

You control **how many** posts come back (`max_posts`) and can narrow the run with **date bounds**. Profiles and pages are fetched fast in parallel time windows; group feeds can be ordered by **new posts**, **top posts**, or **recent activity**.

Every run also gives you export to JSON / CSV / Excel / XML, API and webhook access, scheduled runs, and MCP access for AI agents.

### What data can you get?

One row per post, with these fields:

| 📦 Group | 🔎 Fields |
|----------|-----------|
| **Identity** | `post_id`, `feedback_id`, `permalink_url`, `seo_title` |
| **Content** | `text`, `media_type`, `media_url`, `is_video`, `is_text_only_story` |
| **Timing** | `creation_time`, `publish_time`, `published_at`, `created_at` |
| **Engagement** | `likes`, `views`, `comments`, `shares`, `video_view_count`, `video_post_view_count` |
| **Author** | `actors.id`, `actors.name`, `actors.url`, `actors.profile_picture` |
| **Details** | `engagement.*`, `media[]`, `story_media_metadata.*`, `collaborators`, `interesting_top_level_comments` |
| **Flags** | `sponsored_data`, `paid_partnership` |

### How to use Facebook Posts Scraper

1. [Create](https://console.apify.com/sign-up) a free Apify account.
2. Open **Facebook Posts Scraper** in Apify Console.
3. Paste one or more profile, page, or public group URLs into **Profiles / Pages / Groups**.
4. Optionally set **Max posts per target** and date bounds.
5. Click **Start** and wait for the run to finish.
6. Download from **Storage ▸ Dataset** as JSON, CSV, Excel, or XML.

### Input

There are two ways to identify a target — use either (they can be mixed in the same list):

- **URL** — paste the profile, page, or public group URL, e.g. `https://www.facebook.com/zuck` or `https://www.facebook.com/groups/dataminers`.
- **Numeric id** — a profile/page numeric id, e.g. `4`. To target a group by id, use its `/groups/<id>` URL.

All targets go in the same **Profiles / Pages / Groups** list; group URLs are detected automatically.

#### Results

- `max_posts` — hard cap on posts per profile, page, or group (default `20`). The final batch is trimmed so exactly up to this many posts are returned.

#### Time frame

- `after_time` — only posts published on or after this point (**profiles/pages only**).
- `before_time` — only posts published on or before this point (**profiles/pages only**).

Each field has an **Absolute / Relative** switch: **Absolute** takes a date (`2024-01-01`) or full timestamp (`2024-01-01T12:00:00`); **Relative** takes a rolling window like `3 days`, `2 weeks`, or `1 month`. Times are UTC.

Public group feeds have no server-side date filtering, so group posts ignore `after_time`/`before_time` — every fetched post is returned up to `max_posts`.

#### Group post order

- `group_sort` — order for group feeds: `CHRONOLOGICAL` (default, newest first), `TOP_POSTS` (Facebook's ranking), or `RECENT_ACTIVITY` (bumped by new comments, so old posts can appear).

#### Language

- `language` — locale used when requesting the posts.

**Example input**

```json
{
  "users": [
    "https://www.facebook.com/zuck",
    "https://www.facebook.com/groups/dataminers"
  ],
  "group_sort": "CHRONOLOGICAL",
  "max_posts": 20,
  "language": "en"
}
```

See the **Input** tab above for every field and its default.

### Output

Results land in the default dataset under **Storage ▸ Dataset**. Built-in **Overview** and **Engagement** views make the data readable immediately. Download as JSON, CSV, Excel, or XML.

**Sample post**

```json
{
  "post_id": "10117934760258471",
  "feedback_id": "ZmVlZGJhY2s6MTAxMTc5MzQ3NjAyNTg0NzE=",
  "permalink_url": "https://www.facebook.com/reel/2281597032594351/",
  "text": "...",
  "creation_time": 1788893848,
  "publish_time": 1788892763,
  "published_at": "2026-01-15T12:00:00Z",
  "media_type": "Video",
  "media_url": "https://...",
  "likes": 10000,
  "views": 0,
  "comments": 29370,
  "shares": 9583,
  "is_video": true,
  "actors": { "id": "4", "name": "Mark Zuckerberg", "url": "https://www.facebook.com/zuck", "profile_picture": "https://..." },
  "engagement": {
    "reaction_count": 10000,
    "comment_count": 29370,
    "share_count": 9583,
    "top_reactions": [ { "localized_name": "Like", "reaction_count": 9032 } ]
  },
  "media": [ { "browser_native_hd_url": "https://...", "thumbnail_image": "https://...", "width": 1080, "height": 1920 } ]
}
```

Field names follow Facebook's own lowercase snake\_case names.

### Use cases

1. **Content and cadence research** — pull a page's recent posts and analyze posting frequency, formats, and topics.
2. **Competitor benchmarking** — compare engagement (`likes`, `comments`, `shares`, `views`) across pages.
3. **Influencer vetting** — check post reach and reaction mix before a partnership.
4. **Brand monitoring** — track your own posts over a date range and export to your BI tool.
5. **AI / LLM datasets** — use captions, media URLs, and engagement as structured training or RAG data.

### How much does it cost?

Facebook Posts Scraper is priced **per result** (pay-per-result) at **$2.00 per 1,000 posts** ($0.002 each), plus a small Apify platform fee. Starting a run is free.

- 1,000 posts ≈ **$2.00** in actor cost.
- 5,000 posts ≈ **$10.00**.
- Filtered-out or failed items are not charged.

See the **Pricing** tab for plan discounts.

### FAQ

**Do I need a Facebook account, login, or cookies?**
No. The actor reads publicly available posts — no login, cookies, or account required.

**Can it get posts from public groups?**
Yes. Add public group URLs to `users` (for example `https://www.facebook.com/groups/dataminers`) — they are detected automatically. Private groups are not supported; only posts that are visible without logging in are returned.

**Can it get posts from private profiles or groups?**
No. It only returns posts that are visible publicly.

**How many posts can I get?**
`max_posts` (default `20`) caps the total per profile, page, or group. Raise it for more, but large pulls take longer.

**Why do the numbers differ from what I see when logged in?**
Public views can show different reaction or view counts than a logged-in session. The dataset reflects what is publicly available at run time.

**Is it legal to extract this data?**
Results may contain personal data, which is protected by GDPR and similar laws. Only scrape personal data when you have a legitimate reason, and follow the terms of the data source and your local laws.

**Can I use it from the API, SDKs, or an AI agent?**
Yes — use the **API** tab for JavaScript, Python, REST, and CLI examples, or connect the Apify MCP server to call it from Claude, ChatGPT, or another MCP client.

**Something isn't working.**
Check that each entry is a valid profile/page URL or numeric id. If it still fails, open an issue in the **Issues** tab with your input JSON.

### Notes and limitations

- **Public content only** — private profiles, private/restricted groups, and login-walled posts are not available.
- **`max_posts` is a hard cap** — the final batch is trimmed so the total is never exceeded.
- **Parallel time windows** — profiles/pages are fetched as parallel weekly windows and stitched newest-first. A post sitting exactly on a window boundary can occasionally be skipped.
- **Groups walk the feed sequentially** — public group feeds have no date-range support, so they are walked page by page (with `group_sort`).
- **Group date bounds are ignored** — `after_time`/`before_time` only apply to profiles and pages. Public group feeds are not filtered by date, so every fetched post is returned up to `max_posts`. Old posts can still appear because `group_sort: RECENT_ACTIVITY`/`TOP_POSTS` surface posts by engagement or comments; use `group_sort: CHRONOLOGICAL` for newest-first ordering.
- **Counts can differ from the logged-in view** — hidden or viewer-specific metrics won't appear.
- **Personal data** — posts and author details may contain personal data. Handle the results accordingly.

### Integrations

Call the actor from your own code or an AI agent — see the **API** tab for JavaScript, Python, REST, and CLI. MCP clients can add the actor via the Apify MCP server. Schedule runs or trigger them with webhooks from Apify Console.

### Support

Found a bug or have feedback? Open an issue in the **Issues** tab, or email **islam.tazerout@outlook.com**.

# Actor input Schema

## `users` (type: `array`):

Profile, page, or public group URLs, or numeric profile/page ids. Examples: <code>https://www.facebook.com/zuck</code>, <code>4</code>, <code>https://www.facebook.com/groups/dataminers</code>. Group URLs are detected automatically and scraped as public groups. Add one per line, or paste a list with <b>Bulk edit</b>. Duplicates are removed automatically.

## `group_sort` (type: `string`):

How posts are ordered when fetching from public groups. <b>Top posts</b> is Facebook's ranking, <b>Recent activity</b> bumps posts that got new comments (so old posts can appear), and <b>New posts</b> is chronological.

## `max_posts` (type: `integer`):

How many posts to fetch per profile, page, or group. The final batch is trimmed so the total never exceeds this number.

## `language` (type: `string`):

Locale used when requesting the posts. Posts are returned in the language Facebook provides for that locale.

## `after_time` (type: `string`):

Only include posts published on or after this date. Switch between <b>Absolute</b> (<code>2024-01-01</code> or a full timestamp <code>2024-01-01T12:00:00</code>) and <b>Relative</b> (<code>3 days</code>, <code>2 weeks</code>, <code>1 month</code>). Times are UTC. <b>Applies to profiles and pages only</b> - public group feeds have no server-side date filtering, so group posts ignore this.

## `before_time` (type: `string`):

Only include posts published on or before this date. Switch between <b>Absolute</b> (<code>2024-01-01</code>) and <b>Relative</b> (<code>2 weeks</code>, <code>1 year</code>). Times are UTC. <b>Applies to profiles and pages only</b> - public group posts ignore it.

## Actor input object example

```json
{
  "users": [
    "https://www.facebook.com/zuck",
    "https://www.facebook.com/groups/dataminers",
    "100044234596005"
  ],
  "group_sort": "CHRONOLOGICAL",
  "max_posts": 20,
  "language": "en"
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per scraped post. Export as JSON, CSV, Excel, or XML.

# 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 = {
    "users": [
        "https://www.facebook.com/zuck"
    ],
    "group_sort": "CHRONOLOGICAL",
    "max_posts": 20,
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("harpoon/fb-posts-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 = {
    "users": ["https://www.facebook.com/zuck"],
    "group_sort": "CHRONOLOGICAL",
    "max_posts": 20,
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("harpoon/fb-posts-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 '{
  "users": [
    "https://www.facebook.com/zuck"
  ],
  "group_sort": "CHRONOLOGICAL",
  "max_posts": 20,
  "language": "en"
}' |
apify call harpoon/fb-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,harpoon/fb-posts-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/okcxCQXXgCgKhZgZL/builds/FCCnlD3UJc712G4t6/openapi.json
