Facebook Post Scraper: Reactions and Shares by URL
Pricing
from $0.94 / 1,000 posts
Facebook Post Scraper: Reactions and Shares by URL
Scrape public Facebook posts by URL without a login: paste post, photo, video, reel, group or share links and get reactions by type, comments, shares, exact video plays, text, author, media and link preview. Free rows for dead links, change tracking for re-checks. Pay per post.
Pricing
from $0.94 / 1,000 posts
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Facebook Post Scraper: Reactions and Shares by URL
Facebook post scraper by URL, with no login and no cookies. Paste the links of public Facebook posts, photos, videos, reels or group posts and get one row per post: the text, the time, the author, the reaction count and the breakdown by type (like, love, care, haha, wow, sad, angry), the comment count, the share count, the exact play count of videos and reels, the photos, the video file and the link preview. A dead, private or unreadable link gets a free status row that keeps its link. Each post is charged once per run, however many of your links name it, from $0.94 per 1,000 posts.
What it is for
- Agencies and brand teams: the numbers of your campaign posts, your competitors' posts and the posts your brand is tagged in, in one table.
- Influencer marketing: check creators' posts and reels after publication: reactions, comments, shares and plays.
- Re-checks on a schedule: name a watch list (memory) and every run adds the previous figures and the change since the last run, so you see how each post moved.
- Researchers and newsrooms: the public figures of a list of news, government or campaign posts, with the time they were published.
- Automation users: one row per post, ready for n8n, Make, Zapier, Power BI, Google Sheets or a database.
Quick start
- Paste your links into Post links, one per line: page posts, pfbid links, photos, videos,
/watch/?v=links, reels, public group posts, share links (/share/p/,/share/r/,/share/v/) orfb.watchlinks. - Optional: turn on Include the top comments the post shows, Include video captions (transcript) or Include author follower counts (Read every photo of a post is on already). None of them changes the price.
- Optional, for re-checks: give a memory name (for example
campaign october) and schedule the run. - Click Start. Download the rows as JSON, CSV or Excel, or read them through the API.
What you get
One row per post (type: "post"), the Post event. Fill rates are counted over the 76 distinct posts the platform test runs delivered on 2026-10-14 (57 page posts, 2 photos, 2 posts with a video, 4 videos, 8 reels, 3 group posts, of brands, news, a space agency, a public figure, a small business and public groups).
| Field | What it holds | Filled |
|---|---|---|
postId, postKind, postUrl | Facebook's number of the post, its kind (post, photo, video, video_post, reel, group_post) and its own link | every row |
feedbackId | Facebook's id of the reactions and comments the row's figures come from (base64 of feedback:<number>: the post's number on post rows; on video and reel rows the number Facebook gives the video's story, which can differ from postId), the key comment tools take for a post | every row |
inputUrl, position | the link you gave and its place in your list | every row |
videoId, photoId | the video number (videos and reels) and the photo number (photo links) | where the post has one |
createdAt, createdAtUnix | when the post was published (UTC) | 76 of 76 |
text, title | the post's text, and a video's title | text 74 of 76 (one photo post and one video had none) |
hashtags, mentions, linksInText, events | hashtags, tagged people and pages, the web links written in the text, and the Facebook events the post links | where the post has them |
authorName, authorId, authorUrl, authorType | the page or person who posted | 76, 76 and 73 of 76 (group posts name their author without a link) |
authorPageId, authorIsBusinessPageActive | the author page's id (the one Meta's Ad Library uses) and Facebook's business page flag, from the post's header | 72 of 76 (the four others were group members and a person) |
authorIsVerified, authorFollowers, authorCategory | the verified mark (from the post's header where it shows one, and from the author's page with the option) and, with Include author follower counts, the follower count as Facebook shows it (rounded, for example 28,000,000 for "28M") and the page's category | 6 of 6 posts of the run with the option on (verified mark on 5) |
reactionCount, reactionCountIsExact | all reactions; exact where Facebook gives the number | 76 of 76 |
reactions | like, love, care, haha, wow, sad and angry | 75 of 76 (one post had no reactions) |
commentCount | Facebook's comment count | 76 of 76 |
shareCount, shareCountIsExact | Facebook's share count; on larger reels Facebook shows it rounded ("1.2K") and shareCountIsExact is false | 72 of 72 posts and reels (videos show no share count) |
playCount, viewCount | a video's or reel's play count and view count, exact | 12 of 12 videos and reels |
engagementTotal | reactions plus comments plus shares | every row |
photoCount, photos | the photos with their links, sizes and Facebook's own description of the image (altText); with Read every photo of a post (on by default) every photo of a post with more than five | 47 of 76 posts had photos |
mediaTotal, photosComplete | how many photos and videos the post holds, and whether every one is in the row | where the post has media |
video, videos | a video's or reel's link, duration, thumbnail (thumbnailUrl), the video file link (videoFileUrl, HD where Facebook offers it), the SD file link (videoFileUrlSd) and Facebook's own captions file (captionsUrl, an .srt, where the video has captions); videos lists every video of a post with several | 14 of 14 posts with a video |
music | a reel's audio track (title, audio id, album art) where the reel names one | where shown |
link | the link preview of a post that shares a web page (address, title, description, site) | 10 of 76 posts shared a link |
isShare, sharedPost | whether the post shares another post, and that post's number, link, author and text | where the post shares one |
taggedPlace, taggedProfiles, collaborators | the place the post is tagged at, the people and pages tagged with "with", and the post's collaborators | where shown |
groupId, groupName, groupUrl | the group of a group post | 3 of 3 group posts |
topComments | with Include the top comments the post shows: the comments the post's page shows a logged out visitor (usually up to 10), each with text, author, time, reactions and reply count | 4 of 4 posts of the run with the option on |
transcript, transcriptStatus | with Include video captions: the text of Facebook's own captions of a video or reel (ok, truncated past 200,000 characters, no_captions, not_a_video, failed, or not_read when the run stopped first) | 2 of 2 videos and reels of the run with the option on had captions (one past 200,000 characters, truncated) |
previous, change | with a memory name: the figures of the last run that read the post (and when), and the difference for reactions, comments, shares, plays and views, with the hours between the two reads | from the second run on |
source, scrapedAt | the page the row was read from, and when | every row |
Status rows (type: "status", free) answer every link that does not become a post row, with its position and, where the link is readable, its inputUrl: post_not_available (deleted, private, restricted or never published), login_required (Facebook asked for a login on every address tried, for example a post in a private group), post_unresolved (the page did not show the post the link names), duplicate (another link of the run already delivered this post), outside_date_window, lookup_failed (Facebook did not answer; run it again), link_not_read and not_a_post (values that are not a single post link: one row per kind, listing their positions and reasons), skipped (one row listing the links a stopped run did not read), invalid (the input could not be read; nothing was read and only the run's start fee was billed, plus any posts billed before a platform restart of the run) and change_tracking_unavailable (the memory name could not be used: rows come without previous figures, billed as usual). The summary row (type: "summary", free) closes every run with its counters and what was billed. A run that fails ends with an error row (type: "error", free) saying why.
Links it reads
| Link | Example | Read how |
|---|---|---|
| Page or profile post | facebook.com/NASA/posts/1637283811100322, facebook.com/nike/posts/pfbid04GE... | the post's own page |
| Mobile and slug links | m.facebook.com/NASA/posts/..., facebook.com/NASA/posts/some-title/1637... | the same post page |
| Photo | facebook.com/photo/?fbid=...&set=a...., photo.php?fbid=..., facebook.com/nike/photos/a.../... | the owner's post page of the photo (the photo's owner is read from its embed when the link does not name it) |
| Video, watch | facebook.com/NASA/videos/1408202287429345/, facebook.com/watch/?v=..., video.php?v=... | the video's page: exact plays and views, reactions by type |
| Reel | facebook.com/reel/1082585924135116 | the reel's video page (exact plays, reactions by type), then its reel page for the share count |
| Public group post | facebook.com/groups/dogspotting/posts/..., /permalink/..., ?multi_permalinks=... | the group post page |
| permalink.php, story.php | facebook.com/permalink.php?story_fbid=...&id=... | the owner's post page |
| Share and short links | facebook.com/share/p/..., /share/r/..., /share/v/..., fb.watch/... | the link's first redirect names the post, which is then read as above |
Page, profile and group home links are not posts: they get a free status row (for a page's posts, use our Facebook page posts listing, linked at the end of this page).
How much does it cost to scrape Facebook posts?
Pay per event: you pay for each post delivered, nothing for status rows, duplicates or links Facebook does not show.
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| Post (per 1,000 posts) | $1.32 | $1.20 | $1.09 | $0.94 |
| Actor start (per run) | $0.005 | $0.005 | $0.005 | $0.005 |
Platinum and Diamond plans pay the Gold price. The Store pricing card shows these same prices per 1,000 events: "$0.94 / 1,000" on the Post row means one post costs $0.00094. The Actor start is charged once per run, by the platform, per GB of run memory (a 256 MB run pays one). The options (top comments, captions, author follower counts, every photo of a post, reel share counts, change tracking) cost nothing extra.
Examples at the Gold price:
- One post: $0.005 + $0.00094 = $0.00594.
- 100 posts: $0.005 + 100 x $0.00094 = $0.099.
- 1,000 posts: $0.005 + $0.94 = $0.945.
- A daily re-check of 20 campaign posts for 30 days: 30 x ($0.005 + 20 x $0.00094) = $0.714.
Free, always: status rows (dead, private, walled, unreadable or duplicate links, posts outside your date window), the summary, and the sample post of an empty input (a fresh run started that way pays only the Actor start).
Input
| Field | What it does |
|---|---|
postUrls | the post links (up to 5,000). startUrls with { "url": ... } objects, urls, directUrls and links are read too |
maxPosts | stop after this many posts (empty: every link, within your charge limit and the run's allowance of unpaid work) |
postedAfter, postedBefore | a date window: YYYY-MM-DD, YYYY-MM-DD HH:MM or YYYY-MM-DDTHH:MM (UTC), today, yesterday, "7 days", "2 weeks", "3 months", "12 hours" (back from the run's start); a post outside it gets a free row |
includeTopComments | add the comments the post's page shows (empty: off) |
includeTranscript | add the text of Facebook's own captions of videos and reels (empty: off) |
includeAuthorDetails | add the author's follower count, verified mark and category (empty: off) |
includeAllPhotos | read every photo of a post with more than five (empty: on) |
reelShareCount | read a reel's share count from its reel page (empty: on) |
memoryName, resetMemory | change tracking: previous figures and the change since the last run |
maxConcurrency | how many links are read at once (empty: 4) |
proxyUrls | your own proxies (optional, secret) |
Example:
{"postUrls": ["https://www.facebook.com/NASA/posts/1637283811100322","https://www.facebook.com/reel/1082585924135116","https://www.facebook.com/groups/dogspotting/posts/10159050659364467/"],"includeTopComments": true,"memoryName": "campaign october"}
Change tracking (watch lists)
Give the same memoryName to scheduled runs of the same list. Each row then carries previous (the reactions, comments, shares, plays and views the last run delivered for that post, and when) and change (the difference, and the hours between the two reads). The first run of a name has no previous figures. Every post read is a Post, on every run: the memory only keeps figures and never makes a re-check free or skips it. A memory belongs to this Actor and your account; it keeps up to 20,000 posts (past that the posts checked longest ago are dropped first). Two runs on one memory name at the same time: the second one delivers without previous figures and a free row says so.
Use it through the API
curl -X POST "https://api.apify.com/v2/acts/automation_craft~facebook-post-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-H "Content-Type: application/json" \-d '{"postUrls": ["https://www.facebook.com/NASA/posts/1637283811100322"]}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation_craft/facebook-post-scraper').call({ postUrls: ['https://www.facebook.com/reel/1082585924135116'] });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((x) => x.type === 'post'));
from apify_client import ApifyClientclient = ApifyClient("<YOUR_TOKEN>")run = client.actor("automation_craft/facebook-post-scraper").call(run_input={"postUrls": ["https://www.facebook.com/NASA/posts/1637283811100322"]})posts = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "post"]
What this Actor does NOT do
- No login, no private content. It reads what Facebook shows a logged out visitor. Posts in private groups, friends only posts and posts of restricted pages get a free
login_requiredorpost_not_availablerow. - No page or profile timelines. It reads the posts you link. For a page's posts over time use our Facebook page posts listing (linked below); for keyword search there is no mode here.
- No full comment lists or reactor lists. The top comments option gives what the post's page shows (usually up to 10). For every comment and reply use our Facebook Comments Scraper; the people who reacted are not read.
- No share count on videos. Facebook shows none on video and watch pages; reels get theirs from the reel page.
- No paid partnership flag. Facebook does not show the paid partnership label to a logged out visitor (checked on 3 posts Meta's branded content library lists as paid partnerships, 2026-10-14); the brand a creator tags shows in
taggedProfiles. - No live viewer counts, marketplace flags, product tags on photos or reactions per photo. On the logged out pages read for this Actor, product tags were empty on every photo and no photo carried its own reaction counts.
- No gender or other data Facebook does not display. Author and commenter fields are what the post's page shows a visitor: name, id and profile link.
- No speech to text. Transcripts are Facebook's own captions; a video without captions says
no_captions. - No stored copies of photos or videos. Rows carry Facebook's links to the files, which expire after some days.
- Exact follower counts. Author follower counts are Facebook's rounded figure ("28M").
FAQ
How do I get the number of likes, comments and shares of a Facebook post I do not own?
Paste the post's link into Post links and start the run. The row carries reactionCount with the breakdown by type, commentCount and shareCount, as Facebook shows them to a logged out visitor; no login or access to the page is needed.
Can I scrape Facebook reel and video views?
Yes. A video or reel link gives playCount and viewCount exactly, from the video's own page, and a reel also gets its share count from its reel page.
Does it work with photo links, share links and fb.watch links?
Yes. Photo links, permalink.php and story.php links are read through the owner's post page, and share and fb.watch links through their first redirect, which names the post.
Is scraping Facebook posts without logging in possible?
Yes, for public posts. This Actor never logs in and never sends cookies; posts that need a login get a free status row.
How do I track how a post's engagement changes over time?
Give a memory name and schedule the run. Each row then shows the previous figures, when they were read, and the change since then.
Why does this Actor run with limited permissions?
It runs with the least privilege Apify offers: it reads Facebook and writes only to its own run's storage, plus the memory store it creates itself under your memory name. It cannot see your other Actors, datasets or account data.
More data tools by Automation Craft
- Facebook page posts, no login (our page posts listing)
- Facebook Page ID Finder: Names to Page IDs
- Facebook Marketplace Scraper with Sold Tracker
- Facebook Ads Library Scraper - Ad Library & Spy
- Meta Branded Content Scraper: Paid Partnerships
- Instagram Posts Scraper: Profiles, Reels, No Login
- Threads Scraper: Posts, Search, Tags, Replies
Changelog
See the Changelog tab.