Facebook Reels Scraper - $0.35 per 1,000 Reels
Pricing
from $0.35 / 1,000 reels
Facebook Reels Scraper - $0.35 per 1,000 Reels
Scrape any public Facebook Page's Reels for $0.35 per 1,000 - up to 200 per Page. Reel link, video URL, thumbnails, caption, hashtags, duration, posting time and view, reaction, comment and share counts. No login, no cookies. The cheapest Facebook Reels scraper on the market.
Pricing
from $0.35 / 1,000 reels
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
8 hours ago
Last modified
Categories
Share
Facebook Reels Scraper
Paste public Facebook Page URLs and get their newest Reels back as clean, flat rows: the reel link, a direct video file URL, the thumbnail, the full caption and its hashtags, the exact time it was posted, how long it runs, its frame size, and its view, reaction, comment and share counts — plus who the Page is. No login, no cookies, no Facebook account, no browser, and nothing for you to configure.
- Up to 50 Pages in a single run, and up to 200 reels from each of them — not just the handful a Page shows on its front tab.
- A direct video file URL and two thumbnails on every row, so you can download or embed without a second tool.
- Reaction and comment counts are exact numbers, not rounded labels.
- Captions come back whole, with the hashtags already split out into their own array.
- Date filtering is included at no extra charge — it is a field on the input, not a paid add-on.
- Runs with empty input return a labelled sample row, free, so you can see the shape first.
- A Page that is blocked, private, misspelled or simply has no reels produces an uncharged diagnostic row, never a failed run.
Price
$0.35 per 1,000 reels, plus a $0.0005 start fee per run (billed per gigabyte of run memory, so exactly that on the default 1 GB).
This is the cheapest Facebook Page Reels scraper on the market, and it is the same rate on every plan, free or paid. There are no volume tiers, no minimum spend, no subscription and no add-on fees. What you read here is what you pay on day one and on day four hundred.
| Reels | Total cost |
|---|---|
| 100 | $0.0355 |
| 1,000 | $0.3505 |
| 10,000 | $3.5005 |
| 100,000 | $35.0005 |
What is actually charged
- One
reel-scrapedevent per reel row written to the dataset. Nothing else is metered per row. - Free: the sample row an empty run returns, and every diagnostic row — a blocked target, a dead URL, a search that matched nothing. Those rows all carry
"charged": false. - Reels dropped by your date filter are never charged — the filter runs before billing, and using it costs nothing extra.
- Duplicate reels inside a single run are dropped before they are charged.
- A Page that returns nothing produces one free diagnostic row and no reel charges.
- A run that finds nothing costs the start fee and nothing more.
- Rows never leave the dataset without a charge, and are never charged without a row. The billed event is a named one, so there is no price quietly attached to
apify-default-dataset-item— the trick that makes some scrapers bill you for their own error messages.
Input
{"startUrls": ["https://www.facebook.com/9gag","https://www.facebook.com/natgeo"],"resultsLimit": 60,"onlyPostsNewerThan": "30 days"}
| Field | What it does |
|---|---|
startUrls | Public Facebook Page URLs, one per line. A bare handle (9gag), a Reels-tab URL, a /pg/ URL, a /p/ URL and a profile.php?id= URL all work. Up to 50 Pages per run. A single /reel/… link is not a Page and is rejected with a free diagnostic row. |
resultsLimit | How many recent reels to take from each Page, newest first. Default 50, maximum 200. The first ten cost one request; past that the Actor walks the Page eight reels at a time, so a big number costs more time but roughly the same per reel. Lower it while testing; you pay per reel. |
onlyPostsNewerThan | Optional. Drop reels older than this. Accepts 2026-08-01, a full ISO timestamp, an epoch, or a relative window such as 7 days. Free. |
onlyPostsOlderThan | Optional. Drop reels newer than this. Same formats. Free. |
proxyUrls | Leave empty. Fill it in only if you want the traffic to leave through proxy servers you already pay for, as http://user:pass@host:port. |
Run it with empty input and you get one clearly labelled sample row, free, so you can see the output shape before you spend anything.
Output
One row per reel. A real row from a real run:
{"ok": true,"charged": true,"recordType": "reel","inputUrl": "https://www.facebook.com/9gag","pageName": "9GAG","pageId": "100064681269092","pageUrl": "https://www.facebook.com/9gag/","pageIsVerified": true,"pageProfilePicture": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=100064681269092","reelId": "27847866498168467","reelUrl": "https://www.facebook.com/reel/27847866498168467","postId": "1532426152256746","videoUrl": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=27847866498168467","thumbnailUrl": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=27847866498168467&get_thumbnail=1","previewImageUrl": "https://scontent-yyz1-1.xx.fbcdn.net/v/t15.5256-10/759017053_1030907243061362_759126857526234640_n.jpg","caption": "how fancy you're #9gag #foodart","captionLength": 31,"hashtags": ["9gag","foodart"],"time": "2026-08-15T07:00:01.000Z","timestamp": 1786777201,"viewCount": 586000,"viewCountText": "586K","reactionsCount": 1833,"commentsCount": 15,"sharesCount": 33,"sharesCountText": "33","durationMs": 24682,"durationSeconds": 24.682,"width": 1080,"height": 1920,"aspectRatio": 0.5625,"audioTitle": "Esperé Eckard-Lee · Paris Carousel","audioIsOriginal": true,"isReshare": false,"isSponsored": false,"scrapedAt": "2026-08-16T05:08:11.916Z"}
Field notes
inputUrl— the Page URL you asked for, so you can group rows by Page after merging several runs.reelUrl— the canonicalfacebook.com/reel/…permalink. This is the link to share or open in a browser.videoUrl— Facebook's own public media endpoint for that reel. It is a stable address rather than a signed link that expires in a few hours, so it keeps working in a spreadsheet you open next week — but Facebook only serves the MP4 itself to a crawler identity: fetched with an ordinary browser or HTTP-client user-agent it answers with a small HTML redirect to the reel's watch page instead. Measured:curl -A 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' '<videoUrl>' -o reel.mp4returns video/mp4; the same request with a browser user-agent returns 302 bytes of HTML. The Actor never downloads the file itself — you are charged for the row, not for the video.thumbnailUrl— a stable thumbnail URL from the same public media endpoint.previewImageUrlis the higher-resolution first frame, on a CDN address that does expire — take a copy if you need it to last.caption— the reel text exactly as posted, including emoji and line breaks.hashtagsis the same caption with the tags pulled out into an array, without the#.time— the exact posting time in ISO 8601 UTC, taken from the reel itself rather than a "2 days ago" label.timestampis the same moment in epoch seconds.viewCount— the play count. Facebook only publishes this rounded — it shows "586K", never 586,214 — soviewCountis that rounded figure turned into a number andviewCountTextkeeps the original string so nobody mistakes it for exact.reactionsCount— total reactions of all types at read time, and this one IS exact rather than rounded.commentsCountis exact too. Both were present on all 1,031 rows of the last measured sweep; they can still be null on a reel Facebook has not yet published a counter for, which is usually the very newest one on a Page.sharesCount— shares at read time, rounded the same way views are;sharesCountTextkeeps the original. Null when Facebook publishes no share count for that reel.durationMs— the reel length in milliseconds, withdurationSecondscarrying the same value with its fractional part.width—width,heightandaspectRatiodescribe the video frame. Reels are usually 1080x1920, but Facebook also accepts landscape reels, so do not assume vertical.audioTitle— the soundtrack label Facebook shows on the reel — a licensed track, or "isReshare— true when the Page re-shared somebody else's reel rather than posting its own.isSponsored— true when the reel is a paid placement rather than an organic one.
Every real row carries "charged": true. Sample rows carry "_sample": true and diagnostic rows carry "_diagnostic": true with an errorCode you can filter on, and neither is ever billed.
How it works
- It reads the public, logged-out version of the Page's Reels tab and lifts the reels out of the structured data already inside that page. No headless browser, no rendering, no scrolling, no account and no cookies.
- The first ten reels of a Page arrive in that one request. Beyond that the Actor follows the same paging cursor the Reels tab itself uses, eight reels per call, on the same connection — so going deeper costs a little more time and no extra page loads.
- The engagement counters live in a different part of that same response from the reels themselves, so the read runs on until the counters for every reel found have arrived, and then stops — the rest of the page is deferred video-player state this Actor has no use for.
- Traffic leaves through a large pool of rotating addresses. Facebook throttles per address, so a refusal is answered by moving to a fresh one and asking again, up to eight times per Page, with the request identity varied each time.
- Nothing is charged until a reel row is safely written to your dataset.
What people use it for
- Short-form content research — pull the newest reels from thirty Pages in your category every morning and sort by
viewCountto see what is actually working this week. - Competitive and brand monitoring on the surface Facebook is pushing hardest, with engagement numbers as plain columns rather than screenshots.
- Creator and influencer vetting — reach, reaction rate and posting cadence for a list of Pages, in one run, before you sign anything.
- Hook and format analysis:
caption,hashtags,durationSecondsandaspectRatiotogether tell you what the top performers have in common. - Building a reel archive —
reelUrl,videoUrlandthumbnailUrlon every row mean the record survives a deleted reel. - Feeding a dashboard or a warehouse: rows are flat and typed, so they load without a transformation step.
Reading the output
Every run writes three kinds of row, and they are easy to tell apart:
- Real rows carry
"charged": trueand"recordType": "reel". These are the rows you paid for, one billed event each. - The sample row carries
"_sample": trueand"charged": false. There is exactly one, it only appears when the input had no Page URLs, and it exists so you can look at the output shape before you spend anything. - Diagnostic rows carry
"_diagnostic": true,"charged": falseand anerrorCodeyou can switch on:NOT_FOUNDwhen there is no public Page at that URL,BLOCKEDwhen Facebook served a login interstitial from every address tried,NO_REELSwhen the Page rendered but publishes no reels,BAD_INPUTwhen a URL could not be read as a Page,TIME_BUDGETwhen the run ran out of time before reaching a Page, andNETWORKwhen Facebook could not be reached. Each carries theinputUrlit belongs to and a plain-English explanation.
If you only want the data, filter on charged == true. The count of those rows always equals the number of events you were billed for, so the dataset is its own invoice.
Limitations
- The ceiling is 200 reels per Page per run. A Page that has published fewer than you asked for returns what it has — that is not an error, and you are only charged for what arrives.
- Deep runs take longer than shallow ones: the first ten reels of a Page come back in one request, and every eight after that is another. Asking 50 Pages for 200 reels each is a long run, so give it a generous timeout or split it.
- The date filters narrow the reels a Page has published — they cannot reach further back than the Page itself goes. Asking for last year on a Page that started reels in March will correctly return nothing.
- View counts and share counts are published by Facebook only in rounded form ("586K"), so those two columns are rounded. Reaction and comment counts are exact.
- Occasionally Facebook has not yet published any engagement counter for a brand-new reel, and
reactionsCount,commentsCountandsharesCountcome back null for it; the reel itself, its caption, its view count and its media links are all still there. It is rare - across the last 1,681 measured rows it did not happen once - and it fills in within a day. - Two of the optional fields are frequently empty because the reels themselves are:
hashtagsis empty when the caption has none, andaudioTitleis null when the reel carries no soundtrack label. Across a 1,031-row sample they were populated on 32% and 49% of rows respectively. Everything else on this list was populated on 100% of those rows. - Not every Page has a public Reels tab. Plenty of large Pages post short video to their timeline without it ever appearing under Reels, and those Pages correctly return an uncharged
NO_REELSrow rather than invented data. - Public Pages only. Personal profiles with a private timeline, Groups, Events and anything behind a login are out of scope and produce an uncharged
NOT_FOUNDorBLOCKEDrow. - Some Pages are age-restricted or country-restricted and show a logged-out visitor nothing at all. Those return an uncharged diagnostic row, and no amount of retrying changes it.
- Comments themselves are not returned, only the comment count. The same goes for the identities of people who reacted.
- View, reaction, comment and share counts are a snapshot at read time and keep moving on a live reel.
videoUrlpoints at a public Facebook media address. It is not a licence: what you may do with somebody else's video is between you and them.- Facebook throttles per address. Under heavy parallel load a Page can come back as
BLOCKED; re-running a few minutes later normally clears it, and nothing is charged for the attempt. - Captions are returned as posted. They are not translated, and emoji and line breaks are preserved exactly.
Questions
My Page has no @username, only a numeric id. Does it work?
Yes. Paste whatever Facebook shows you — facebook.com/profile.php?id=1000..., the facebook.com/people/Page-Name/1000.../ form, the /p/Page-Name-1000.../ form, or just the number on its own. All four read the same Page, with the same fields and the same pagination as a Page that has a custom URL.
Do I need a Facebook account or cookies?
No. Nothing in this Actor logs in, holds a session, or asks you for credentials. It reads only what Facebook shows the public web, which is also why private content is out of reach.
How many reels can I get from one Page?
Up to 200 per Page per run, set with resultsLimit. The default is 50: the first request already carries 10 and the rest are paginated eight at a time, at roughly the same cost per reel. Lower it to 10 if you only want the newest few and want the cheapest possible run. Running it on a schedule and deduplicating on reelId builds deep history over time, one cheap run at a time.
Why is the view count rounded but the reaction count exact?
Because that is how Facebook publishes them. The reels surface ships plays as a display string like "586K" and ships reactions and comments as real integers. viewCount is that string parsed into a number for you, and viewCountText keeps the original so the rounding is never hidden.
Is videoUrl a real download link?
It is Facebook's own public media address for that reel, and it is stable rather than a signed URL that expires — but whether it hands you the file depends on who asks. Fetched with a crawler user-agent it answers video/mp4; fetched with an ordinary browser or HTTP-client user-agent it answers a ~300-byte HTML redirect to the reel's watch page instead. So it downloads fine with curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "<videoUrl>" -o reel.mp4, and not with a plain curl <videoUrl>. The Actor never fetches the video itself — you are charged for the row, not for the file.
What happens if a Page has no reels?
You get one uncharged NO_REELS diagnostic row for that Page, the run carries on to your other Pages, and you are billed nothing for it.
Does the date filter cost extra?
No. It is a plain input field, it runs before anything is billed, and reels it removes are never charged. Filtering to last week is strictly cheaper than not filtering.
Will the run fail if something goes wrong?
No. A blocked, empty or broken target produces an uncharged diagnostic row and the run still finishes as succeeded. A failed run would still bill you the start fee, which would mean paying to be told something went wrong.
Can I run this on a schedule?
Yes, and it is the intended way to use it. Nothing in the run holds state between runs. Schedule the same Page list daily and deduplicate on reelId to see only new reels.
How do I get exactly the rows I paid for?
Filter the dataset on "charged": true. Sample and diagnostic rows are always false, and the number of charged rows always equals the number of billed events.
Do I need to supply a proxy?
No. The run brings its own egress and its cost is already inside the price you see. The proxyUrls field exists only for callers who specifically want traffic to leave through servers they own.