Facebook Posts Scraper
Pricing
from $3.00 / 1,000 posts
Facebook Posts Scraper
Scrape posts from public Facebook Pages and profiles without login, by date window, with a per-URL coverage report. $3 per 1,000 posts.
Pricing
from $3.00 / 1,000 posts
Rating
5.0
(1)
Developer
Daniel G
Maintained by CommunityActor stats
0
Bookmarked
13
Total users
9
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape posts from public Facebook Pages and profiles, plus single post, reel and video URLs, without login. Set a date window and receive a per-URL coverage report describing whether each feed was read completely. Each returned post costs $0.003 ($3 per 1,000); from October 21, 2026, each Page or profile checked also costs $0.003. A $0.00005 start fee applies per run.
What it returns
Each dataset item is one post. Optional fields may be omitted.
| Name | Type | Meaning |
|---|---|---|
facebookUrl | string | Supplied Page, profile, post or video URL. |
inputUrl | string | Original input URL. |
postId | string | Facebook post ID. |
url | string | Post permalink. |
topLevelUrl | string | URL built from author and post IDs. |
time | string | ISO 8601 publication time. |
timestamp | number | Publication time, Unix seconds. |
text | string or null, optional | Post text; videos can have empty or null text. |
user | object | Author's id, name, profileUrl and profilePic; values can be null. |
pageName | string | Name from the URL or resolved author name. |
facebookId | string or null | Resolved Facebook ID. |
likes | number or null | Reaction count. |
comments | number or null | Comment count. |
shares | number or null | Share count. |
topReactionsCount | number or null | Reaction types represented. |
viewsCount | number or null, optional | Video views when exposed. |
media | array, optional | Photos or videos with available thumbnails and media fields. |
sharedPost | object or null, optional | Shared post when exposed. |
link | string, optional | Attached URL. |
isVideo | boolean, optional | Whether the row contains video. |
Example row (shortened text and placeholder details):
{"facebookUrl":"https://www.facebook.com/PAGE","inputUrl":"https://www.facebook.com/PAGE","postId":"POST_ID","pageName":"PAGE","url":"https://www.facebook.com/reel/POST_ID/","time":"2026-10-06T13:22:32.000Z","timestamp":1791292952,"user":{"id":"AUTHOR_ID","name":"Author","profileUrl":"https://www.facebook.com/AUTHOR_ID","profilePic":"https://example.com/profile.jpg"},"likes":62,"comments":1,"shares":3,"topReactionsCount":4,"topLevelUrl":"https://www.facebook.com/AUTHOR_ID/posts/POST_ID","facebookId":"AUTHOR_ID","collaborators":[],"paidPartnership":false,"topComments":[],"text":"Example post text…","media":[{"thumbnail":"https://example.com/thumbnail.jpg","__typename":"Video","url":"https://www.facebook.com/reel/POST_ID/","id":"VIDEO_ID"}],"isVideo":true}
Input
| Field | Default | Meaning |
|---|---|---|
startUrls | Required | Array of objects containing a Facebook url. |
resultsLimit | 20 | Maximum posts per URL; integer from 1–10,000. |
onlyPostsNewerThan | No lower bound | Inclusive publication-time lower bound. |
onlyPostsOlderThan | No upper bound | Exclusive publication-time upper bound. |
captionText | false in the input editor | Compatibility boolean; ignored. |
The half-open window is [onlyPostsNewerThan, onlyPostsOlderThan). Both bounds accept ISO dates, ISO datetimes or relative values such as 7 days, 12 hours, 2 weeks and 1 month, measured back from run initialization. Dates mean midnight UTC; datetimes without a timezone use UTC. Omit either bound; the lower bound must precede the upper bound. The window also filters single posts and videos.
Last seven days of one Page:
{"startUrls":[{"url":"https://www.facebook.com/NASA/"}],"onlyPostsNewerThan":"7 days"}
One UTC day from several Pages:
{"startUrls":[{"url":"https://www.facebook.com/NASA/"},{"url":"https://www.facebook.com/EuropeanSpaceAgency/"}],"onlyPostsNewerThan":"2026-10-01","onlyPostsOlderThan":"2026-10-02"}
Supported URLs
Example paths use https://www.facebook.com; replace placeholder IDs/codes.
| URL form | Example | Notes |
|---|---|---|
| Page or profile | /NASA/, /profile.php?id=123, /people/Name/123 | Reads the timeline. Numeric paths work. |
| Post | /NASA/posts/123, /NASA/posts/pfbidCODE, /permalink.php?story_fbid=123&id=456, /photo/?fbid=123 | Returns only the requested post; a reel's /posts/ URL also works. |
| Reel | /reel/123 | Likes, comments and shares; viewsCount is null. |
| Watch | /watch/?v=123 | Likes, comments and viewsCount; shares is null. /watch?v=123 also works. |
| Video | /NASA/videos/123 | Same counts as watch; title-slug URLs such as /NASA/videos/title/123 work. |
| Group post | /groups/GROUP/posts/123, /groups/GROUP/permalink/123 | Public groups only. |
| Share | /share/r/CODE, /share/v/CODE, /share/p/CODE | Follows redirects to the final URL. |
Missing count fields are null, never estimated. Absent single-video media fields are also null. An absent post or video returns no row or post charge; its report uses stopReason: "not_found" and status: "unavailable".
How coverage is checked
Each accessible Page or profile feed is read at least twice using different IP addresses, with a third read when the first two differ. In-window results are merged by post ID. The first read stops after six consecutive posts older than the window start; later reads stop after three. Pinned posts and duplicates do not advance that streak.
complete and empty are reported only after two reads agree, or after a third read when the first two differ. All reads are merged by post ID, so a post found by any read is returned.
| Status | Meaning |
|---|---|
complete | Posts returned; verification finished and traversal reached the date boundary or feed end. |
empty | Same traversal conditions, with no posts in the window. |
partial | Coverage limited by the post limit, charge cap, free plan limit or failed verification; possibly no rows. |
unavailable | Target missing or hidden from logged-out visitors. |
failed | Coverage could not be established and no posts were returned. |
Single-post URLs use one read. An available post outside the window returns no row and reports empty.
stopReason identifies the boundary (passed_window_start, end_of_feed), limit (max_posts, charge_cap, free_plan_limit), failure (timeout, rate_limited, error) or visibility issue (not_found, private, login_wall, age_gated, restricted, not_visible_or_missing).
The default key-value store's OUTPUT record contains the normalized window and reports in targets, with a COVERAGE log line per URL.
| Report field | Meaning |
|---|---|
walks | Number of reads attempted. |
walksDisagreed | Whether the first two reads differed. |
postsAddedByVerification | Additional posts found before applying the results limit. |
outOfOrderPosts | Older posts followed by an in-window or newer post during the first read. |
boundaryPost | First post in the first read's final older streak. |
profileCharged | Whether the profile event was charged. |
Reports also include postsEmitted, newestPostAt, oldestPostAt, skipped, feedPagesRead, requestsFailed, retries and errors. Compatibility fields firstPageFetches and firstPageDisagreed mirror walks and walksDisagreed.
Read /records/OUTPUT in the default store or through /v2/actor-runs/{runId}/key-value-store/records/OUTPUT.
Pricing
post: $0.003 per returned post ($3 per 1,000).profile: $0.003 per Page or profile checked, starting October 21, 2026, forcomplete,emptyorpartialresults. Unavailable and failed URLs are free; single posts and videos pay only thepostevent.apify-actor-start: $0.00005 per run. There is no minimum post count.
From October 21, one profile checked for one day with four posts costs $0.015 in events, plus the start fee. Reaching your charge limit stops emission and crawling with charge_cap; coverage is partial.
Limits
Runs by users on Apify's free plan are limited to 3 URLs and 20 results per run.
Only public content visible without login is available. Hidden or restricted Pages and age-gated posts cannot be returned. Comments and group feeds are not collected; topComments is always empty. Reels that appear on a timeline are returned like other posts.
The Actor keeps a small cache of Page/profile IDs in the runner's account (facebook-posts-scraper-cache), and deleting it only makes the next run slower.
A reel page can report a creation time a few minutes different from the feed's. Refresh counts by matching postId. captionText is accepted but does nothing.
Use via API
Send JSON to the synchronous dataset-items endpoint:
curl -X POST 'https://api.apify.com/v2/acts/LordFloofington~facebook-posts-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN' \-H 'Content-Type: application/json' \--data '{"startUrls":[{"url":"https://www.facebook.com/NASA/"}],"onlyPostsNewerThan":"7 days","resultsLimit":20}'
Compliance
Users are responsible for complying with Facebook's terms and applicable law when using this Actor.
