# Facebook Post Scraper by ID: Text, Comments and Reactions (`whoareyouanas/facebook-single-post-scraper`) Actor

Scrape Facebook posts by numeric ID. Extract text, authors, timestamps, reactions, comment counts and media URLs. Batch lookup for public group posts with JSON and CSV exports, API access and optional loaded comments.

- **URL**: https://apify.com/whoareyouanas/facebook-single-post-scraper.md
- **Developed by:** [Anas Nadeem](https://apify.com/whoareyouanas) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 http post results

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/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 Post Scraper by ID: Text, Comments and Reactions

**Facebook Post Scraper by ID** extracts structured Facebook post data from a list of numeric post IDs. Get post text, author information, publication time, reaction counts, comment and share counts, image URLs, video URLs, and optional loaded comments in structured JSON. Export results from the Apify dataset for analysis or automation.

**Best for:** looking up specific Facebook posts you already know, refreshing engagement metrics, and enriching an existing list of post IDs. Public Facebook group posts are the live-tested scope, including photo, video, and long-text posts.

| At a glance | Details |
| --- | --- |
| Actor identifier | `whoareyouanas/facebook-single-post-scraper` |
| Required input | `postIds`: an array of numeric strings |
| Output | One dataset row per unique processed post ID, including a status |
| Extracted data | Text, author, timestamp, reactions, counts, media URLs, optional loaded comments |
| Access | Public posts where Facebook exposes the content; optional user-supplied cookies and proxy |
| Interfaces | Apify Console, REST API, JavaScript client, Python HTTP requests |
| Result formats | JSON dataset; CSV and other exports through Apify |

### How to scrape a Facebook post

1. Enter one or more numeric post IDs in **Post IDs**.
2. Leave **Include media URLs** enabled if you need photo or video links. Enable **Include loaded comments** if needed.
3. Click **Start** and open the run's dataset.
4. Check each row's `status`, then export the results or retrieve them through the API.

Start with this input:

```json
{
  "postIds": ["4376904415959558"],
  "includeMedia": true,
  "includeComments": false
}
```

#### Where do I find the Facebook post ID?

For this post URL:

```text
https://www.facebook.com/groups/2447813518868667/permalink/4376904415959558/
```

The **post ID is `4376904415959558`**. The earlier number, `2447813518868667`, is the group ID. A URL ending in `/posts/4376904415959558/` refers to the same post.

Pass the post ID as a quoted string. The Actor accepts numeric strings containing 5 to 40 digits; it does not accept full URLs or opaque IDs beginning with `pfbid`. Quoting IDs preserves their precision in JavaScript and JSON workflows.

#### Extract several posts in one run

```json
{
  "postIds": [
    "4376904415959558",
    "4378894958999683",
    "4426680754221103"
  ],
  "includeMedia": true,
  "includeComments": true,
  "maxComments": 10,
  "maxConcurrency": 5
}
```

Duplicate IDs are extracted once. Results arrive in completion order; use `inputPostId` to match them to your input.

### Pricing

Pay for successfully extracted posts. Standard Apify compute, storage and the built-in residential proxy are included in the event prices below.

| Charge | Price | When it applies |
| --- | --- | --- |
| HTTP post result | $0.005 per post ($5 per 1,000) | A complete post extracted over HTTP |
| Browser post result | $0.04 per post ($40 per 1,000) | A complete post extracted through browser fallback |
| Actor start | $0.00005 per GB of allocated memory, minimum one GB | Charged when a run starts; $0.00005 at the default 1 GB |

Each successful post receives **one result charge**. The browser price replaces the HTTP price; the two are never added together. Partial, restricted, unavailable, unresolved and error rows have no result charge. The start fee still applies to a run with no successful posts. Duplicate IDs within a run produce at most one result charge.

Examples for one run at the default 1 GB memory:

| Successful results | Total event charge |
| --- | --- |
| 100 HTTP posts | $0.50005 |
| 1,000 HTTP posts | $5.00005 |
| 900 HTTP posts and 100 browser posts | $8.50005 |

Set `browserFallback` to `false` for HTTP-only pricing. Otherwise, a post that needs a browser can use the higher rate automatically. Set a maximum run cost in Apify to control spending; the Actor stops scheduling new work when its result charging limit is reached. A spending-limited run can return fewer rows than the input contains.

There is no Actor subscription and no additional result fee for media URLs or loaded comments. If you supply your own proxy, any charges from that external provider are separate. Apify account subscription fees and applicable taxes are separate from these Actor event prices. The [Pricing tab](https://apify.com/whoareyouanas/facebook-single-post-scraper/pricing) is the source of truth for active rates.

### What Facebook post data does it extract?

| Field | Meaning |
| --- | --- |
| `post.postId`, `post.postUrl` | Verified post identity and resolved URL |
| `post.text` | Post message, including Unicode and rendered rich-text content |
| `post.authorName`, `post.authorId`, `post.authorProfileUrl` | Author identity and profile link, when available |
| `post.timestamp` | Publication time in ISO 8601 UTC |
| `post.groupId`, `post.groupName`, `post.groupUrl`, `post.groupPrivacy` | Group context when exposed |
| `post.source`, `post.postType` | Source classification and content type |
| `post.totalReactions`, `post.reactions` | Total reactions and available reaction-type breakdown |
| `post.commentsCount`, `post.sharesCount` | Comment and share counts |
| `post.images`, `post.videos` | Available media URLs; files are not downloaded |
| `post.topComments` | Optional comments already loaded in the response |
| `post.commentsStatus` | `not_requested` or `loaded_only` |
| `post.textTruncated` | Whether the returned content is known to be truncated |

Missing scalar values are `null`. A count of `0` means Facebook explicitly supplied zero. An empty comment list does not establish that a post has no comments. Media URLs and engagement counts can change over time.

#### Output example

This shortened field selection illustrates the dataset structure. The Actor returns the full available text and additional fields described above; the sample text below is abbreviated for readability.

```json
{
  "inputPostId": "4376904415959558",
  "status": "success",
  "post": {
    "postId": "4376904415959558",
    "postUrl": "https://www.facebook.com/groups/2447813518868667/posts/4376904415959558/",
    "authorName": "MKR Senior Living Advisors",
    "authorId": "100063722123704",
    "text": "Let's welcome our new members! [sample shortened]",
    "timestamp": "2026-05-24T07:00:57.000Z",
    "groupName": "Senior Placement Network",
    "groupPrivacy": "public",
    "source": "facebook_group",
    "postType": "photo",
    "totalReactions": 7,
    "commentsCount": 1,
    "sharesCount": 0,
    "textTruncated": false
  },
  "extractionMethod": "http",
  "missingFields": [],
  "error": null
}
```

The counters above are from a recorded validation snapshot, not guaranteed current values. Complete rows also include `attempts`, `durationMs`, and `scrapeDate`.

### Use cases

- **Post monitoring:** refresh reactions, comments, and shares for a known set of posts.
- **Dataset enrichment:** add text, publication dates, author details, and media links to existing post IDs.
- **Community research:** analyze accessible public-group discussions with traceable post URLs.
- **Content analysis:** supply post text to classification, summarization, or reporting workflows.
- **Workflow automation:** call the Actor from an HTTP-capable tool such as n8n or Make and process its dataset rows.

Need to discover posts from an entire group or Page first? Use [Facebook Group & Page Scraper](https://apify.com/whoareyouanas/facebook-group-scraper), then send the numeric post IDs here for individual lookups.

### Facebook post scraping API

Use your **Apify API token** to call the Actor. No Facebook developer-app token is required by this Actor. Facebook content visibility can still require cookies or a suitable proxy.

#### cURL: run and retrieve JSON results

Set `APIFY_TOKEN` in your environment, then send:

```bash
curl --fail-with-body --request POST \
  'https://api.apify.com/v2/acts/whoareyouanas~facebook-single-post-scraper/run-sync-get-dataset-items?format=json' \
  --header "Authorization: Bearer ${APIFY_TOKEN}" \
  --header 'Content-Type: application/json' \
  --data '{"postIds":["4376904415959558"],"includeMedia":true}'
```

For larger batches, start an asynchronous run through `POST /v2/acts/whoareyouanas~facebook-single-post-scraper/runs`, wait for completion, and read `/v2/datasets/{defaultDatasetId}/items`. Check row statuses even when the run succeeds. See the [Apify API documentation](https://docs.apify.com/api/v2/getting-started).

#### JavaScript

Install `apify-client` in your application, then:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('whoareyouanas/facebook-single-post-scraper').call({
  postIds: ['4376904415959558'],
  includeMedia: true,
  includeComments: false,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) {
  console.log(row.inputPostId, row.status, row.post?.text);
}
```

Dataset listing is paginated; paginate when retrieving large batches.

#### Python

With `requests` installed and `APIFY_TOKEN` set:

```python
import os
import requests

response = requests.post(
    "https://api.apify.com/v2/acts/"
    "whoareyouanas~facebook-single-post-scraper/run-sync-get-dataset-items",
    headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"},
    json={"postIds": ["4376904415959558"], "includeMedia": True},
    timeout=180,
)
response.raise_for_status()
for row in response.json():
    print(row["inputPostId"], row["status"], (row.get("post") or {}).get("text"))
```

### Input settings

| Input | Default | Purpose |
| --- | --- | --- |
| `postIds` | Required | Array of numeric post ID strings |
| `includeMedia` | `true` | Return photo/video URLs without downloading media |
| `includeComments` | `false` | Return comments already present in the response |
| `maxComments` | `10` | Loaded-comment limit per post, 0 to 100 |
| `maxConcurrency` | `5` | Concurrent post lookups, 1 to 30 |
| `browserConcurrency` | `2` | Maximum fallback browser tabs, 1 to 10 |
| `httpTimeoutSecs` | `12` | Timeout per HTTP attempt, 1 to 120 seconds |
| `browserTimeoutSecs` | `30` | Timeout per fallback page, 1 to 120 seconds |
| `maxRetries` | `1` | Extra attempts for transient failures or restricted native proxy exits, 0 to 3 |
| `browserFallback` | `true` | Use a browser when HTTP data is incomplete |
| `proxyConfiguration` | Residential, India | Built-in Apify Proxy settings for cloud runs |
| `proxyUrl` | Unset | HTTP(S) proxy URL, optionally containing credentials |
| `cookies` | `[]` | User-supplied Facebook cookies in browser-extension format |

Start with the defaults. Reduce concurrency when requests are throttled. The configured proxy is used by both HTTP and browser requests; use sticky-session credentials if your proxy provider rotates IPs. Cookie-authenticated/private posts are not part of the public-post validation suite, and cookies do not grant access your account does not have.

### Cloud proxy setup

Cloud runs use Apify Residential Proxy in India (`IN`) by default with credentials provided by the runtime. This region was selected from live browser validation; you can change it through `proxyConfiguration.apifyProxyCountry`. Input can remain a list of post IDs; no proxy password needs to be copied. The built-in residential proxy is included in the Actor event prices. To disable the default, set `"proxyConfiguration": {"useApifyProxy": false}`. A supplied `proxyUrl` overrides the implicit cloud default; do not combine it with explicitly enabled `proxyConfiguration`.

Direct cloud and datacenter requests received Facebook login restrictions in validation. Local runs use a direct connection unless a proxy is supplied. Public posts can still become unavailable or restricted; inspect every row's `status`.

### Result statuses and troubleshooting

| Status | Meaning and next step |
| --- | --- |
| `success` | Matching story with author, timestamp, and content; inspect optional fields for availability |
| `partial` | Some post data is available; check `missingFields` before using it as complete text |
| `access_restricted` | Facebook returned a login/checkpoint, throttling, or access-denial response; review access and proxy settings |
| `unavailable` | Facebook reports unavailable content; confirm the ID and whether the post is accessible |
| `unresolved` | No matching story was found; confirm that you supplied a numeric post ID |
| `error` | Request or browser failure; review the error class and retry settings |

A run fails if it produces no complete posts, while retaining partial/failure rows. A successful run can contain failed rows alongside successful ones. `unavailable` does not prove deletion: Facebook can return the same response for inaccessible content.

### For AI agents and automated workflows

| Tool-selection question | Answer |
| --- | --- |
| When does this Actor fit? | The task provides numeric Facebook post IDs and needs structured details or updated engagement counts |
| What must the caller supply? | `postIds` as an array of strings; do not substitute group IDs or rounded numbers |
| Where are results? | The default dataset; the output schema exposes its URL and the `SUMMARY` record |
| How are results matched? | By `inputPostId`, never array position |
| How is completeness checked? | Require row `status: "success"`; inspect optional fields separately |
| How are missing counts handled? | Preserve `null`; do not convert missing data into zero |
| Does it discover group posts? | No; use the linked Group & Page Scraper for discovery |
| Does it extract every comment? | No; `includeComments` returns loaded comments only |
| Does it accept post URLs or `pfbid` IDs? | No; this version requires numeric post ID strings |

This Actor supplies data for downstream analysis. It does not perform sentiment analysis, generate summaries, or send messages on Facebook.

### Performance and validation

The Actor first requests the individual post over HTTP and starts a browser only when needed. It avoids crawling an entire group feed and does not download media files.

In one local comparison on the same public post, with media URL output enabled and comments disabled, this Actor took **1.40 seconds** versus **10.57 seconds** for our group actor's individual-post path. Both returned the same full 1,949-character text and author. This single measurement excludes SDK initialization and is not a guarantee for cloud runs, larger batches, or different network conditions.

The extraction implementation passed regression tests and real checks covering the supplied public-group example, another photo post, a long rich-text post, and a video post. Validation compared full text with rendered pages, checked visible authors/reactions, exercised both HTTP and browser extraction, and tested unavailable-post handling and dataset output.

### Frequently asked questions

#### Can I get Facebook post details without the Facebook Graph API?

Yes. This Actor reads data Facebook exposes on its post pages. It does not require a Facebook developer-app token. The Apify API requires your Apify token, and Facebook visibility restrictions still apply.

#### How much does Facebook post scraping cost?

HTTP results cost $5 per 1,000 successful posts. Browser results cost $40 per 1,000 successful posts instead of the HTTP rate. At the default 1 GB memory, each run also has a $0.00005 start fee. Failed and partial results have no result fee. See the pricing section for mixed-run examples.

#### Does it extract Facebook comments and reactions?

It extracts available reaction totals, reaction-type breakdowns, comment counts, and share counts. Enable `includeComments` for comment text already loaded in the response. It does not paginate all comments or return a list of everyone who reacted.

#### Can I export Facebook posts to CSV?

Yes. Results are stored in an Apify dataset, which supports CSV export. Use JSON when you need nested media arrays, reaction breakdowns, or comment objects. See [dataset export documentation](https://docs.apify.com/storage/dataset).

#### Can I scrape private groups, Pages, or personal-profile posts?

The current live-tested scope is accessible public-group posts addressed by numeric IDs. The parser includes Page/profile source classifications and accepts optional cookies, but authenticated/private-group, Page, and personal-profile coverage has not been comprehensively live-validated. Test your intended input before relying on those surfaces.

#### Are photo and video files downloaded?

No. The Actor returns available media URLs. Their availability and expiry are controlled by Facebook.

#### How do I report a problem?

Use the Actor's **Issues** tab. Include the run ID, affected post ID, expected behavior, and result status. Keep cookies, proxy credentials, and API tokens out of issue reports.

# Actor input Schema

## `postIds` (type: `array`):

Required: numeric Facebook post IDs as quoted strings, for example \["4376904415959558"]. For a /groups/GROUP\_ID/permalink/POST\_ID/ URL, use POST\_ID. URLs, group IDs, and pfbid identifiers are not accepted. Duplicates produce one row.

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

Return image and video URLs without downloading the files.

## `includeComments` (type: `boolean`):

Return comments present in the post response, up to maxComments. Does not paginate or promise all comments.

## `maxComments` (type: `integer`):

Limit per post, applied after deduplication.

## `maxConcurrency` (type: `integer`):

Maximum posts in flight. Lower this when Facebook throttles requests.

## `browserConcurrency` (type: `integer`):

Maximum fallback tabs in the shared browser.

## `httpTimeoutSecs` (type: `integer`):

Maximum time per HTTP attempt.

## `browserTimeoutSecs` (type: `integer`):

Maximum time per fallback page after browser startup and queue wait.

## `maxRetries` (type: `integer`):

Retries for transient network errors, throttling, and server errors.

## `browserFallback` (type: `boolean`):

Use a browser when HTTP does not expose complete data. Successful browser results cost $0.04 instead of $0.005 for HTTP results. Disable for HTTP-only pricing.

## `proxyUrl` (type: `string`):

Optional HTTP(S) proxy URL used for both HTTP and browser requests. Use sticky session credentials where supported.

## `cookies` (type: `array`):

Optional cookies supplied by you for posts accessible to your account. Browser-extension cookie format is supported.

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

Residential Apify Proxy is enabled by default for cloud runs, using runtime credentials. Built-in proxy usage is included in Actor event pricing. Datacenter IPs may receive Facebook login restrictions. Disable explicitly for direct requests. The tested default country is India (IN); you can select another region.

## Actor input object example

```json
{
  "postIds": [
    "4376904415959558"
  ],
  "includeMedia": true,
  "includeComments": false,
  "maxComments": 10,
  "maxConcurrency": 5,
  "browserConcurrency": 2,
  "httpTimeoutSecs": 12,
  "browserTimeoutSecs": 30,
  "maxRetries": 1,
  "browserFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IN"
  }
}
```

# Actor output Schema

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

JSON dataset containing inputPostId, status, post details, extraction method, attempts, duration, missing fields and error. Rows are in completion order.

## `summary` (type: `string`):

Total processed posts, elapsed milliseconds, and counts by result status.

# 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 = {
    "postIds": [
        "4376904415959558"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("whoareyouanas/facebook-single-post-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 = { "postIds": ["4376904415959558"] }

# Run the Actor and wait for it to finish
run = client.actor("whoareyouanas/facebook-single-post-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 '{
  "postIds": [
    "4376904415959558"
  ]
}' |
apify call whoareyouanas/facebook-single-post-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,whoareyouanas/facebook-single-post-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/cggVYvBfjNB8MtVS1/builds/u6kekYMOSf6Pcalgt/openapi.json
