Alfalfa

Facebook Comments API: every comment and reply of a post as JSON

The Graph API exposes comments only on posts of pages you manage. This endpoint returns the comments and replies of any public post, as a signed-out visitor sees them, with the thread structure preserved. One call, JSON back, no Facebook account.

Updated September 2026. Endpoint hosted on Apify; an Apify account and API token are the only requirements.

What the Graph API gives you today

The /{post-id}/comments edge works for your own page's posts with a Page token carrying pages_read_user_content. For other pages' posts it needs the Page Public Content Access feature, granted after app review to few apps. Replies, reaction counts and commenter profiles are further permissions. For any post you do not own, the Graph API is closed in practice.

The endpoint

One HTTP call. The synchronous form waits for the run and returns the records in the same response (fine for up to a few minutes of work); the asynchronous form returns a run id at once and you read the dataset when it has finished, with webhooks if you want a callback.

Synchronous

curl -X POST "https://api.apify.com/v2/acts/alfalfa~facebook-comments-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN&format=json" \
  -H 'Content-Type: application/json' \
  -d '{"startUrls": [{"url": "https://www.facebook.com/humansofnewyork/posts/pfbid0BbKbkisExKGSKuhee9a7i86RwRuMKFC8NSkKStB7CsM3uXJuAAfZLrkcJMXxhH4Yl"}], "resultsLimit": 200, "includeNestedComments": true}'

Asynchronous

# start the run (returns immediately with the run id and dataset id)
curl -X POST "https://api.apify.com/v2/acts/alfalfa~facebook-comments-scraper/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' -d '{"startUrls": [{"url": "https://www.facebook.com/humansofnewyork/posts/pfbid0BbKbkisExKGSKuhee9a7i86RwRuMKFC8NSkKStB7CsM3uXJuAAfZLrkcJMXxhH4Yl"}], "resultsLimit": 200, "includeNestedComments": true}'
# read the results when the run has finished (JSON, CSV or XLSX; paginate with offset and limit)
curl "https://api.apify.com/v2/datasets/<defaultDatasetId>/items?token=$APIFY_TOKEN&format=json&offset=0&limit=1000"

Python

from apify_client import ApifyClient  # pip install apify-client

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("alfalfa/facebook-comments-scraper").call(run_input={
  "startUrls": [
    {
      "url": "https://www.facebook.com/humansofnewyork/posts/pfbid0BbKbkisExKGSKuhee9a7i86RwRuMKFC8NSkKStB7CsM3uXJuAAfZLrkcJMXxhH4Yl"
    }
  ],
  "resultsLimit": 200,
  "includeNestedComments": true
})
items = list(client.dataset(run.default_dataset_id).iterate_items())
print(len(items), items[0])

JavaScript

import { ApifyClient } from 'apify-client'; // npm install apify-client

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('alfalfa/facebook-comments-scraper').call({"startUrls": [{"url": "https://www.facebook.com/humansofnewyork/posts/pfbid0BbKbkisExKGSKuhee9a7i86RwRuMKFC8NSkKStB7CsM3uXJuAAfZLrkcJMXxhH4Yl"}], "resultsLimit": 200, "includeNestedComments": true});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);

Request fields

FieldTypeMeaning
startUrlsarrayPost URLs in any form Facebook uses: /posts/, /photo/?fbid=, /videos/, /reel/, permalink.php.
resultsLimitintegerMaximum top-level comments per post; replies come on top of it.
includeNestedCommentsbooleanReturn replies and replies to replies as their own records with parent links.
viewOptionstringRANKED_UNFILTERED (all), RECENT_ACTIVITY (newest), RANKED_THREADED (most relevant).
onlyCommentsNewerThanstringDate or relative period; with the newest view the run stops early.

Response fields

One JSON object per record. Field names are the ones the official Apify Actor uses, so code written for it works unchanged.

FieldMeaning
commentId, commentUrl, id, feedbackIdIDs and the direct link.
date, text, attachmentsWhen, what, and any photo, GIF or video attached.
profileName, profileId, profileUrl, profilePicture, authorWho wrote it.
likesCount, commentsCountReactions on the comment and the number of replies.
threadingDepth, replyToCommentId, parentComment, parentReply0 for a comment, 1 and 2 for replies, with the parents, so the thread can be rebuilt.
facebookUrl, facebookId, postTitle, postDescriptionThe post the comment belongs to.

Limits, pagination, scheduling

Pricing

$0.50 per 1,000 comments or replies, no start fee, no surcharge for date filters. Platform usage and residential proxies are included; you pay only for records written to the dataset. The Apify free plan includes $5 of usage a month, enough to try it properly.

Questions people ask

Can I read comments on another page's post through the Graph API?

Not without the Page Public Content Access feature, which requires app review and is rarely granted. This endpoint reads the public post instead and needs no Facebook account.

Why is the count lower than the number shown on the post?

The number on the post includes replies, spam-filtered comments and comments by deactivated accounts, which no visitor can read. The response contains what a signed-out visitor can see.

Do I get the thread structure?

Yes. Replies are separate records with threadingDepth, replyToCommentId, parentComment and parentReply, so a conversation tree can be rebuilt without guessing.

What does it cost?

$0.50 per 1,000 comments or replies, platform usage included, no start fee. The official Apify comments scraper charges $2.50 plus $1 per run and a surcharge per comment when a date filter is on.

Open the Actor on Apify All five endpoints