Facebook Ad Library Scraper avatar

Facebook Ad Library Scraper

Pricing

$0.50 / 1,000 results

Go to Apify Store
Facebook Ad Library Scraper

Facebook Ad Library Scraper

Scrapes ads from the Facebook Ad Library. Accepts search URLs or Facebook page URLs and returns structured ad data.

Pricing

$0.50 / 1,000 results

Rating

0.0

(0)

Developer

Practical Tools

Practical Tools

Maintained by Community

Actor stats

0

Bookmarked

34

Total users

10

Monthly active users

5 days ago

Last modified

Share

Extract ads from the Facebook Ad Library — including creative content, targeting info, impressions, and page details — without needing a Facebook account or API key.

Three input modes: keyword search (simplest), Ad Library search URLs, or Facebook page URLs. Handles cursor-based pagination automatically. Output is normalized to one row per creative card.


Features

  • No login required — scrapes the public Ad Library
  • Simple keyword mode — type a keyword and go, no URL-building required
  • Three input modes — keyword search, Ad Library search URLs, or Facebook page URLs
  • Normalized card-level output — one dataset row per creative card, clean flat fields, dates as YYYY-MM-DD
  • Automatic pagination — follows cursor-based pages until the limit is reached
  • Proxy-ready — supports Apify residential proxies or custom proxy URLs

Input

There are two ways to tell the actor what to scrape. Use one or the other — not both.

Provide a keyword and the actor builds the Ad Library URL for you:

{
"keyword": "zapier",
"country": "US",
"activeOnly": true,
"mediaType": "all",
"limitPerSource": 50
}

That's it. No URL construction needed.

URL mode

Provide pre-built Ad Library search URLs or Facebook page URLs:

{
"urls": [
{ "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=zapier&search_type=keyword_unordered&media_type=all" }
],
"limitPerSource": 50
}

The above two examples produce identical results. Use URL mode when you need precise control over query parameters, or when you're copying a URL directly from the Ad Library website.

All input fields

FieldTypeDescription
keywordstringSearch keyword. The actor builds the Ad Library URL for you. Use this OR urls, not both.
urlsarrayPre-built Ad Library search URLs or Facebook page URLs. Use this OR keyword, not both.
countrystringISO 3166-1 alpha-2 code (US, GB) or ALL. Applies to all input modes. Default: ALL
activeStatusstringFilter by ad status: all, active, inactive. Applies to all input modes. Default: all
mediaTypestringFilter by media type: all, image, video, meme, none. Applies to all input modes. Default: all
sortBystringSort order: impressions_desc, impressions_asc, start_date_desc, start_date_asc. Applies to all input modes. Default: impressions_desc
limitPerSourceintegerMaximum ads to collect per source URL. Default: 10
scrapeAdDetailsbooleanInclude full creative snapshot in output. Default: true
includeRawDatabooleanAttach the full raw Facebook API response to each row. Default: false
proxyConfigurationobjectOptional proxy settings

Using Facebook page URLs

If you provide a Facebook page URL (e.g. https://www.facebook.com/Nike), the scraper resolves the numeric page ID and builds the Ad Library URL automatically using the scrapePageAds.* options:

{
"urls": [
{ "url": "https://www.facebook.com/Nike" },
{ "url": "https://www.facebook.com/Adidas" }
],
"limitPerSource": 30,
"activeStatus": "active",
"country": "US",
"sortBy": "impressions_desc"
}

Output

Each dataset row represents one creative card. A single-image or video ad produces one row. A carousel ad produces one row per card (after deduplication).

{
"adArchiveID": "914351827969140",
"adUrl": "https://www.facebook.com/ads/library/?id=914351827969140",
"cardIndex": 0,
"pageName": "LinkedIn",
"pageUrl": "https://www.facebook.com/LinkedIn",
"pageID": "6191007822",
"isActive": true,
"isDCO": false,
"startDate": "2024-07-03",
"endDate": "2026-03-27",
"format": "video",
"headline": "LinkedIn Ads",
"body": "Grow your business with LinkedIn Ads.",
"cta": "Learn More",
"destinationUrl": "https://business.linkedin.com/marketing-solutions",
"imageUrl": null,
"videoUrl": "https://video.fbcdn.net/..."
}
FieldDescription
adArchiveIDUnique Facebook ad archive ID
adUrlDirect link to this ad in the Ad Library
cardIndex0-based position within the ad (always 0 for non-carousel ads)
pageNameAdvertiser page name
pageUrlFacebook page URL of the advertiser
pageIDNumeric Facebook page ID
isActiveWhether the ad is currently running
isDCODynamic Creative Optimization — ad uses template variables
startDateWhen the ad started running (YYYY-MM-DD)
endDateWhen the ad stopped running (YYYY-MM-DD), or null if still active
formatimage, video, or carousel
headlineCard headline / title
bodyAd body text
ctaCall-to-action button label (e.g. Learn More, Shop Now)
destinationUrlLanding page URL
imageUrlCard image URL (resized version preferred)
videoUrlCard video URL (HD version preferred)
rawDataFull raw Facebook API response (only present when includeRawData: true)

How it works

Facebook's Ad Library server-side renders ad data as a JSON blob embedded in the initial HTML response (a Relay store dump containing search_results_connection). The scraper:

  1. Makes a plain HTTP request to the Ad Library URL with browser-like headers
  2. If Facebook returns a 403 challenge page, solves it via the /__rd_verify endpoint and retries
  3. Extracts the embedded JSON blob using balanced-brace parsing
  4. Normalises fields into the output schema above, one row per creative card
  5. Reads the page_info.end_cursor from the response and enqueues the next page URL (?after=<cursor>) if more ads are needed
  6. Repeats until limitPerSource is reached or no more pages exist

For Facebook page URLs, the scraper first visits the page to extract its numeric ID, then builds and processes the corresponding Ad Library URL.


Proxy

The Facebook Ad Library is a public transparency tool — no proxy is required in most cases. The actor runs cleanly on Apify's infrastructure without additional proxy configuration.

If you encounter blocks or CAPTCHAs (more likely with very high volumes or repeated runs from the same IP), you can optionally add residential proxies:

"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}