Facebook Ads Library Scraper & Competitor Tracker avatar

Facebook Ads Library Scraper & Competitor Tracker

Pricing

from $0.60 / 1,000 ad or change events

Go to Apify Store
Facebook Ads Library Scraper & Competitor Tracker

Facebook Ads Library Scraper & Competitor Tracker

Extract public Facebook and Instagram ads by Page ID, keyword, or Meta Ads Library URL. Get copy, creatives, CTAs, landing page URLs, dates, platforms, and advertiser data. Track new, reused, changed, possibly inactive, confirmed inactive, and reactivated ads.

Pricing

from $0.60 / 1,000 ad or change events

Rating

0.0

(0)

Developer

Milad Amirzadeh

Milad Amirzadeh

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

14 days ago

Last modified

Share

Scrape public ads from the Facebook Ads Library (Meta Ads Library) by exact advertiser Page ID, keyword, or a copied Ads Library URL. Export ad copy, headlines, images, videos, carousel cards, CTAs, landing page URLs, dates, platforms, advertiser details, and available transparency data.

Need ongoing ad monitoring? Enable history to see which ads and creatives are new, reused, changed, possibly inactive, confirmed inactive, or reactivated across scheduled runs—without treating an incomplete Meta response as evidence that an ad has stopped.

No Facebook login, Meta API token, browser, or destination-site crawling is required.

What can you do with this Actor?

  • Research Facebook and Instagram ads: collect creatives, copy, CTAs, media, and landing page URLs.
  • Monitor advertiser activity: schedule exact Page ID searches and receive only meaningful change events.
  • Distinguish new Ad IDs from previously seen creatives: tell a new ad instance from a creative already observed in the same history.
  • Build a creative swipe file: export structured ad data to JSON, CSV, Excel, or your own database.
  • Track copy, media, and destination URL changes: detect changes to messaging, creative assets, or landing page URLs.
  • Automate ad intelligence workflows: run through the Apify API, schedules, webhooks, Make, Zapier, or other integrations.

Quick start

  1. Use the small prefilled example, or replace it with a Facebook Page ID, search term, or Meta Ads Library URL.
  2. Choose the country where the ads should be visible.
  3. Keep Raw ads selected for a one-time scrape. Enable history only for recurring monitoring.
  4. Click Start. Results appear in the Dataset and can be downloaded in multiple formats.

Not sure which setup to use?

GoalRecommended inputHistoryOutput
Research one known advertiserPage IDOffRaw ads
Discover ads across a marketSearch termOffRaw ads
Repeat filters from Meta Ads LibraryCopied Ads Library URLOffRaw ads
Monitor one competitor over timePage IDOnRaw ads and changes
Send only changes into an automationPage IDOnChanges only

The simplest raw scrape looks like this:

{
"searchTerms": ["running shoes"],
"countries": ["US"],
"maxResultsPerTarget": 100,
"outputMode": "raw"
}

What data does it extract?

Each raw result represents a real ad returned by Meta and can include:

  • Meta archive/library ID, Page ID, Ad ID, and collation identifiers;
  • advertiser name, page category, profile URL, profile image, and page likes;
  • active status, start date, and source-backed end date for inactive ads;
  • ad body, headline, description, CTA type, and CTA text;
  • display URL, Meta's source click URL, and ordered source-backed landing-page URLs;
  • deduplicated images, videos, video previews, and carousel cards;
  • Facebook, Instagram, Messenger, and other publisher platforms reported by Meta;
  • targeted/reached countries and available public transparency fields;
  • Ad, Asset, and Creative identity objects with explicit confidence and limitations;
  • optionally, the complete parsed source object under raw when includeRawPayload is enabled.

Fields that Meta does not provide are returned as null or an empty collection. The Actor does not manufacture spend, impressions, targeting, or other unavailable values.

Input guide

Choose what to scrape

You can use one or combine several input methods:

InputBest forExample
pageIdsExact advertiser scraping and scheduled monitoring"101694774572"
searchTermsDiscovering ads by brand, product, or market keyword"running shoes"
startUrlsReproducing a search configured in Meta Ads LibraryA full facebook.com/ads/library/... URL

