Facebook Ad Library Scraper
Pricing
$0.50 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
34
Total users
10
Monthly active users
5 days ago
Last modified
Categories
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.
Simple mode (recommended)
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
| Field | Type | Description |
|---|---|---|
keyword | string | Search keyword. The actor builds the Ad Library URL for you. Use this OR urls, not both. |
urls | array | Pre-built Ad Library search URLs or Facebook page URLs. Use this OR keyword, not both. |
country | string | ISO 3166-1 alpha-2 code (US, GB) or ALL. Applies to all input modes. Default: ALL |
activeStatus | string | Filter by ad status: all, active, inactive. Applies to all input modes. Default: all |
mediaType | string | Filter by media type: all, image, video, meme, none. Applies to all input modes. Default: all |
sortBy | string | Sort order: impressions_desc, impressions_asc, start_date_desc, start_date_asc. Applies to all input modes. Default: impressions_desc |
limitPerSource | integer | Maximum ads to collect per source URL. Default: 10 |
scrapeAdDetails | boolean | Include full creative snapshot in output. Default: true |
includeRawData | boolean | Attach the full raw Facebook API response to each row. Default: false |
proxyConfiguration | object | Optional 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/..."}
| Field | Description |
|---|---|
adArchiveID | Unique Facebook ad archive ID |
adUrl | Direct link to this ad in the Ad Library |
cardIndex | 0-based position within the ad (always 0 for non-carousel ads) |
pageName | Advertiser page name |
pageUrl | Facebook page URL of the advertiser |
pageID | Numeric Facebook page ID |
isActive | Whether the ad is currently running |
isDCO | Dynamic Creative Optimization — ad uses template variables |
startDate | When the ad started running (YYYY-MM-DD) |
endDate | When the ad stopped running (YYYY-MM-DD), or null if still active |
format | image, video, or carousel |
headline | Card headline / title |
body | Ad body text |
cta | Call-to-action button label (e.g. Learn More, Shop Now) |
destinationUrl | Landing page URL |
imageUrl | Card image URL (resized version preferred) |
videoUrl | Card video URL (HD version preferred) |
rawData | Full 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:
- Makes a plain HTTP request to the Ad Library URL with browser-like headers
- If Facebook returns a
403challenge page, solves it via the/__rd_verifyendpoint and retries - Extracts the embedded JSON blob using balanced-brace parsing
- Normalises fields into the output schema above, one row per creative card
- Reads the
page_info.end_cursorfrom the response and enqueues the next page URL (?after=<cursor>) if more ads are needed - Repeats until
limitPerSourceis 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"]}