Facebook Reels Scraper — Views, Reactions & MP4 URLs
Pricing
$2.00 / 1,000 per reel returneds
Facebook Reels Scraper — Views, Reactions & MP4 URLs
Scrape every Reel a public Facebook Page posts: permalink, MP4 video URL, thumbnail, caption, view count, exact reactions, comments, shares, duration, posted-at and author Page. No login, no cookies. Measured on 624 live reels: 100% views/reactions/comments/shares, 98% captions.
Pricing
$2.00 / 1,000 per reel returneds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
6
Total users
3
Monthly active users
16 days ago
Last modified
Categories
Share
Pull every Reel a public Facebook Page has published, as clean rows. One row per reel: permalink, video_url_hd, video_url_sd, thumbnail_url, caption, posted_at, duration_seconds, view_count_approx, reaction_count, comment_count, share_count_approx, audio_track_title and the author Page (page_name, page_id, page_url, page_is_verified). No login, no cookies, no session token, no CAPTCHA solving.
{"pages": ["redbull", "gopro"],"maxReelsPerPage": 20,"proxyConfiguration": { "useApifyProxy": true }}
Click Try for free and press Start — that block is literally the input this Actor ships with. It returned 40 reels, 0 duplicates, 100% fill on views, reactions, comments, shares, thumbnails and MP4 URLs, and cost $0.08.
Calling it from the API, an MCP client or an AI agent with an empty input is safe too: with no Pages supplied the Actor runs that same two-Page sample (20 reels each) and says so in the run status, instead of failing.
Read this before you buy rows
Six things that would otherwise turn into a refund request.
- View counts are ROUNDED. Reactions and comments are EXACT. This is the single most
important thing on this page. Facebook itself only publishes a bucketed play count on
the reels surface — the literal string it renders is
"3.2M","807K","9.8K". On a 360-reel sample, 93.9% of view counts came back bucketed (they carry a K/M/B suffix and are rounded to two significant figures); only the 6.1% under 1,000 are exact. You get bothview_count_text("3.2M"— what Facebook literally said) andview_count_approx(3200000— that string expanded to a number). Do not presentview_count_approxas a precise figure.reaction_countandcomment_count, by contrast, are exact integers on 100% of rows.share_countsits in between: 85.6% of rows carried an exact integer, 14.4% were bucketed. - There is no keyword mode and no hashtag mode. This Actor reads a Page's public reels
tab. Facebook puts hashtag pages, keyword search and Watch behind a login — verified
2026-08-15, all four surfaces (
/hashtag/…,/search/videos/,/watch/search/,/reel/?q=) redirect a logged-out client to a login form. Anything that claims to search reels by keyword without a login is doing something this Actor deliberately does not do. You must supply Pages. - Some Pages have no public reels tab, and that is not a bug. Facebook answers
"This content isn't available right now"for those — measured identically on datacenter and on residential IPs, so it is a content state, not a block. Of 20 varied brand Pages tested, 2 answered this way (tiffanyandco, Corona) and 2 more served a reels tab with an empty collection (NASA, thedodo). Those Pages are logged, skipped, and never billed. video_url_hdandvideo_url_sdare signed, expiring CDN links. They are the real MP4s and they play, but Facebook signs them with an expiry (hours, not days) and ties them to the fetching context. Download what you need promptly; do not store them as permanent links.permalinkis the stable one.- No follower count, no email, no contact details. This Actor returns reels, not Page
profiles. If you need Page-level fields (likes, category, phone, email, website, bio),
run our Facebook Page Scraper and join on
page_id. - No comments text, no commenter list.
comment_countis a number. The comments themselves are a different record and are not in this dataset.
What you get
| Field | What it is |
|---|---|
reel_id | Facebook's numeric reel/video id. Stable, and the de-duplication key. |
permalink | https://www.facebook.com/reel/<id> — the durable public link. |
page_slug | The handle you supplied. |
page_name | The Page's display name, as Facebook prints it. |
page_id | Numeric Page id — join key to our Facebook Page Scraper. |
page_url | Canonical Page URL. |
page_is_verified | Blue-check state of the author Page. |
caption | The reel's caption text, with line breaks and emoji preserved. |
posted_at | ISO 8601 UTC publish timestamp, to the second. |
duration_seconds | Playable length, fractional. |
view_count_text | What Facebook literally rendered — "3.2M", "9.8K", "415". |
view_count_approx | That string expanded to a number. Rounded — see limit #1. |
reaction_count | Exact total reactions (all types combined). |
comment_count | Exact comment count. |
share_count_text | Facebook's share string — exact below ~1,000, bucketed above. |
share_count_approx | That string as a number. |
thumbnail_url | Poster frame, full resolution. |
video_url_hd / video_url_sd | Signed MP4 URLs. Expiring — see limit #4. |
video_width / video_height | Source pixel dimensions. |
audio_track_title | e.g. "Nike · Original audio". Sparse — see below. |
is_original_audio | Whether the audio is the creator's own. |
is_ai_generated | Facebook's own AI-content detection flag. |
is_reshare | Whether the reel is a reshare of someone else's. |
post_id | The underlying post id (differs from reel_id). |
video_permalink_url | Facebook's /videos/ form of the same asset. |
scraped_at | When this row was captured. |
Field fill — measured on 360 live reels
360 unique reels across 12 public brand Pages (Cristiano, Red Bull, National Geographic, BuzzFeed, Sephora, GoPro, Starbucks, Tasty, LADbible, ESPN, LEGO, Airbnb), 30 reels per Page, pulled through Apify datacenter proxies on 2026-08-15. Counted, not estimated.
| Field | Fill |
|---|---|
reel_id | 100.0% |
permalink | 100.0% |
page_slug · page_name · page_id · page_url · page_is_verified | 100.0% |
posted_at | 100.0% |
duration_seconds | 100.0% |
view_count_text · view_count_approx | 100.0% |
reaction_count | 100.0% |
comment_count | 100.0% |
share_count_text · share_count_approx | 100.0% |
thumbnail_url | 100.0% |
video_url_hd · video_url_sd | 100.0% |
video_width · video_height | 100.0% |
is_original_audio · is_ai_generated · is_reshare | 100.0% |
post_id · video_permalink_url | 100.0% |
caption | 94.2% |
audio_track_title | 43.6% |
The sparse ones, plainly:
audio_track_title— 43.6%. Facebook only names the audio when the reel is attached to an identified track or the creator's own original audio is registered. On the other 56.4% Facebook publishes no track name at all, and the field isnull.caption— 94.2%. 5.8% of reels are published with no caption text.video_url_hd— 100% here, 98.9% on a wider 624-reel sample. A handful of reels are only distributed at SD;video_url_sdwas present on every row in both samples.is_ai_generatedandis_resharewerefalseon all 360 rows in this sample. The fields are populated (not null), the flags simply did not fire on these Pages. Treat them as a signal you can filter on, not as a distribution you can trust from this sample.
Value ranges in the same sample, so you know what the columns look like: views 316 → 71,000,000 (median 166,000); reactions 0 → 4,523,560 (median 1,001); comments 0 → 135,670 (median 47); shares 0 → 126,000 (median 56); duration 2.5s → 13,310s (median 36.2s — yes, Facebook files some multi-hour videos under the reels tab). Publish dates in the sample ran from 2018-12-14 to 2026-08-15.
How deep it goes
Facebook serves the reels tab in batches of 10, newest first, and this Actor follows the same pagination the browser does — contiguously, with no gaps.
- Sephora,
maxReelsPerPage: 100→ 100 reels in 10 contiguous batches, 0 duplicates, 100% engagement fill, covering 2026-06-08 → 2026-08-14. - 12 Pages × 30 reels → 360 rows, 0 duplicates, 36 contiguous batches.
- Across every measurement run on this page, in-run duplicate rate on a single Page was
0.0%. Duplicates only appear if you list the same Page twice under different aliases
(e.g.
goproandGoPro) — those are de-duplicated onreel_idbefore billing, so you never pay twice.
Depth is bounded by what the Page has published, not by the Actor. Set
maxReelsPerPage to whatever you need; the log tells you when a Page ran out of reels
versus when it hit your cap.
Reliability — measured through Apify proxies, not from a laptop
A residential home IP tells you nothing about how a scraper behaves from a datacenter, so every number here was measured through Apify Proxy.
| Rung | Calls | Usable | Notes |
|---|---|---|---|
| Apify DATACENTER, one pinned session per Page | 20 Page fetches + 50 pagination calls | 68 / 70 = 97.1% | The 2 misses were Pages with no public reels tab, not blocks |
| Apify RESIDENTIAL (spot check) | 9 | 9 / 9 HTTP 200 | Outcomes byte-identical to datacenter on the same Pages, including the empty ones |
| Across all runs on this page | 122 | 118 / 122 = 96.7% | 0 transport blocks observed. All 4 misses were Pages with no public reels |
On Pages that actually publish reels, the through-Apify success rate was 118/118. That is why this Actor has no residential fallback rung: datacenter is not walled here, and a reels payload runs about 1.4 MB per reel, so a residential retry would burn several times the revenue of the rows it recovered. You can still select RESIDENTIAL in the proxy input if your account needs it — just budget for the data transfer.
Retries rotate to a fresh datacenter session, because the failure mode on Facebook is a served-but-empty response rather than an HTTP error code. There is one extra safeguard: the reaction/comment/share counters arrive in a separate deferred chunk of the same response, and Facebook occasionally omits it — when a Page comes back with zero engagement fill, the Actor re-fetches it once on a fresh session before accepting the rows, and logs how many rows still ended up without counters.
How it works
The reels tab at https://www.facebook.com/<page>/reels/ is server-rendered: the first
batch of 10 reels is a plain JSON blob embedded in the HTML that a logged-out client
receives. No headless browser is needed to read it, which is why this Actor runs on 2 GB
instead of the 4–8 GB the browser-based reels scrapers ask for.
Later batches come from the one Relay query the browser fires when you scroll,
ProfileCometAppCollectionReelsRendererPaginationQuery. That query is answerable
logged out, but only if you send it exactly right: the request tokens Facebook prints into
the same HTML (lsd, haste session, revision, jazoest), the connection node id and
cursor from page_info, and Relay's 19 feature-gate "provided variables" with the precise
values Facebook chose for that response. Guess any of them and the server returns
noncoercible_variable_value, so this Actor lifts them verbatim out of the page's own
preloaded-query blob rather than hard-coding them.
The persisted-query id is not in the HTML — it lives in a JS bundle. The Actor tries to discover it at run time from the bundles the page links, and falls back to a pinned id when it cannot. Measured 2026-08-19 on 8 platform runs: the bundle that defines this query is lazily loaded and is not among the ones the reels tab links, so run-time discovery does not currently fire and every run uses the pinned id. That pinned id paginated 8/8 runs, including a 300-reel / 30-batch pass on a single Page, so pagination is working — but the self-healing path is not carrying it, and the id is re-verified on each release rather than per run.
The engagement counters are not in the reels connection at all; Facebook streams them later in the same response as deferred chunks, keyed back to a reel by its video id. The parser reads both and joins them.
Pricing
$0.002 per reel returned. One event, reel-scraped. That is the cheapest per-reel price
on the Apify Store for a Facebook reels Actor as of 2026-08-15 (live comparison: $0.0045,
$0.00499, $0.00599, $0.006, $0.007 across the other per-reel actors).
| Reels | Cost |
|---|---|
| 20 (shipped default, 2 Pages) | $0.04 |
| 100 | $0.20 |
| 1,000 | $2.00 |
| 10,000 | $20.00 |
You are billed for unique reels actually returned, and only for those:
- Reels are de-duplicated on
reel_idbefore the charge, across Pages and across pagination batches. - A Page with no public reels tab costs nothing.
- A Page that would not serve a payload after retries costs nothing.
- A reel removed by the
postedAfterfilter costs nothing — the filter runs before billing, so it costs you run time, not money. - If a run ends with zero reels it finishes SUCCEEDED with a status message naming why (no public reels / no payload / everything removed by your date filter) and bills nothing — it does not fail the run on you, and it does not silently pretend it worked.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
pages | array | ["redbull","gopro"] | Handles, Page URLs, /profile.php?id=… URLs or numeric Page ids. |
startUrls | list source | — | Bulk paste, a .txt/.csv upload, or a linked Google Sheet of Page URLs. |
maxReelsPerPage | integer | 100 (prefill 20) | Per-Page cap. Facebook pages in 10s. |
postedAfter | string | — | YYYY-MM-DD. Keep only reels published on or after this date. |
proxyConfiguration | object | Apify Proxy | Required. Datacenter default is what the numbers above were measured on. |
requestDelayMs | integer | 500 | Pause between Facebook requests. |
Handles, full URLs and numeric ids can be mixed freely, and duplicates across pages and
startUrls are dropped before anything is fetched.
Who buys this
- Ad-creative and short-form research. Every organic reel a competitor ran, with the MP4, the caption, the exact reaction and comment counts and the posted date — a swipe file with real engagement attached, refreshed on a schedule.
- Brand and competitor monitoring. Point it at a set of Pages with
postedAfterand a daily schedule to get posting cadence, format mix and engagement trend per brand. - Creator and partnership sourcing.
reaction_count / view_count_approxgives a per-reel engagement rate you can rank creators by — with the caveat from limit #1 that the denominator is rounded. - Video and dataset work.
video_url_hdpluscaptionandduration_secondsis a ready ingestion feed for transcription, captioning or vision pipelines.
When a run fails
| Log line | What it means | What to do |
|---|---|---|
no public reels ("This content isn't available right now") | The Page has no public reels tab. | Nothing — not billed. Check the Page in a logged-out browser. |
Page has a reels tab but publishes no public reels | Reels tab exists, collection is empty. | Nothing — not billed. |
no reels payload after retries | Three fetches on three sessions all came back without data. | Re-run; if it persists on one Page only, that Page is likely region-restricted. |
reels pagination stopped after N reel(s) | Facebook ended the connection early. | The N reels already returned are yours; re-run to go deeper. |
engagement counters missing from the first response | The deferred counter chunk was omitted; the Actor is retrying. | Nothing — informational. |
No reels scraped — N Page(s) publish no public reels … | Every Page you listed has no public reels, or your date filter removed all of them. | Run ends SUCCEEDED, nothing billed. Check your handles or widen postedAfter. |
Stopped early to stay within the run time limit | The Actor hit its own wall-clock budget and stopped before the platform could kill the run. | The reels already pushed are yours; raise the run timeout or lower maxReelsPerPage. |
No Facebook Pages supplied — running the built-in sample | You started the Actor with an empty input (common from the API or an AI agent). | The Actor runs the two-Page demo (redbull, gopro, 20 reels each) so you get real rows. Fill in pages to scrape your own. |
Legal & fair use
https://www.facebook.com/robots.txt states, for the generic crawler group:
User-agent: *Disallow: /
Facebook's robots.txt disallows generic crawlers site-wide and reserves crawl access to a named allow-list of bots. This Actor reads only publicly visible pages — no login, no cookies, no session token, nothing behind an authentication wall — and it returns business/brand Page content, not private individuals' data. It does not download or re-host video files; it returns the URLs Facebook itself serves. Robots.txt compliance, Meta's Terms of Service and the applicable data-protection rules in your jurisdiction are your responsibility as the operator of the run. If you are scraping at volume, or for a commercial product, take your own legal advice first.
Our other Facebook Actors
- Facebook Page Scraper — Page name, category, likes, talking-about, phone, email,
website, address and bio. Join to this dataset on
page_id.
Feedback
Found a Page this Actor mis-reads, or a field you need that Facebook publishes and this does not return? Open an issue on the Actor page with the Page handle — measured bug reports get fixed.