For reliable competitor monitoring, prefer pageIds. Keyword results can change because of search ranking, so keyword absence is never treated as proof that an ad stopped.

Filters and limits

InputWhat it controlsRecommended use
countriesCountries where the ads should be visible, such as US, GB, DE, or ALLThis is the audience country, not the advertiser's home country
maxResultsPerTargetMaximum ads returned for each Page ID/keyword and country combinationUse a small limit for tests; leave empty for complete inactivity monitoring
activeStatusAll, active, or inactive adsUse all for full history; active for current creative research
startDateMin / startDateMaxAd start-date rangeOptional
adType, mediaType, contentLanguages, publisherPlatformsAdvanced Meta source filtersLeave at defaults unless you need a specific source filter
includeRawPayloadAdds Meta's complete parsed source object under rawLeave off for a smaller, cleaner Dataset; enable only for diagnostics or custom parsing

One Page ID with two countries creates two targets. The result limit applies separately to each target.

The Input tab starts with one Page ID, US, and a limit of 3 ads. This keeps the first test quick and inexpensive. Replace the Page ID with your advertiser when ready. Remove maxResultsPerTarget only when you need a complete advertiser history.

Raw scraping examples

Scrape an advertiser by Page ID

{
"pageIds": ["101694774572"],
"countries": ["US"],
"activeStatus": "all",
"maxResultsPerTarget": 100,
"tracking": false,
"outputMode": "raw"
}

Search multiple markets by keyword

{
"searchTerms": ["running shoes", "fitness app"],
"countries": ["US", "GB"],
"activeStatus": "active",
"maxResultsPerTarget": 250,
"outputMode": "raw"
}

Use a copied Meta Ads Library URL

{
"startUrls": [
{
"url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&view_all_page_id=101694774572"
}
],
"outputMode": "raw"
}

Competitor monitoring and change detection

Set tracking to true, choose a stable trackingNamespace, and reuse that namespace in every scheduled run of the same monitoring program.

Receive only changes

{
"pageIds": ["101694774572"],
"countries": ["US"],
"activeStatus": "all",
"tracking": true,
"trackingNamespace": "shoe-carnival-us",
"outputMode": "changes"
}

Receive raw ads and changes separately

{
"pageIds": ["101694774572"],
"countries": ["US"],
"activeStatus": "all",
"tracking": true,
"trackingNamespace": "shoe-carnival-us",
"outputMode": "rawAndChanges"
}

Runs with different namespaces keep independent histories. Do not reuse one namespace for unrelated brands or monitoring setups.

Change events

EventMeaning
NEW_ADA previously unseen ad instance appeared
NEW_CREATIVEA creative fingerprint has never been seen in this history
REUSED_CREATIVEA new Ad ID reused an existing creative
COPY_CHANGEDMeaningful ad text, headline, description, or CTA changed
MEDIA_CHANGEDImage, video, or carousel identity changed
LANDING_PAGE_CHANGEDThe canonical destination URL changed
POSSIBLY_INACTIVEAn ad was missing from one complete, eligible Page ID run
INACTIVE_CONFIRMEDMeta explicitly reported inactivity, or the ad was missing from two eligible runs
REACTIVATEDA previously confirmed inactive ad appeared again

The first tracked run intentionally emits discovery events such as NEW_AD and NEW_CREATIVE. This gives monitoring workflows an initial inventory instead of an unexplained empty result. Later unchanged runs can produce an empty Changes Dataset—this means no change was detected, not that the run failed.

Output modes

outputModeDefault DatasetSeparate Changes Dataset
rawRaw ad recordsNot used
changesChange events onlyNot used
rawAndChangesRaw ad recordsChange events

changes and rawAndChanges require tracking: true. The input is validated before any request is sent.

Example raw result

