Scrape public ads from the Meta (Facebook) Ads Library by Page URL: creatives, copy, CTAs, placements, and reach/spend when Meta discloses them. JSON/CSV export for competitor intel, creative research, and media audits. Contact: corentin@outreacher.fr
Defaults — country omitted → all countries (ALL); maxAds omitted → 0 (no per-page cap within Actor limits); active ads only (no activeStatus input). Minimal input.json is URL-only.
GraphQL country — Meta’s API rejects countries: ["ALL"]; when input is ALL, listing/detail calls use FR (documented in README / input schema).
GraphQL variables — AdLibrarySearchPaginationQuery variables are merged from the browser-intercepted JSON (Relay shape) with patches for viewAllPageID, countries, cursor, etc.; replacing the whole object caused missing_required_variable_value.
Relay merge — when country is left empty (default ALL), do not overwrite activeStatus / mediaType / sortData from intercept — only sanitize countries (ALL→FR); overwriting defaults fixed empty edges while HTTP stayed 200.
Session URL — bootstrapLibrarySession used country=ALL in the Ads Library URL while GraphQL used FR, producing 0 edges; the loaded page now uses graphqlCountryCode (and lowercase ad_type / media_type in the query string) so it matches a working UI like country=FR.
Input UX — primary field is Facebook Page URL (url); Page ID is optional/advanced. Resolution order and docs updated; if both URL and Page ID are set, URL wins (no silent fallback to Page ID when url is present).
Logs — user-facing run messages moved to English for consistency with the README and Apify Store.
Local CSV — UTF-8 with BOM for Excel compatibility.
package.json version aligned with actor minor release.
Fixed
Pagination merge — when reusing an intercepted GraphQL body, doc_id from Facebook is no longer overwritten by a static constant (keeps front-end alignment).