# Meta Facebook Ads Library Scraper (`confidential_gnat/facebook-ads-library-scraper`) Actor

Scrape ads from the Facebook (Meta) Ad Library by keyword, advertiser page, ad ID or URL: ad copy, images, videos, dates, platforms, spend and impressions ranges, EU reach and targeting. Filters for country, status, media and dates. Cache for new ads only. Export JSON, CSV or Excel.

- **URL**: https://apify.com/confidential_gnat/facebook-ads-library-scraper.md
- **Developed by:** [ActorFlow](https://apify.com/confidential_gnat) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Facebook Ads Library (Meta Ad Library) Scraper - Ads by Keyword or Page

**Scrape ads from the Facebook Ads Library (facebook.com/ads/library)** by keyword, advertiser page, ad ID or Ad Library link: ad copy, images, videos, carousel cards, dates, platforms and call to action, plus spend, impressions, **EU reach and targeting** where the library shows them. Type a brand, press Start, and export **JSON, CSV or Excel**, or call it as an **API**.

**Target website:** [facebook.com/ads/library](https://www.facebook.com/ads/library)

![Meta Facebook Ads Library Scraper cover: every Meta ad with EU targeting included, only new ads](https://i.postimg.cc/15WG8Z73/Gemini-Generated-Image-sruwqbsruwqbsruw.jpg)

### ✨ Features of this Facebook Ads Library scraper

- **Ad extraction** — ad text, headline, link, call to action, images, videos (HD and SD), carousel cards, display format, start and end dates, active status and platforms (Facebook, Instagram, Messenger, Audience Network, Threads).
- **Four ways to search** — keywords, advertiser pages (page ID, page URL or just the page name), single ad IDs, or any Ad Library link copied from your browser with its filters.
- **Advertiser details** — page name, URL, likes, categories, and with details on also Instagram account and followers, verification, about text and lifetime spend.
- **Spend, impressions and reach** — spend and impression ranges for political and issue ads, who paid for the ad, and for ads shown in the EU the targeted age, gender, locations and reach breakdown.
- **Filters** — country (one, several or all), active or inactive, ad category, image, video or meme, platform, language, start date range, exact phrase, and sort by impressions.
- **Count only mode** — one row per search with the number of ads the library shows, for tracking how many ads a brand runs.
- **Pagination support** — the library is scrolled like a visitor, and searches too big to scroll through are split automatically by country, date and filters.
- **Cache for new ads only** — scheduled runs return only ads not seen before.
- **Proxy support** — runs work from any Apify proxy.

### 🚀 How to scrape Facebook ads in 5 steps

1. [Sign up](https://apify.com/sign-up) for a free Apify account — includes **$5 monthly credit**.
2. Open the actor page and click **Try for free**.
3. Add a **keyword** such as a brand name, or an **advertiser page**.
4. Click **Start** and wait for the run to complete.
5. Download results from the **Output** tab in JSON, CSV, or Excel format.

You can also run this actor via the [Apify API](https://docs.apify.com/api/v2) or integrate it directly into your workflows using [Zapier](https://zapier.com/apps/apify), [Make](https://www.make.com/), or [n8n](https://n8n.io/).

### 💰 Pricing for the Facebook Ads Library scraper

This actor uses **pay-per-result** billing: you pay for each ad saved. Ads skipped by the cache are not charged.

- New Apify accounts include **$5 of free monthly credit**.
- Turning on ad details opens a panel per ad and makes runs slower.

### 🖼️ Facebook Ads Library scraper input screenshot

![Meta Facebook Ads Library Scraper input form in Apify Console: keywords, country, ad status, media type, max ads per search, cache project name and open ad details](https://i.postimg.cc/kXMNM5cZ/Gemini-Generated-Image-yet7p3yet7p3yet7.jpg)

The numbers match the input fields below:

1. **Keywords**: brands or topics to search for in the Ad Library.
2. **Country**: the country whose ads are searched.
3. **Ad status**: active ads, inactive ads or all ads.
4. **Media type**: all ads, or only images, videos or memes.
5. **Max ads per search**: the ad limit for each search.
6. **Cache project name**: reuse the same name on each run to get only new ads.
7. **Open ad details (page info, EU reach and targeting)**: adds the advertiser's page info and, for EU ads, targeting and reach.

### 🔧 Facebook Ads Library scraper input configuration

| Field | Type | Required | Default | Description |
| ----- | ---- | -------- | ------- | ----------- |
| Keywords | array | — | `["nike"]` | Search by brand or phrase. One search per keyword. |
| Advertiser pages | array | — | — | Page IDs, Facebook page URLs or page names. Lists every ad of the advertiser. |
| Ad Library URLs | array | — | — | Ad Library search, advertiser or single ad links; their filters are kept. |
| Ad IDs | array | — | — | Library IDs of single ads. |
| Country | string | — | `US` | Country code, several separated by commas, or `ALL`. One search per country. |
| Ad status | string | — | `active` | `active`, `inactive` or `all`. |
| Ad category | string | — | `all` | All ads, political and issue, housing, employment or credit ads. |
| Media type | string | — | `all` | `all`, `image`, `video`, `meme` or `none`. |
| Platforms | array | — | — | Only ads shown on these platforms. |
| Ad languages | array | — | — | Language codes of the ad text, like `en`, `de`. |
| Date range | string | — | — | Ads started in the last 24 hours, 7, 14 or 30 days. |
| Started after / before | string | — | — | Start date window, `YYYY-MM-DD`. |
| Match exact phrase | boolean | — | `false` | Search the keyword as one phrase. |
| Sort by | string | — | `relevance` | Relevance or impressions. |
| Only count the ads | boolean | — | `false` | One row per search with the total number of ads. |
| Max ads per search | integer | — | `5` | Limit for each keyword, page or URL. |
| Max ads in total | integer | — | — | Optional limit for the whole run. |
| Cache project name | string | — | — | Same name on each run returns only new ads. |
| Open ad details | boolean | — | `false` | Adds page info, payer and EU targeting and reach. |
| Proxy configuration | object | — | Residential | Proxy settings for the run. |

**Supported URL types:**

- `https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered`
- `https://www.facebook.com/ads/library/?view_all_page_id=15087023444&country=US&active_status=all`
- `https://www.facebook.com/ads/library/?id=1550534860016399`

### 📦 Facebook Ads Library scraper output data

Each row is one ad in JSON with the fields `adArchiveId`, `adUrl`, `collationId`, `collationCount`, `pageId`, `pageName`, `pageUrl`, `pageProfilePictureUrl`, `pageLikeCount`, `pageCategories`, `isActive`, `startDate`, `endDate`, `platforms`, `displayFormat`, `adText`, `title`, `linkDescription`, `caption`, `linkUrl`, `ctaText`, `ctaType`, `images`, `videos`, `videoPreviewImages`, `cards`, `paidForBy`, `categories`, `spend`, `currency`, `impressions`, `reachEstimate`, `targetedOrReachedCountries`, `pageAlias`, `pageIgUsername`, `pageIgFollowers`, `pageVerification`, `pageAbout`, `pageLifetimeSpend`, `payer`, `beneficiary`, `euTargetsEu`, `euTotalReach`, `euAgeMin`, `euAgeMax`, `euGender`, `euLocations`, `euReachBreakdown`, `detailsScraped`, `changeType`, `searchInput`, `totalAds` and `scrapedAt`. Fields that do not apply to an ad are `null`.

The dataset has 2 views: **Overview** (advertiser, dates, copy, format, link) and **Spend and reach** (payer, spend, impressions and EU reach for political and issue ads).

**Output at a glance:**

| Ad | Advertiser | Started | Active | Format | CTA | Platforms |
| -- | ---------- | ------- | ------ | ------ | --- | --------- |
| [1550534860016399](https://www.facebook.com/ads/library/?id=1550534860016399) | Perfect themes | 2026-05-19 | true | IMAGE | Install now | 5 |
| [962050096457659](https://www.facebook.com/ads/library/?id=962050096457659) | Depop | 2026-09-11 | true | IMAGE | Shop now | 3 |
| [8932462163548008](https://www.facebook.com/ads/library/?id=8932462163548008) | Shiekh Shoes | 2025-02-03 | true | DPA | Shop now | 4 |

**Sample output (raw JSON):**

```json
{
  "adArchiveId": "8932462163548008",
  "adUrl": "https://www.facebook.com/ads/library/?id=8932462163548008",
  "collationId": null,
  "collationCount": null,
  "pageId": "163762275750",
  "pageName": "Shiekh Shoes",
  "pageLikeCount": 83788,
  "pageCategories": ["Shoes"],
  "isActive": true,
  "startDate": "2025-02-03",
  "endDate": "2026-11-05",
  "platforms": ["FACEBOOK", "INSTAGRAM", "AUDIENCE_NETWORK", "MESSENGER"],
  "displayFormat": "DPA",
  "adText": "Sneakerhead Alert! Nike, Jordan, Adidas - Must-Have Drops!",
  "title": "{{product.name}}",
  "caption": "https://www.shiekh.com",
  "ctaText": "Shop now",
  "ctaType": "SHOP_NOW",
  "images": null,
  "videos": null,
  "cards": [
    {
      "title": "(td) true flight black/white",
      "text": "Sneakerhead Alert! Nike, Jordan, Adidas - Must-Have Drops!",
      "linkUrl": "https://www.shiekh.com/jordan-td-true-flight-black-white.html",
      "caption": "shiekh.com",
      "ctaText": "Shop Now",
      "imageUrl": "https://scontent.example.com/card1.jpg",
      "videoUrl": null
    }
  ],
  "paidForBy": null,
  "spend": null,
  "impressions": null,
  "pageAlias": "shiekhshoes",
  "pageIgUsername": "shiekh",
  "pageIgFollowers": 319016,
  "pageAbout": "Urban lifestyle retailer.",
  "detailsScraped": true,
  "changeType": null,
  "searchInput": "nike",
  "scrapedAt": "2026-11-05T14:49:01.932Z"
}
```

### 🔁 Scrape only new Facebook ads with the cache

Set the same **Cache project name** on every scheduled run. Ads already saved under that name are skipped, not charged and not counted towards **Max ads per search**, and each new ad gets `changeType: "new"`. Different names keep separate caches, so you can follow one brand per project. Use an Apify Schedule to run it daily or weekly.

### 🐍 How to scrape Facebook ads with Python, JavaScript or the API

Run the actor programmatically with the official Apify clients. Replace `<YOUR_API_TOKEN>` with the token from your [Apify Console](https://console.apify.com/account/integrations).

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("confidential_gnat/facebook-ads-library-scraper").call(run_input={
    "keywords": ["nike"],
    "country": "US",
    "status": "active",
    "maxItems": 50,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript** (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('confidential_gnat/facebook-ads-library-scraper').call({
    keywords: ['nike'],
    country: 'US',
    status: 'active',
    maxItems: 50,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**cURL** — start a run and wait for the dataset:

```bash
curl -X POST "https://api.apify.com/v2/acts/confidential_gnat~facebook-ads-library-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["nike"], "country": "US", "status": "active", "maxItems": 50}'
```

### 💡 What you can use Facebook Ads Library data for

- Competitor ad monitoring: see every creative, offer and call to action a rival runs.
- Creative research: collect images, videos and carousels for a niche to find what works.
- Political and issue ad tracking: spend, impressions and who paid for the ad.
- EU ad transparency research: targeting, age, gender and reach by country.
- Ad volume tracking over time with the count only mode.

Marketers, agencies, e-commerce brands, journalists and researchers use this data across advertising, politics, retail and media.

### ⚠️ Limitations of the Facebook Ads Library scraper

- **Public data only** — the actor sees what the Ad Library shows to a visitor who is not logged in.
- **Spend and impressions** — shown by the library only for political and issue ads; targeting and reach only for ads shown in the EU.
- **Speed** — ads load in groups of about 10 per scroll, so large runs take time, and opening ad details makes them slower.
- **Very big searches** — the library stops after a few hundred ads per search; the actor splits big searches into narrower ones, but heavy filters work best.

### ❓ Facebook Ads Library scraper FAQ

#### Can I scrape the Facebook Ads Library legally?

The actor only collects ads that the Meta Ad Library shows publicly, without logging in. Scraping publicly available data is generally considered lawful (see *hiQ Labs v. LinkedIn*), but you are responsible for following Meta's terms and applicable laws such as GDPR when you use the data.

#### What data does the Facebook Ads Library scraper return?

Ad copy, headline, link, call to action, images, videos, carousel cards, dates, status, platforms and the advertiser page. With **Open ad details** it adds the advertiser's Instagram account, about text, lifetime spend, payer and EU targeting and reach.

#### How many ads can I scrape from one search?

**Max ads per search** applies to each keyword, page or URL, and **Max ads in total** limits the whole run. The library scrolls a few hundred ads at a time, so bigger searches are split into narrower ones by date, country and filters.

#### Do I need a proxy to scrape the Facebook Ads Library?

The input defaults to residential proxies, which work reliably. Runs also work without a proxy or with datacenter proxies, though results can vary.

#### How do I scrape the Facebook Ads Library with Python?

Use the Python example above, then iterate over the dataset items.

#### Can I run this Facebook ads scraper on a schedule?

Yes, with Apify Schedules. Add a **Cache project name** and every run returns only ads not seen before under that name.

#### What output formats are supported?

JSON, CSV, Excel, XML and RSS, either from the **Output** tab or through the Apify API.

#### Why do some ads have no spend or impressions?

The Ad Library publishes spend and impression ranges only for political and issue ads, and targeting only for ads delivered in the EU, so those fields are `null` for other ads.

### 🔗 Relevant actors for Facebook ads data

| Scraper | Description |
| ------- | ----------- |
| [Google Ads Transparency Center Scraper](https://apify.com/confidential_gnat/google-ads-transparency-scraper) | Scrape ads from the Google Ads Transparency Center by advertiser or domain. |
| [TikTok Ad Library Scraper](https://apify.com/confidential_gnat/tiktok-ads-scraper) | Scrape ads from the TikTok Ad Library by keyword or advertiser. |
| [Facebook Events Scraper](https://apify.com/confidential_gnat/facebook-events-scraper) | Scrape public Facebook events by keyword, location and date, no login. |

### 🔗 Other actors you may find useful

| Scraper | Description |
| ------- | ----------- |
| [Kiwi.com Flight Scraper](https://apify.com/confidential_gnat/kiwi-flight-scraper) | Scrapes flight prices and routes from Kiwi.com. |
| [Total Wine Scraper](https://apify.com/confidential_gnat/totalwine-scraper) | Scrape Total Wine & More products, prices and stock. |
| [Carousell Products Scraper](https://apify.com/confidential_gnat/carousell-products-scraper) | Scrape Carousell listings with prices and seller details. |
| [WHOIS Domain Lookup Scraper](https://apify.com/confidential_gnat/whois-com) | Bulk WHOIS lookups for domain owners and dates. |
| [Incidecoder Scraper](https://apify.com/confidential_gnat/incidecoder-scraper) | Scrapes skincare products and ingredient analysis. |

### 💬 Support & contact

If you encounter any issues or have questions, please [open an issue](https://apify.com/confidential_gnat/facebook-ads-library-scraper/issues/open).

You can also find more of our actors on the [Actor Flow](https://apify.com/confidential_gnat) page.

# Actor input Schema

## `keywords` (type: `array`):

Search the Ad Library by keyword, brand or phrase. One search is run per keyword. Example: nike

## `country` (type: `string`):

Two-letter country code (US, GB, DE, FR, BR, IN...), several codes separated by commas (US, GB), or ALL for every country. One search is run per country.

## `maxItems` (type: `integer`):

Maximum ads saved for each keyword, advertiser page or URL. Searches too big to scroll through are split into narrower ones automatically.

## `cacheProjectName` (type: `string`):

Use the same name on each scheduled run to get only new ads. Ads already saved under that name are skipped, not charged and not counted towards Max ads per search. Each record gets changeType: new. Leave empty to turn the cache off.

## `pages` (type: `array`):

List every ad of an advertiser. Use Facebook page IDs, Facebook page URLs or page names. Example: 15087023444 or https://www.facebook.com/nike

## `startUrls` (type: `array`):

Ad Library search pages, advertiser views or single ad pages copied from the browser. Their filters are kept. Example: https://www.facebook.com/ads/library/?active_status=active\&ad_type=all\&country=US\&q=nike

## `adIds` (type: `array`):

Library IDs of single ads to load, like 1550534860016399.

## `status` (type: `string`):

Which ads to include.

## `adType` (type: `string`):

All ads, or the categories that carry spend and audience details.

## `mediaType` (type: `string`):

Only ads with this kind of media.

## `platforms` (type: `array`):

Only ads shown on these platforms. Leave empty for all.

## `languages` (type: `array`):

Two-letter language codes of the ad text, like en, de, es. Leave empty for all languages.

## `dateRange` (type: `string`):

Only ads that started in this period. Ignored when Started after is set.

## `startDate` (type: `string`):

Only ads that started running on or after this day (YYYY-MM-DD).

## `endDate` (type: `string`):

Only ads that started running on or before this day (YYYY-MM-DD).

## `exactPhrase` (type: `boolean`):

Search the keyword as one exact phrase instead of any of its words.

## `sortBy` (type: `string`):

Most relevant first, or most impressions first (impression ranges are shown for political and issue ads).

## `onlyTotal` (type: `boolean`):

Return one row per search with the number of ads the library shows for it (up to 50,000), without reading the ads. Good for tracking how many ads a brand or advertiser runs.

## `maxTotalItems` (type: `integer`):

Optional limit for the whole run, on top of Max ads per search.

## `scrapeDetails` (type: `boolean`):

On: the details panel of every ad is opened to add the advertiser's page info (Instagram account, followers, about text, lifetime spend), who paid for the ad and, for ads shown in the EU, the targeting, total reach and the reach by age, gender and country. This is slower, about one extra click per ad. Off: only what the search results show.

## `proxyConfiguration` (type: `object`):

Proxy settings for the run. The default works for most searches.

## Actor input object example

```json
{
  "keywords": [
    "nike"
  ],
  "country": "US",
  "maxItems": 5,
  "status": "active",
  "adType": "all",
  "mediaType": "all",
  "exactPhrase": false,
  "sortBy": "relevance",
  "onlyTotal": false,
  "scrapeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "nike"
    ],
    "country": "US",
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("confidential_gnat/facebook-ads-library-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": ["nike"],
    "country": "US",
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("confidential_gnat/facebook-ads-library-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "nike"
  ],
  "country": "US",
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call confidential_gnat/facebook-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,confidential_gnat/facebook-ads-library-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/JKdJkgl53MgPZV5pK/builds/spCkGzAHuw88vTgnH/openapi.json