{
"recordType": "ad",
"pageName": "Example Brand",
"pageId": "123456789",
"archiveId": "987654321",
"isActive": true,
"headline": "Explore the new collection",
"body": "Designed for everyday movement.",
"ctaText": "Shop Now",
"sourceClickUrl": "https://example.com/collection",
"destinationUrl": "https://example.com/collection",
"destinationUrls": ["https://example.com/collection"],
"platforms": ["FACEBOOK", "INSTAGRAM"],
"creativeIdentity": {
"version": "v2",
"confidence": "exact",
"fingerprint": "v2:creative:...",
"limitations": []
}
}

Example change event

{
"eventType": "LANDING_PAGE_CHANGED",
"observedAt": "2026-08-15T05:53:34Z",
"adIdentity": {
"archiveId": "987654321",
"pageId": "123456789"
},
"creativeIdentity": {
"version": "v2",
"confidence": "exact",
"fingerprint": "v2:creative:...",
"limitations": []
},
"details": {
"from": "v2:landing:old-fingerprint",
"to": "v2:landing:new-fingerprint"
}
}

How tracking distinguishes a new ad from a new creative

A new Facebook Ad Library ID does not always mean a new creative. This Actor keeps three concepts separate:

  • Ad identity: the specific ad instance (pageId + archiveId).
  • Asset identity: the image, video, or carousel media.
  • Creative identity: the meaningful combination of media, copy, headline, CTA, and landing page.

Validated Meta video asset identifiers are used when available. Images without a stable source identifier are identified by complete-file SHA-256, not by temporary CDN URLs. Reused media is downloaded only once per run.

Meta can repeat identical carousel/card objects inside one source record. The Actor removes only semantically identical duplicates before media verification, output, and fingerprinting, while preserving the first-seen order and retaining distinct cards that share an image but have different copy or destinations. The optional raw payload remains unchanged.

creativeIdentity.confidence is exact when the required identity evidence is complete. If an asset cannot be verified, the raw ad is still returned, but the Actor marks confidence as limited and avoids definitive new/reused-creative claims.

Fingerprint algorithm upgrades use a new identity version and rebaseline already-known ads without emitting artificial copy, media, or landing-page change events.

How tracking avoids false inactive alerts

Meta can block a session, change a response contract, or return an incomplete page. A missing ad is therefore evaluated only when the Page ID run is complete and trustworthy.

  • Truncated, blocked, rate-limited, partial, or changed-contract runs never create missing/inactive transitions.
  • Keyword absence never creates inactivity events.
  • One eligible complete miss produces POSSIBLY_INACTIVE.
  • A second consecutive eligible miss produces INACTIVE_CONFIRMED.
  • An explicit is_active: false from Meta can confirm inactivity immediately.

Every run stores a RUN_SUMMARY with source health, record counts, retries, media verification metrics, output counts, and history commit status. The Actor never pushes fake error rows into your ad Dataset.

Pricing

Pricing is based on visible Default Dataset items plus a small run-start fee. Platform compute, storage operations, and proxy usage are included:

  • $0.005 per run;
  • $0.00075 per Default Dataset item on the Free plan ($0.75 per 1,000 items);
  • $0.00070 per item on Starter, $0.00065 on Scale, and $0.00060 on Business.

In raw and rawAndChanges mode, a billed Default Dataset item is one raw ad. In changes mode, it is one change event. The separate Changes Dataset in rawAndChanges mode is not billed as an additional result.

The first tracking baseline can produce multiple discovery events for one ad. Later changes runs typically return only actual changes. Use Apify's maximum charge per run setting if you need a hard budget cap.

Free-plan examples:

  • 100 raw ads: $0.005 + (100 × $0.00075) = $0.080;
  • an unchanged changes-only run: $0.005;
  • 10 change events: $0.005 + (10 × $0.00075) = $0.0125.

Performance and cost behavior

The Actor uses direct HTTP extraction instead of launching a browser. Source requests reuse a bounded residential session, while public media files use a separate direct CDN session so image/video bytes do not inflate residential proxy costs.

