# Facebook User Posts Scraper — Public Profile Timeline (`khadinakbar/facebook-user-posts-scraper`) Actor

Scrape recent public posts from Facebook user/profile URLs. Returns text, post URL, author, timestamps, reactions, comments, and media. Cookieless ScrapeCreators + SociaVault. Not for Groups or follower rosters. MCP-ready. $0.005/post.

- **URL**: https://apify.com/khadinakbar/facebook-user-posts-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 post scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Scrape recent **public posts from Facebook user and profile URLs**. Paste one or more profile vanity links (for example `https://www.facebook.com/pacemorby`); each dataset row is one public post with text, post URL, author, timestamps, reactions, comments, shares, and media when Facebook exposes them.

This Actor is **cookieless and login-free**. It reads public timeline data through ScrapeCreators (primary) with SociaVault fallback, runs on Apify (API, schedules, webhooks, MCP), and returns flat JSON ready for agents and dashboards.

Facebook is a trademark of its owner. This independent Actor is not affiliated with, associated with, or endorsed by Meta or Facebook.

### Best fit for this Actor

- Monitor public-figure and personal-brand Facebook timelines for competitive content
- Pull engagement snapshots (reactions / comments / shares) for creator audits
- Feed recent public posts into social listening, CRM enrichment, or content research
- Agent workflows that need profile URL → structured posts without a browser session

