Web Scraping Layers for AI & Automation

back to blog

How to scrape the Meta Ad Library for competitor ad research

ParseBird·14 Oct 2026

Key Takeaways

What is the Meta Ad Library? The Meta Ad Library (facebook.com/ads/library) is Meta's public transparency database of ads running across Facebook, Instagram, Messenger, Threads, and Audience Network. Anyone can search it by advertiser or keyword without logging in.

What can you scrape from the Meta Ad Library? Each ad's body text, headline, images, videos, carousel cards, call to action, landing page URL, start and end dates, platforms, and advertiser page. With details on, you also get EU and UK reach with age, gender, and country breakdowns, payer and beneficiary, and the advertiser's Facebook likes and Instagram followers.

Does the Meta Ad Library show how much a competitor spends? Mostly no. Meta publishes spend and impression ranges for political and issue ads. For ordinary commercial ads the spend field is usually empty. EU reach numbers are the closest public proxy for scale.

What is the fastest way to find a competitor's winning Facebook ads? Sort by run length. Advertisers stop ads that lose money, so an ad that has been active for 60 or more days is very likely profitable.

Why the Meta Ad Library is the best free competitor ad research source

Performance marketers, DTC founders, agencies, and creative strategists use the Meta Ad Library to see exactly what competitors are running on Facebook (Meta), Instagram, Messenger, and Threads. Since Meta made the library public, it has been the largest free source of real, live ad creative anywhere.

The problem is the interface. It shows one advertiser's ads as cards, with no export, no sorting by run length, and no way to compare 10 competitors side by side. The Meta Ad Library Scraper returns the same data as structured rows.

Research questionField to use
What hooks and offers are competitors testing?snapshot.body.text, snapshot.title
Which ads are probably profitable?start_date_formatted, is_active
Image, video, or carousel?snapshot.display_format, snapshot.cards
Where does the ad send traffic?snapshot.link_url, snapshot.cta_type
Which placements do they buy?publisher_platform
How many people in the EU saw it?transparency_by_location.eu_transparency.eu_total_reach

How to scrape a competitor's Facebook and Instagram ads

The scraper takes one startUrl, which can be a Facebook Page URL, an Instagram profile URL, a single ad URL, a plain keyword, or any Ad Library search URL with filters already set.

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("parsebird/facebook-ads-library-scraper").call(run_input={
    "startUrl": "https://www.facebook.com/nike/",
    "maxAds": 500,
    "country": "US",
    "activeStatus": "all",
    "extractDetails": False,
})
ads = client.dataset(run["defaultDatasetId"]).list_items().items

The easiest way to apply complex filters is to set them in the Ad Library itself (country, media type, platform, language, date range, exact phrase), then paste the resulting URL as startUrl. The scraper keeps every filter in the URL.

InputValuesNotes
startUrlPage URL, Instagram URL, Ad Library URL, ad URL, or keywordRequired
maxAds1 to 10,000Default 100
countryTwo-letter code or ALLUsed when the URL has no country
activeStatusactive, inactive, allall includes stopped ads, useful for history
extractDetailstrue or falseEU/UK reach, demographics, payer, advertiser stats

Can I scrape Instagram ads, or only Facebook ads? Both. The Ad Library covers Facebook, Instagram, Messenger, Threads, and Audience Network, and each ad's publisher_platform field lists where it ran. You can also start from an Instagram profile URL.

Finding long-running ads as a profitability signal

Run length is the single most useful public signal in ad research. Here is a simple filter for ads that have run at least 60 days:

const DAY = 86400;
const now = Math.floor(Date.now() / 1000);

const winners = ads
  .map((ad) => ({
    id: ad.ad_archive_id,
    page: ad.page_name,
    hook: ad.snapshot?.body?.text?.slice(0, 120),
    format: ad.snapshot?.display_format,
    cta: ad.snapshot?.cta_text,
    daysRunning: Math.round(((ad.is_active ? now : ad.end_date) - ad.start_date) / DAY),
    url: ad.ad_library_url,
  }))
  .filter((ad) => ad.daysRunning >= 60)
  .sort((a, b) => b.daysRunning - a.daysRunning);

Group the winners by format and cta and patterns show up fast: one competitor might run long-lived video ads with "Shop now" while its static image ads rarely last more than two weeks.

Why do many ads have the same text? Advertisers often run the same copy with different images or videos, or across several pages. Group by snapshot.body.text to count variants. A hook with many creative variants is one the advertiser is investing in.

Using EU reach and demographics as a scale proxy

The EU Digital Services Act requires Meta to publish reach data for ads shown in the European Union. With extractDetails on, each EU-targeted ad includes eu_total_reach and breakdowns by country, age, and gender. That is the closest thing to impression data the Ad Library offers for commercial ads.

A trimmed, illustrative details block:

{
  "aaa_info": { "targets_eu": true },
  "transparency_by_location": {
    "eu_transparency": {
      "eu_total_reach": 173451,
      "gender_audience": "All",
      "age_audience": { "min": 18, "max": 65 },
      "age_country_gender_reach_breakdown": [
        {
          "country": "AT",
          "age_gender_breakdowns": [
            { "age_range": "45-54", "male": 1073, "female": 547, "unknown": 19 }
          ]
        }
      ]
    },
    "uk_transparency": { "total_reach": 6485 }
  }
}

Details are billed as a separate event, so a cost-efficient pattern is two passes: scrape all ads without details, filter to long-running ones, then re-scrape only those by their single-ad URLs with extractDetails on.

Meta Ad Library scraper pricing

At the time of writing the scraper charges about $0.59 per 1,000 ads, plus about $0.59 per 1,000 ad-details lookups when extractDetails is on, with lower prices on paid Apify plans. Check the actor page for current rates.

Pairing Meta ad data with TikTok ad data

Most brands now split paid social spend between Meta and TikTok. The TikTok Top Ads guide covers the TikTok side: Creative Center ranks top ads by CTR and engagement, which complements Meta's run-length signal. For an always-on version of this research, see how to build competitor monitoring without code.

FAQ

Is it legal to scrape the Meta Ad Library? The Ad Library is a public transparency tool and the scraper reads only what it shows to logged-out visitors. Meta also offers an official Ad Library API, which requires identity verification and mainly covers political and issue ads. Check Meta's terms before commercial use.

How far back does the Meta Ad Library go? Active ads are always shown. Political and issue ads are kept for seven years, and ads delivered in the EU are kept for a year after they last ran under the Digital Services Act. Other inactive commercial ads may not be listed. Set activeStatus to all to include any inactive ads the library still shows.

Can I download the ad images and videos? The output includes image and video URLs from Meta's CDN. These links are signed and expire after a few days, so download the files you want to keep soon after the run.

Can I track when a competitor launches new ads? Yes. Schedule a daily run on the competitor's page with activeStatus set to active and compare ad_archive_id values with the previous run. New IDs are new ads.

Browse the Social Media category for more ad and social data tools.