In a production acceptance run on 15 August 2026, a bounded test returned 40 ads from two exact Page ID targets in 9.2 seconds total runtime, with zero retries or restarts, about 75 MiB peak memory, and approximately $0.0032 in Apify platform usage before Store event pricing. This is one measured workload, not a speed or cost guarantee.

Actual throughput and platform cost vary with targets, countries, result volume, media size, proxy conditions, and Meta response behavior. Use each run's RUN_SUMMARY and Apify usage details when measuring your own workload.

API and integrations

You can run this Facebook Ads Library scraper manually, on a schedule, through the Apify API, or from integrations such as Make and Zapier. Dataset results can be exported as JSON, CSV, Excel, XML, RSS, or HTML.

A typical scheduled competitor tracker should:

  1. use exact Page IDs;
  2. keep the same countries, filters, and trackingNamespace;
  3. run at a consistent interval;
  4. use changes to receive only events, or rawAndChanges when both outputs are needed.

FAQ

Do I need a Facebook account or Meta API token?

No. The Actor reads public Meta Ads Library web data and does not require Facebook login or Graph API approval.

Can it scrape Instagram ads?

Yes. Meta Ads Library records can include placements reported for Facebook, Instagram, Messenger, and other Meta surfaces. platforms shows the placements available in the source record.

Should I use a Page ID or a keyword?

Use a Page ID when you know the advertiser and want reliable scheduled monitoring. Use keywords to discover ads across multiple advertisers or research a market.

How do I find a Facebook Page ID?

Open the advertiser in Meta Ads Library and copy the numeric value from the view_all_page_id parameter in the URL. You can also paste the complete Ads Library URL into startUrls.

Why is my Changes Dataset empty?

An empty Changes Dataset usually means the run succeeded but no new or changed ads were detected. Check RUN_SUMMARY to confirm source health and output counts.

Why are some values null?

Meta does not expose every transparency field for every ad, country, or ad category. Missing source values remain null; the Actor does not replace them with estimates.

For active ads, endDate is intentionally null. Meta's active-result end_date can move with the query window and is not reliable evidence of a scheduled stop. Inactive ads retain the source-backed end date when available; the untouched value is also available in raw.end_date when includeRawPayload is enabled.

Why do some ads contain {{product.name}} or similar text?

Meta returns template variables at the ad level for some dynamic product ads. These are source values, not invented placeholders. The resolved product headlines, copy, media, and destination URLs are available in the deduplicated cards array.

What is the difference between sourceClickUrl, destinationUrl, and destinationUrls?

sourceClickUrl is the canonicalized click URL reported by Meta and may still be a DoubleClick-style redirect. destinationUrls contains all ordered, unique destination URLs that can be determined directly from the ad and its cards without crawling another website. destinationUrl is populated only when a direct primary destination exists or the result is unambiguous. Each card follows the same separation through cards[].sourceClickUrl and cards[].destinationUrl. Unresolved redirect wrappers are never presented as landing pages.

Does the Actor download media files into storage?

It returns media URLs and, when tracking requires identity verification, streams supported assets to calculate identity. It does not save full media files as separate Dataset attachments.

What is includeRawPayload?

It adds Meta's complete parsed source record under raw for advanced diagnostics or custom parsing. It is off by default to keep Datasets smaller and easier to use; all documented normalized fields remain available without it.

Are Facebook CDN URLs permanent?

No. Meta CDN URLs can expire or change. Use them as locators, not stable identifiers. The Actor's Creative identity does not rely on the CDN URL alone.

Is this an official Meta API?

No. This is an independent Facebook Ads Library API alternative built from Meta's public web interface. Meta can change its private web contract; source-contract failures are reported explicitly rather than returned as silent empty results.

The Actor extracts publicly available advertising data and does not access private Facebook accounts. You are responsible for using the data lawfully and complying with applicable privacy, intellectual-property, platform, and data-protection rules.

Support

If a run fails, open the run's RUN_SUMMARY first. It distinguishes blocks, rate limits, partial results, valid empty results, and source-contract changes. For reproducible problems, create an issue with the Run ID, input with sensitive values removed, and the summary diagnostics.