**Not this Actor?** Use [Facebook Posts Scraper](https://apify.com/khadinakbar/facebook-posts-scraper) for multi-source page/group/direct post jobs, [Facebook Group Posts Scraper](https://apify.com/khadinakbar/facebook-group-posts-scraper) for Groups, and [Facebook Followers Scraper](https://apify.com/khadinakbar/facebook-followers-scraper) for page follower/like **counts** (not the login-gated follower roster).

### Practical scenario

A brand analyst pastes `https://www.facebook.com/pacemorby` with `maxPostsPerProfile: 3`. The Actor normalizes the URL, calls the profile-posts provider chain, keeps three public posts with text and engagement, charges three `post-scraped` events, and writes `OUTPUT` / `RUN_SUMMARY` with `COMPLETE` when every profile succeeds.

### Quick start input

```json
{
  "profileUrls": ["https://www.facebook.com/pacemorby"],
  "maxPostsPerProfile": 3,
  "resultsLimit": 20,
  "provider": "auto"
}
```

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `profileUrls` | array | Required public profile / vanity URLs. Prefill: `pacemorby`. Also accepts public Pages such as `NASA`. |
| `maxPostsPerProfile` | integer | Cap per profile (1–100). Prefill **3** for quality tests; default 10. |
| `resultsLimit` | integer | Hard cap across the whole run (1–500). Primary spend control. |
| `onlyPostsNewerThan` | string | Optional `YYYY-MM-DD` or relative windows such as `7 days` / `2 months`. |
| `onlyPostsOlderThan` | string | Optional upper date bound. Posts with unparseable timestamps are kept. |
| `provider` | enum | `auto` (ScrapeCreators → SociaVault), or pin one provider for diagnostics. |

Group URLs, Marketplace, Ads Library, and individual post/reel permalinks are rejected as invalid input — route those jobs to the sibling Actors above.

### What data you receive

One dataset item is one public Facebook post.

```json
{
  "profileUrl": "https://www.facebook.com/pacemorby",
  "postUrl": "https://www.facebook.com/pacemorby/posts/1234567890",
  "postId": "1234567890",
  "authorName": "Pace Morby",
  "authorUrl": "https://www.facebook.com/pacemorby",
  "authorId": "100012345",
  "text": "New project update for the team…",
  "timestamp": "2026-09-01T12:00:00.000Z",
  "timestampText": "2026-09-01T12:00:00+0000",
  "reactionsCount": 120,
  "commentsCount": 14,
  "sharesCount": 3,
  "media": ["https://scontent.xx.fbcdn.net/v/example.jpg"],
  "provider": "scrapecreators",
  "scrapedAt": "2026-09-22T12:00:00.000Z"
}
```

| Field | Meaning |
|---|---|
| `profileUrl` | Canonical profile URL that was scraped |
| `postUrl` / `postId` | Public post permalink and ID when available |
| `authorName` / `authorUrl` / `authorId` | Author identity fields when exposed |
| `text` | Caption / body text |
| `timestamp` / `timestampText` | ISO time when parseable + raw provider string |
| `reactionsCount` / `commentsCount` / `sharesCount` | Public engagement aggregates |
| `media` | Image/video URLs when present |
| `provider` | `scrapecreators` or `sociavault` |
| `scrapedAt` | ISO scrape timestamp |

You can download the dataset as JSON, CSV, Excel, or HTML from the Output tab. `OUTPUT` and `RUN_SUMMARY` in the default key-value store hold `outcome`, `itemsPushed`, and run diagnostics.

### Coverage contract

- **In scope:** Public personal profiles and public vanity / Page timelines visible without login; cursor pagination; cookieless providers.
- **Out of scope:** Private / friends-only / age-gated timelines; Messenger; full follower rosters; Groups as the primary product; video transcripts; login or cookie BYOK.
- Valid profile with no matching public posts → `VALID_EMPTY` (no `post-scraped` charges).
- Empty / non-Facebook / group / post-permalink input → `INVALID_INPUT`.
- Total provider outage with zero rows → `UPSTREAM_FAILED`.
- Missing owner provider keys → `CONFIG_ERROR`.

### Pricing

Pay per event + **platform usage pass-through** (`isPPEPlatformUsagePaidByUser: true`):

| Event | Price |
|---|---|
| `apify-actor-start` | $0.00005 (once per run) |
| `post-scraped` | **$0.005** per saved public post |

Invalid input and fully empty valid runs are not charged the post event. See the Actor Pricing tab for the live table. Providers return about **3 posts per API page**, so deeper `maxPostsPerProfile` values cost more upstream credits.

#### Rough cost examples

- Prefill 3 posts → about **$0.015** PPE + small compute usage
- 20 posts → about **$0.10** PPE (+ start)

### How to use

1. Open the Actor in Apify Console and paste one or more public Facebook profile URLs.
2. Keep `maxPostsPerProfile` at 3 for a cheap quality sample; raise `resultsLimit` only when you need more rows.
3. Start the run, then export the dataset or read it from the API / MCP.

#### API example

```bash
curl "https://api.apify.com/v2/acts/khadinakbar~facebook-user-posts-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"profileUrls":["https://www.facebook.com/pacemorby"],"maxPostsPerProfile":3}'
```

#### MCP note

On Apify MCP this Actor appears as `apify--facebook-user-posts-scraper` (or `khadinakbar/facebook-user-posts-scraper`). Pass `profileUrls` and read dataset rows for `postUrl`, `text`, and engagement fields. Check `RUN_SUMMARY.outcome` before treating an empty dataset as an outage.

#### Agent prompt card

> Use `khadinakbar/facebook-user-posts-scraper` with `profileUrls: ["https://www.facebook.com/pacemorby"]`, `maxPostsPerProfile: 3`. Read `postUrl`, `text`, `reactionsCount`, `commentsCount`, and `provider`. If the job is a Group URL, call `facebook-group-posts-scraper` instead. If you only need follower counts, call `facebook-followers-scraper`.

### Best results tips

- Prefer profiles that publish publicly (creators, public figures, brand Pages with open timelines).
- Use `resultsLimit` as the spend guardrail on multi-profile batches.
- Pin `provider` only when diagnosing a specific upstream; leave `auto` for production.
- Pair timeline posts with [Facebook Followers Scraper](https://apify.com/khadinakbar/facebook-followers-scraper) when you also need page follower/like counts.

### Builder's note

Native Facebook HTML for personal timelines is login-walled. The working path is ScrapeCreators `GET /v1/facebook/profile/posts` (about three posts per credit) with SociaVault `GET /v1/scrape/facebook/profile/posts` as fallback. Input validation deliberately rejects `/groups/`, Marketplace, Ads Library, and post permalinks so this SKU stays a clean “user/profile posts” tool and routes Groups / general posts / follower counts to portfolio siblings.

### Legal / responsible use

Use only for **public** Facebook data and lawful marketing, research, or brand-safety workflows. Respect Meta’s terms and applicable privacy laws. Do not use this Actor to access private profiles, scrape people who have not made content public, or build unauthorized contact databases. You are responsible for how you store and process the results.

### Support

Open an Issue on the Actor page for bugs or feature requests. Custom enrichment pipelines and private deployments are available on request.

# Changelog

This Actor's version history is a separate document: https://apify.com/khadinakbar/facebook-user-posts-scraper/changelog.md

# Actor input Schema

## `profileUrls` (type: `array`):

Public Facebook profile or vanity URLs to scrape posts from (e.g. https://www.facebook.com/pacemorby or https://www.facebook.com/NASA). Accepts m.facebook.com / trailing-slash variants. NOT group URLs, marketplace, ads library, or individual post/reel permalinks — use facebook-posts-scraper or facebook-group-posts-scraper for those.

## `maxPostsPerProfile` (type: `integer`):

Upper bound on posts saved per profile URL. Accepts 1-100; defaults to 10. Quality tests should use 3. Providers return about 3 posts per API page, so higher limits cost more provider credits.

## `resultsLimit` (type: `integer`):

Hard cap on posts saved across all profiles in one run. Use this as your primary spend control; each saved post charges the post-scraped event ($0.005).

## `onlyPostsNewerThan` (type: `string`):

Optional lower date bound. Accepts YYYY-MM-DD or relative windows such as "7 days" or "2 months". Posts with unparseable timestamps are kept.

## `onlyPostsOlderThan` (type: `string`):

Optional upper date bound. Accepts YYYY-MM-DD or relative windows. Posts with unparseable timestamps are kept.

## `provider` (type: `string`):

Upstream data provider chain. Default auto tries ScrapeCreators first, then SociaVault. Pin one provider only for diagnostics.

## Actor input object example

```json
{
  "profileUrls": [
    "https://www.facebook.com/pacemorby",
    "https://www.facebook.com/NASA"
  ],
  "maxPostsPerProfile": 3,
  "resultsLimit": 20,
  "provider": "auto"
}
```

# Actor output Schema

## `posts` (type: `string`):

One row per public Facebook post from the requested profiles.

## `runSummary` (type: `string`):

Terminal outcome, row counts, and spend estimate.

## `output` (type: `string`):

Same summary under the OUTPUT key for agent readback.

# 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 = {
    "profileUrls": [
        "https://www.facebook.com/pacemorby"
    ],
    "maxPostsPerProfile": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/facebook-user-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 = {
    "profileUrls": ["https://www.facebook.com/pacemorby"],
    "maxPostsPerProfile": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/facebook-user-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 '{
  "profileUrls": [
    "https://www.facebook.com/pacemorby"
  ],
  "maxPostsPerProfile": 3
}' |
apify call khadinakbar/facebook-user-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/facebook-user-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/EEIu7lkRrup2vyYoS/builds/p5rBDPkSfDfNT6go5/openapi.json
