---
title: "How to Scrape the Facebook Ads Library | Scrape.ly"
description: "Use a Facebook Ads Library scraper to export a brand's Meta ads: copy, creatives, CTA, landing page and dates. A real run, its cost, API and MCP code."
url: https://scrape.ly/blog/scrape-facebook-ads-library
markdown: https://scrape.ly/blog/scrape-facebook-ads-library.md
---

[Tutorials](https://scrape.ly/blog/category/tutorials.md)

# How to Scrape the Facebook Ads Library (Meta Ad Library)

Scrape the Facebook Ads Library for any brand, page or keyword: ad copy, creatives, call to action, landing page, start date, platforms and the Ad Library link. A real run on Nike's active US ads, its exact cost, and code for curl, Python, Node.js and AI agents.

[Echofield Actor publisher on the Scrape.ly Store](https://scrape.ly/blog/author/echofield.md)

- Published

  Oct 23, 2026

- Reading time

  9 min read

![Pixel-art robot with an orange >\_ on its terminal head pulls an ad card with an image and a blue button out of a monitor showing the blue Facebook logo above two more ad cards, and drops it into a crate](https://scrape.ly/media/scrape-facebook-ads-library.png?w=1080)

To scrape the Facebook Ads Library, point a Facebook Ads Library scraper at a Facebook page, a page name or an Ad Library search link, and save each ad as a row: the ad copy, creative, call to action, landing page, start date, platforms and its public Ad Library link. The fastest way is the Facebook Ad Library Scraper on Scrape.ly, which reads the public library without a Facebook login, Meta app or access token, at $0.05 per 1,000 ads.

This guide covers the no-code steps, the API (curl, Python, Node.js and AI agents over MCP), the cost, the limits that come from Facebook itself, and what Meta's official Ad Library API does and doesn't cover. Everything below comes from a real run on 23 October 2026 on Nike's active US ads: the exact input, output, log and charge.

## What data you can get from the Meta Ad Library

The [Facebook Ad Library Scraper](https://scrape.ly/store/echofield/facebook-ads-library-scraper.md) writes one row per ad. These are the fields you'll use most:

| Field                                                                             | What it holds                                                                                             |
| --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `ad_archive_id`, `ad_library_url`                                                 | The Ad Library ID and the public page for that ad                                                         |
| `page_name`, `page_id`                                                            | The Facebook page that ran the ad                                                                         |
| `is_active`, `start_date_formatted`, `end_date_formatted`                         | Whether the ad is running, and its dates in UTC                                                           |
| `publisher_platform`                                                              | Where it ran: Facebook, Instagram, Audience Network, Messenger, WhatsApp, Threads                         |
| `snapshot.body.text`, `snapshot.title`, `snapshot.cta_text`                       | Ad copy, headline and call to action                                                                      |
| `snapshot.link_url`, `snapshot.caption`                                           | Landing page and the domain shown on the ad                                                               |
| `snapshot.display_format`, `snapshot.cards`, `snapshot.images`, `snapshot.videos` | Format (image, video, carousel, catalog) and every card, image and video URL                              |
| `snapshot.page_like_count`, `snapshot.page_categories`                            | The page's like count and categories                                                                      |
| `pageInfo`                                                                        | Page transparency: creation date, confirmed owner, whether it's running ads                               |
| `spend`, `reach_estimate`, `aaa_info`                                             | Spend and reach (when Meta publishes them) and EU reach and payer details (with **Scrape ad details** on) |

Facebook fills `spend` and `reach_estimate` mainly for ads about social issues, elections or politics, so ordinary commercial ads leave them empty. A URL that can't be read becomes its own row with `error` and `errorCode`, and error rows are not charged.

## How to scrape the Facebook Ads Library without code

1. Open the [Facebook Ad Library Scraper](https://scrape.ly/store/echofield/facebook-ads-library-scraper.md) in the Scrape.ly Store.
2. Pick a ready-made input. We used the preset [Nike's active US ads by reach, 10 ads](https://scrape.ly/store/echofield/facebook-ads-library-scraper/presets/page-url-filters.md). "Try this input" opens it in the console.
3. Swap in the brand you're researching. This is the exact input of our run:

```json
{
  "urls": [{ "url": "https://www.facebook.com/nike" }],
  "count": 10,
  "scrapePageAds.activeStatus": "active",
  "scrapePageAds.countryCode": "US",
  "scrapePageAds.sortBy": "impressions_desc"
}
```

4. Click **Start**. Ten ads take a few seconds.
5. Export the ads as JSON, CSV, Excel or HTML.

The fields that matter most:

- `urls`: three ways in. A Facebook page URL (`https://www.facebook.com/nike`), a bare page slug (`nike`), or an Ad Library search link copied from your browser, which keeps its country, keyword, status and media filters.
- `count`: ads to save across all URLs. Default 10. `limitPerSource` caps each URL.
- `scrapePageAds.activeStatus`, `scrapePageAds.countryCode`, `scrapePageAds.sortBy`, `scrapePageAds.period`: filters for page URLs: `active`/`inactive`/`all`, a two-letter country or `ALL`, `impressions_desc` or `most_recent`, and ads started in the last 24 hours, 7, 14 or 30 days.
- `scrapeAdDetails`: adds EU reach, payer and advertiser fields, one extra request per ad. The preset [Shoe ads in Germany with details, 5 ads](https://scrape.ly/store/echofield/facebook-ads-library-scraper/presets/library-search-de-details.md) shows it with a keyword search link.

Scrape.ly Store Facebook Ad Library Scraper Public Meta ads by page, page name or Ad Library search link: copy, creatives, CTA, landing page, dates and platforms. No login or token. $0.05 per 1,000 ads.

[Try it free](https://scrape.ly/store/echofield/facebook-ads-library-scraper.md) [Browse the Store](https://scrape.ly/store.md)

## Scrape the Facebook Ads Library with the API

Create an API token under **Settings → API & Integrations** and export it as `SCRAPELY_TOKEN`.

Our run finished in 6 seconds, so the synchronous endpoint fits: it starts the run, waits up to 45 seconds and returns the ads as a JSON array. Add `?format=csv` for CSV.

```shell
curl -X POST "https://api.scrape.ly/v2/actors/echofield~facebook-ads-library-scraper/run-sync-get-dataset-items"
  -H "Authorization: Bearer $SCRAPELY_TOKEN"
  -H "Content-Type: application/json"
  -d '{"urls": [{"url": "https://www.facebook.com/nike"}], "count": 10, "scrapePageAds.activeStatus": "active", "scrapePageAds.countryCode": "US"}'
```

If you add many URLs or switch on ad details and a run takes longer than 45 seconds, the call answers `408` while the run keeps going. Don't call it again (that starts a second run); use a client instead.

Python (`pip install scrapely-client-python`). This example compares what three brands are running in the US right now, by format and landing domain:

```python
import os
from collections import Counter
from urllib.parse import urlparse
from scrapely_client import ScrapelyClient

client = ScrapelyClient(os.environ["SCRAPELY_TOKEN"], api_url="https://api.scrape.ly")

run = client.actor("echofield/facebook-ads-library-scraper").call(
    run_input={
        "urls": [{"url": "nike"}, {"url": "adidas"}, {"url": "puma"}],
        "count": 90,
        "limitPerSource": 30,
        "scrapePageAds.activeStatus": "active",
        "scrapePageAds.countryCode": "US",
    }
)
print(run.status)  # SUCCEEDED, FAILED, ABORTED or TIMED-OUT
ads = [a for a in client.dataset(run.default_dataset_id).iterate_items() if not a.get("error")]
for page, n in Counter(a["page_name"] for a in ads).items():
    mine = [a for a in ads if a["page_name"] == page]
    formats = Counter(a["snapshot"].get("display_format") for a in mine)
    domains = Counter(urlparse(a["snapshot"].get("link_url") or "").netloc for a in mine)
    print(page, n, dict(formats), domains.most_common(2))
```

Node.js (`npm install scrapely-client`):

```javascript
import { ScrapelyClient } from 'scrapely-client';

const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN, baseUrl: 'https://api.scrape.ly' });

const run = await client.actor('echofield/facebook-ads-library-scraper').call({
  urls: [{ url: 'https://www.facebook.com/nike' }],
  count: 10,
  'scrapePageAds.activeStatus': 'active',
  'scrapePageAds.countryCode': 'US',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((a) => [a.start_date_formatted, a.snapshot.cta_text, a.ad_library_url]));
```

For AI agents, add the Scrape.ly MCP server. In Cursor, put this in `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "scrapely": {
      "url": "https://api.scrape.ly/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}
```

In Claude Code, run `claude mcp add --transport http scrapely https://api.scrape.ly/mcp` and sign in with `/mcp`. Then ask: "Use scrapely to run echofield/facebook-ads-library-scraper on Nike, Adidas and Puma, 30 active US ads each, and summarize which offers and calls to action each brand is pushing." See the [MCP docs](https://scrape.ly/docs/mcp.md) for other clients. The [Facebook Ads Library API](https://scrape.ly/api/facebook-ads-library-api.md) page shows the same Actor as a ready API product.

## A real run: Nike's active US ads

We ran the "Nike's active US ads by reach, 10 ads" preset on 23 October 2026. It returned 10 ads in 6 seconds and was charged $0.0015. The first five rows:

| Library ID        | Started    | Platforms           | Format | Ad text                                              | First product card  |
| ----------------- | ---------- | ------------------- | ------ | ---------------------------------------------------- | ------------------- |
| 1016451784037642  | 2025-06-20 | Facebook, Instagram | DPA    | Get the gear that goes hard on and off the field.    | Nike Air Monarch IV |
| 1277433457899494  | 2026-10-19 | Facebook, Instagram | DPA    | Run through summer with gear that can take the heat. | Nike Tempo Shorts   |
| 1849003099878021  | 2026-10-19 | Facebook, Instagram | DPA    | Get the gear not afraid to put in the work.          | Nike Air Monarch IV |
| 29548096774776782 | 2026-10-19 | Facebook, Instagram | DPA    | Get the gear that goes hard on and off the field.    | Nike Air Monarch IV |
| 3286219464896203  | 2026-10-19 | Facebook, Instagram | DPA    | Run through summer with gear that can take the heat. | Nike Air Monarch IV |

Nike is a business named in the input on purpose, so nothing here needed masking. What the full ten show:

- **Catalog ads, not one-off creatives.** All ten had `display_format: DPA`, a headline template (`{{product.name}}`) filled from a product feed, and six product cards each: 50 of the 60 cards showed Nike Air Monarch IV shoes and the other 10 Nike Tempo Shorts, every card with its own product URL on nike.com.
- **A fresh batch plus one long runner.** Nine ads started on 19 October 2026; the top one had been running since 20 June 2025. An ad that stays active for 16 months is worth a closer look.
- **Four lines of copy, rotated.** The ten ads used four distinct body texts ("Get the gear not afraid to put in the work." appeared four times), all with **Shop now** and all on Facebook and Instagram only.
- **Page transparency comes along.** `pageInfo` reported "NIKE, Inc. is responsible for this Page," a page created on 21 May 2008, and the page currently running ads; `snapshot.page_like_count` was 39,497,958.
- **No spend or reach.** As expected for commercial ads in the US, `spend` and `reach_estimate` were empty.

The run's log, without the platform's start-up lines:

```plaintext
20261023T03:01:55.528Z [Scrapely] Container started (setup 1.8 s)
20261023T03:01:56.788Z [scrapely.proxy_configuration] INFO  Platform proxy access check succeeded.
20261023T03:01:59.368Z [scrapely.actor] INFO  Saved 10 ads
20261023T03:02:00.145Z [Scrapely] Container state: status=exited exitCode=0 oomKilled=false
```

2.6 seconds from the proxy check to ten saved ads, on the default datacenter proxy, with no browser and no Facebook account.

## What it costs

The Actor charges one event, $0.00005 per ad saved, which is $0.05 per 1,000 ads. Platform usage (compute and proxy) is billed on top, and for this Actor it's the larger part of a small bill.

For our run: 10 ads × $0.00005 = $0.0005 in ad fees. The run was charged $0.0015 in total, because it also used $0.0008 of compute and $0.0001 of datacenter proxy traffic. Error rows for URLs that can't be read are not charged.

A weekly sweep of 20 competitors at 30 ads each is 600 ads, or $0.03 in ad fees plus usage. The Free plan's $5 of monthly credit covers that many times over. Set **Max cost per run** in the run options if you want a hard cap.

## What to watch out for

- **About 30 ads per URL.** Facebook shows logged-out visitors only the first page of results, about 30 ads per search or page. The run status says when a URL returned fewer than you asked for. For more, add narrower URLs in the same run: one per country, media type or date range.
- **Spend and reach are political-ad fields.** Meta publishes spend ranges and reach for ads about social issues, elections or politics. For commercial ads, use start dates, active status and how many variants a brand runs as your signals.
- **EU details cost one request per ad.** `scrapeAdDetails` adds EU reach, payer and advertiser fields, which is useful for ads delivered in the EU and slower for big runs.
- **Media links expire.** Image and video URLs on Facebook's CDN are signed and stop working after a while. Download the creatives you want to keep soon after the run.
- **Templates in catalog ads.** Headlines like `{{product.name}}` are filled per viewer; read the product names from `snapshot.cards`.
- **Country codes.** An unknown country code in the page filters stops the run with a clear message, and an unknown country inside a pasted link falls back to all countries.

## Is it legal to scrape the Facebook Ads Library?

The Ad Library is public by design: Meta built it so anyone can see who is advertising and what they run, and the Actor reads it without logging in. That doesn't settle every question. [Meta's Terms of Service](https://www.facebook.com/terms.php) (effective January 1, 2025) say: "You may not access or collect data from our Products using automated means (without our prior permission)", and they add that this applies "regardless of whether such automated access or collection is undertaken while logged-in to a Facebook account."

Courts have looked at logged-out scraping of Meta's public pages. In [Meta Platforms v. Bright Data](https://www.govinfo.gov/app/details/USCOURTS-cand-3_23-cv-00077/USCOURTS-cand-3_23-cv-00077-7) (N.D. Cal., January 23, 2024), Judge Edward Chen granted Bright Data summary judgment on Meta's breach-of-contract claims, holding that the Facebook and Instagram terms at issue did not prohibit scraping publicly available data while logged off. That ruling concerned those terms and those facts; it isn't a general permission.

Advertisers are mostly businesses, but ad creatives can show people, and political ads name candidates and funders. Treat any personal data you collect under the GDPR and the CCPA, store only what you need, and keep creatives for analysis rather than republishing them. For a wider view, see our guide on [whether web scraping is legal](https://scrape.ly/blog/is-web-scraping-legal.md). This is not legal advice: if ad data feeds a product, ask a lawyer about your case.

## Why Scrape.ly for Meta ad research

- **Commercial ads outside the EU.** Meta's [Ad Library API](https://www.facebook.com/ads/library/api/) covers "Ads about social issues, election or politics that were delivered anywhere in the world during the past 7 years" and "Ads of any type that were delivered to the United Kingdom (UK) or European Union during the past year." Its own parameter notes say ads that did not reach the EU "will only return if they are about social issues, elections or politics." Nike's US shopping ads from our run fall outside that; the public library shows them, and so does the Actor.
- **No identity check or app.** The API's first step is to confirm your identity and location at Facebook.com/ID, which "can take a few days," then create a Meta for Developers account and an app. The Actor needs a Scrape.ly token.
- **Fractions of a cent.** $0.05 per 1,000 ads in fees, and our 10-ad run cost $0.0015 all in.
- **Built for monitoring.** Schedule a daily run per competitor with `scrapePageAds.period: "last24h"`, and send new ads to Slack, email or Google Sheets with [automations](https://scrape.ly/docs/automations.md). For the bigger picture across platforms, see our guide to [social media scraping](https://scrape.ly/blog/social-media-scraping.md).

## FAQ

### Is there an official Facebook Ads Library API?

Yes, Meta offers the Ad Library API, but it covers ads about social issues, elections or politics worldwide and ads of any type delivered to the UK or EU, and it requires identity confirmation and a developer app. For commercial ads in other countries, scrape the public library.

### Can I scrape Facebook ads by keyword?

Yes. Search the Ad Library in your browser with a keyword, country and filters, copy the link, and paste it into `urls`. The Actor keeps the filters in the link, as in the German shoe-ads preset.

### How many ads can I scrape per brand?

Facebook shows logged-out visitors about 30 ads per page or search. To collect more for one brand, add several URLs that split the results, for example one per country or one per media type, and set `limitPerSource`.

### Can I see how much a competitor spends on Facebook ads?

Only for ads about social issues, elections or politics, where Meta publishes spend ranges. For commercial ads, the library does not show spend; how long an ad stays active and how many variants a brand runs are the practical signals.

### Can I download the images and videos?

Every row lists the creative's image and video URLs inside `snapshot`. They are signed links that expire, so download the files you want to keep soon after the run.

### Do I need a Facebook account?

No. The Actor reads the public Ad Library without logging in, on its built-in datacenter proxy. You need only a Scrape.ly account; the Free plan includes $5 of monthly credit.

Scrape.ly Store Scrape the Meta Ad Library Run the Nike preset as-is, or paste any brand's page, page name or Ad Library search link. Copy, creatives, CTA and dates at $0.05 per 1,000 ads.

[Try it free](https://scrape.ly/store/echofield/facebook-ads-library-scraper.md) [Browse the Store](https://scrape.ly/store.md)

About the author

[Echofield](https://scrape.ly/blog/author/echofield.md) Actor publisher on the Scrape.ly Store

Posts, reels, comments and creator stats, from TikTok and YouTube to Weibo and Bluesky. For social listening, creator research and catching a trend while it is still small. A Scrapely studio.

- [Website](https://scrape.ly/users/echofield.md)

Keep reading

## More in Tutorials

- [![Pixel-art robot with a terminal for a head pulling a place card out of a Google Maps pin standing on a folded map, with a crate of collected place cards beside it](https://scrape.ly/media/how-to-scrape-google-maps.png?w=750)](https://scrape.ly/blog/how-to-scrape-google-maps.md)
  ### [How to Scrape Google Maps: Places, Ratings, Phones and Websites](https://scrape.ly/blog/how-to-scrape-google-maps.md)
  [Scrape Google Maps places for any search term and city, with no code or with one API call. A real run, its output, its log and its exact cost, plus the limits and the legal side.](https://scrape.ly/blog/how-to-scrape-google-maps.md)
- [![Pixel-art robot with an orange >\_ on its terminal head pulls a parcel from a stack of cardboard boxes marked with the Amazon smile logo and loads it into a crate](https://scrape.ly/media/how-to-scrape-amazon.png?w=750)](https://scrape.ly/blog/how-to-scrape-amazon.md)
  ### [How to Scrape Amazon: Prices, ASINs and Ratings From Search or Product URLs](https://scrape.ly/blog/how-to-scrape-amazon.md)
  [Paste an Amazon search or product URL into a ready-made Actor and get one row per product with price, ASIN, rating and review count. This guide covers the no-code steps, the API, ZIP code pricing, a real run and its cost.](https://scrape.ly/blog/how-to-scrape-amazon.md)
- [![Pixel-art robot with a grey terminal head showing an orange >\_ pulls a search result card out of a browser window showing the Google G logo and drops it into a crate](https://scrape.ly/media/scrape-google-search-results.png?w=750)](https://scrape.ly/blog/scrape-google-search-results.md)
  ### [How to Scrape Google Search Results: Rankings, People Also Ask and Related Searches](https://scrape.ly/blog/scrape-google-search-results.md)
  [Scrape Google search results by query and country and get each results page as JSON: organic results with positions, People Also Ask and related searches. Run it without code or from Python, with a real run, the cost per page and Google's terms.](https://scrape.ly/blog/scrape-google-search-results.md)

## The internet is full of data. Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

[Get Started Free](https://my.scrape.ly/register) [Chat with Support](mailto:support@scrape.ly?subject=Question%20about%20Scrape.ly\&body=Hi%2C%20I%20have%20a%20question%20about%20Scrape.ly.)

No credit card. No setup calls.
