Scrape public Facebook Page Reels and direct Reel URLs. Export engagement metrics, captions, creators, dates and optional media URLs to JSON, CSV or Excel. Filter by date and deduplicate results without a Facebook login.
All notable changes to this Actor are documented in this file.
2.1.0 — 2026-09-03
v2.1 stabilization: makes delivered records carry what the README promises (engagement counts, owner identity), repairs operational truth, and adds the competitor-proven exact-count mode (experimental). Implemented from the v2.1 spec; live findings from the 2026-09-03 v2.1 probe and live cloud test report.
Added
Engagement metrics on direct-Reel records (ticket 03): the og:title engagement summary ("6.4K views · 19 reactions | caption") is now parsed in production, so direct reels carry viewCount/reactionCount (+ display/label/precision/source) with source: "open_graph" and precision: "rounded" (or "exact" for full numbers). Unobserved channels stay null — never 0.
Owner identity (ticket 04): ownerType/ownerName/ownerUrl derived from the 4-segment og:url/canonical page-video shape at zero extra requests; profile-shaped URLs classify as profile; unresolvable shapes stay unknown.
Relative and ISO dates (ticket 05): dateFrom/dateTo accept YYYY-MM-DD, full ISO timestamps, and relative expressions ("7 days", "2 months", "1 year") resolved against run start in UTC, matching the official actor's UX.
metricsMode: "exact" (ticket 10, experimental): requests direct-Reel details in a locale proven (2026-09-03 probe) to serve unabbreviated counters ("6.4K views" → "6.492 Aufrufe"); German dot-grouped numbers and labels parse locale-aware. Precision labels always reflect the observed display string; promotion from experimental requires the Phase 0 exact-agreement gates.
sourceLocale now carries the observed og:locale (e.g. en_US).
INTERNAL_ERROR failure code for unclassified exceptions so block-rate telemetry stays trustworthy (ticket 01).
PARSER_DEGRADATION warnings that actually fire: systemic schema-miss rate above threshold, or zero candidates on every attempted Page after browser escalation (ticket 01).
Changed
Per-URL error isolation (ticket 02): one invalid or prohibited URL no longer kills the run. Each rejected URL is skipped with a sanitized error record and a RUN_REPORT warning; the run fails (INVALID_INPUT_URL) only when zero valid sources remain, with an aggregated, capped rejection message.
Platform-truth exit codes (ticket 01): a run whose terminal status is FAILED exits non-zero so the Apify platform shows FAILED; SUCCEEDED/EMPTY/CHARGE_LIMIT still exit 0.
Exclusion-counter truth (ticket 01): every date-window exclusion increments RUN_REPORT.totals (excludedBeforeRange, excludedAfterRange, unresolvedTimestamp), so emitted + excluded + unresolved reconciles with attempted.
Docs truth (ticket 08): README/architecture state the real 57-field record (was "53"); docs-contract pins the count against the dataset schema; provenOptionalMediaFields re-baselined through the standard pipeline — only thumbnailUrl survives on current logged-out pages.
Honest page-discovery claims (tickets 07/09): live evidence shows logged-out Page Reels tabs deliver zero Reels through the Actor today; the README capability is re-scoped accordingly and page runs degrade loudly (EMPTY + PARSER_DEGRADATION + per-source stop reasons). Repair is an evidence-gated follow-up (see the probe report §3).
Publication timestamps: documented as unavailable logged-out for direct reels (probe finding); date filtering over direct reels is best-effort with counted exclusions (ticket 06).
Related-Reel expansion: not shipped (ticket 11) — logged-out payloads carry related content only as Video stubs without counts or reel links (documented no-go).
2.0.2 — 2026-09-03
Fixed: every cloud run crashed at startup because the named browser-fallback request queue (BROWSER_FALLBACK) violated Apify storage naming rules (lowercase letters, digits, hyphens only). The queue is now run-scoped (browser-fallback-<runId>), which also prevents aborted runs from leaking browser work into later runs. Discovered by the first live cloud run of v2 on 2026-09-03; local runs never hit it because local storage does not enforce the naming rule.
Fixed: saveErrors: true runs crashed on the first recorded error because the named dataset ERROR_RECORDS also violated the naming rule. The dataset is now named error-records (README and docs updated accordingly).
2.0.1 — 2026-08-18
Fixed: extractReelIdFromUrl now resolves the numeric Reel ID from Facebook's modern 4-segment /videos/<descriptive-slug>/<id>/og:url/canonical shape. Previously it returned the descriptive slug, so direct-Reel records were discarded with PARSER_SCHEMA_MISS even though the page carried extractable OpenGraph data.
Changed: a 200 OK Page seed that yields zero reel candidates now reports JS_REQUIRED and escalates once to the bounded browser fallback (per-source attempt ledger), instead of silently reporting "no more public results" with no verification. Facebook client-side renders Reels grids for logged-out visitors on all HTML surfaces. Browser requests are now counted in RUN_REPORT.requests.browserRequests.
Both findings verified by live logged-out runs on 2026-08-18 (public NASA Page + a public direct Reel).
2.0.0 — 2026-08-17
This major release delivers an HTTP-first architecture overhaul designed for high throughput, predictable memory footprint (1,024 MB baseline), granular metric precision, and seamless Pay-Per-Event (PPE) integration.
Release Evidence Receipts: Local development consistency receipts are archived in Release Evidence Receipts. Cloud deployment, beta canaries, and production promotions remain blocked while Phase 0 is HOLD.
Evidence-Selected Completeness: Operates using the seed_and_direct_only finite pagination route under the current Phase 0 HOLD decision as recorded in Phase 0 Decision. Deep page history pagination remains unproven.
Breaking Changes
Flat Dataset Schema (2.0.0): Emitted records conform to schemaVersion: "2.0.0". All nested objects (author, page, audio, fieldStatus) are replaced with a flat 53-field schema for zero-transformation analytics and direct CSV export compatibility.
Field Renames:
canonicalUrl is replaced by url.
publishedAt is replaced by createdAt (with companion createdAtTimestamp and createdAtPrecision).
caption is replaced by text.
Nested author.* and page.* are flattened into ownerType (page, profile, unknown), ownerName, ownerId, ownerUrl, and sourcePageUrl.
Nested audio.* is flattened into musicTitle and musicArtist.
Metric Decomposition: The old ambiguous engagement counters are replaced by 5 independent, non-coalesced metric channels:
Zero Coercion Policy: Unobserved or missing metrics remain null and are never coerced to 0. A value of 0 strictly indicates that Facebook explicitly published an observed zero count.
Removed Inputs:
maxListingScrolls and maxConcurrency are removed. Concurrency and pagination are handled automatically by the HTTP crawler engine and bounded browser resource pool.
Personal profile listing discovery is removed; only public Facebook Page URLs and direct Reel URLs are accepted.
Added Features & Improvements
HTTP-First Streaming Engine: Direct Reel extractions and seed Page discoveries execute via fast, lightweight HTTP streaming parser without browser launch overhead. Deep pagination is held in Phase 0 pending live public web evidence.
Bounded Browser Escalation: Browser execution is strictly bounded and invoked only when JavaScript hydration or anti-bot verification requires DOM evaluation.
Pay-Per-Event (PPE) Billing: Integrated exact per-event charging per successfully emitted dataset item with crash recovery reconciliation.
Deduplication Key: Added deterministic dedupeKey (facebook:reel:<reelId>) across all records for at-least-once downstream reconciliation.
Signed Media Transparency: Added videoUrlSd, videoUrlHd, thumbnailUrl, mediaUrlObservedAt, and mediaUrlMayExpire: true for short-lived CDN URLs.
Operational Diagnostics: End-of-run RUN_REPORT persisted to the default Key-Value Store with per-source progress counters, parser health rates, and warnings. Dedicated ERROR_RECORDS dataset available when saveErrors: true.
Known Limitations
Public Content Only: Only publicly accessible Facebook Page Reels and direct Reel URLs are scraped. Private profiles, groups, and authenticated reels requiring login are unsupported.
Transient Media CDN URLs: Media URLs (videoUrlSd, videoUrlHd, thumbnailUrl) are signed CDN URLs that may expire after several hours (mediaUrlMayExpire: true). Downstream pipelines should download or ingest media promptly.
Deep Pagination Feeds: Reel discovery operates over public Page listing feeds without login; pagination depth reflects Facebook's publicly exposed feed window.
Zero Automated Auth Bypass: The Actor strictly respects platform boundaries and does not attempt CAPTCHA solving, checkpoint evasion, or credential stuffing.
1.0.1 — 2026-08-16
This hardening release follows a ten-perspective production-readiness review. It adds a separate candidate-detail budget for narrow date ranges, strengthens Reels-only URL admission, binds hydration metadata to the target Reel identity, preserves mixed source-kind provenance, bounds browser snapshot capture, adds deterministic response-capture draining, emits sanitized debug diagnostics, rejects detail pages that no longer resolve to a Reel, and expands parser/deduplication regression coverage.
The release also upgrades and pins the production browser runtime to the matching Apify Node 22 / Playwright 1.62.1 image, moves the TypeScript runtime loader into production dependencies, and verifies zero production dependency advisories with npm audit --omit=dev.
Pre-publication fixes folded into this release: the request-handler timeout now scales with maxListingScrolls so default discovery runs no longer exceed the previous fixed 180-second budget; malformed URL strings inside captured hydration JSON no longer crash detail parsing; profile.php?id=… Page sources normalize to the correct sk=reels listing target; zero-millisecond durations parse as 0 instead of falling through to unrelated keys; and dead failure-classification branches were removed. Platform-side schema files were corrected for Apify build validation: unsupported per-field advanced flags were removed from the input schema, and the dataset schema was restructured to the required actorSpecification/fields/views shape with a full record schema. Dataset schema field types were then aligned with the emitted records (mediaUrlExpiryWarning is boolean-or-null and reelId is nullable), push failures now log the platform rejection reason and a sanitized record type signature, and a CI contract test validates fixture, fully populated, and sparse records against the deployed schema.
1.0.0 — 2026-08-16
The initial production release adds public-only Facebook Reel collection from Page/Profile discovery URLs and exact direct Reel URLs. It provides a 1,000-result default, configurable limit through 10,000, exact inclusive UTC date bounds, canonical URL deduplication, public metadata normalization, aggregate engagement counters, transient-media warnings, source-level diagnostics, and RUN_REPORT coverage reporting.
The release includes a Node.js 22 TypeScript/Playwright Apify Actor, strict runtime input validation, Console input/output schemas, durable queue/checkpoint behavior, sanitized error records, fixture-based tests, and deployment documentation.