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

Scrape the public Facebook Ad Library without logging in: ad copy, titles, images and videos, CTA buttons, landing page links, run dates, platforms and advertiser details, by keyword or advertiser page ID in any country.

- **URL**: https://apify.com/logical\_scrapers/facebook-ads-library-scraper.md
- **Developed by:** [Goldmine](https://apify.com/logical_scrapers) (community)
- **Categories:** Social media, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 ads

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 Scraper — competitor ad research from the Facebook ad library

![Facebook Ads Library Scraper](https://i.ibb.co/VWbPrYxJ/Screenshot-2026-09-20-at-4-42-20-PM.png)

This Facebook Ads Library scraper turns the public [Facebook Ad Library](https://www.facebook.com/ads/library/) into structured data. Search any keyword or advertiser page and scrape Facebook ads with their copy, headlines, images and videos, call-to-action buttons, landing page links, run dates and the platforms they ran on — no Facebook account, cookies or API key needed. Teams use it for competitor ad research, creative swipe files, ad monitoring and political ad transparency work.

Give it a keyword such as `nike`, an advertiser page ID, or an Ad Library URL pasted from your browser, and get every matching ad back as JSON, CSV or Excel.

***

### 🚀 Key Features

- 🔎 **Three ways to search** — keywords, numeric advertiser page IDs, or Ad Library URLs copied straight from the browser, with the country and filters in the URL respected
- 🧾 **Full ad creative** — ad text, headline, link caption, CTA button and type, landing page URL, display format, and every image and video in the ad
- 🏷️ **Advertiser details on every ad** — page name, page ID, page URL, profile picture, page categories and page likes
- 🗳️ **Political ad transparency** — spend range, impressions range, currency and funding byline on ads that disclose them
- 🎛️ **The Ad Library's own filters** — creative type (video, image, meme, text-only), the platforms an ad ran on, and a date window, on top of status and category
- 🌍 **Any Ad Library country** — set a two-letter country code, or one per start URL
- 📑 **Per-search limits** — `maxItems` caps results **per keyword, page ID or start URL**, not per run
- 🛡️ **No login** — public data only; runs on Apify residential proxies by default
- 📤 **Multiple export formats** — JSON, CSV, Excel, XML via the Apify dataset
- 🔁 **Schedulable runs** — watch a competitor's page daily and diff what changed

***

### ✅ What You Get Here

- 💵 **One charge per ad, and that is the whole bill.** No Actor start fee, and no second charge to unlock ad details, advertiser data or enrichment — every field in the table below comes with the ad at the same price.
- 🗳️ **Political spend and impressions in the same record.** Ads in the political and issue category arrive with their spend range, impressions range, currency and funding byline already attached, not behind a separate detail step.
- 🖼️ **The whole creative, not just the first frame.** Every image and video in the ad, including carousel cards and the extra images and videos Facebook attaches beyond the main creative.
- 🏢 **Advertiser context on every ad** — page name, page ID, page URL, profile picture, page categories and page likes — so you do not need a second pass over advertiser pages to make the export usable.
- 🧬 **Collation fields that tell repetition from variety.** `collationId` and `collationCount` show when one creative was run many times, so 40 rows of the same ad do not read as 40 different ads.
- 🤖 **Disclosure flags Facebook publishes but most exports drop** — `containsDigitalCreatedMedia` for AI-generated or digitally altered media, and `containsSensitiveContent`.
- 🎯 **Filters from a pasted URL are obeyed.** Paste an Ad Library URL with its country, status, category, media type, platforms or date window already set and the run returns exactly the ads that URL shows in your browser, from the first result to the last.
- 🔍 **Narrow the search before you pay for it.** Ask for videos only, Instagram placements only, or ads that ran in a given window, and only the matching ads are returned and charged — you do not pay for a broad pull that you then filter yourself.
- 📐 **`maxItems` counts per search, not per run**, so one run can pull 100 ads for each of ten keywords without you splitting it into ten runs.

### 👥 Who Is This Actor For?

- **Performance marketers** — see which creatives and offers a competitor keeps running, and which they quietly stopped
- **Creative strategists** — build a swipe file of hooks, headlines and CTA patterns in a niche
- **Agencies** — audit a prospect's live ads before a pitch, and report on a client's share of voice
- **Researchers and journalists** — study political and issue ads with their disclosed spend and reach
- 🤖 **AI builders** — feed ad copy into a RAG pipeline or an agent that summarises a competitor's current messaging

### 💡 Common Use Cases

- Scrape Facebook ads for a brand and track how its creative rotates week to week
- Pull every active ad from one advertiser page ID before writing a competing campaign
- Collect ad copy and CTA buttons across a keyword to find the angles a market is using
- Monitor political and issue ads in one country with their spend and impressions ranges
- Export a creative library as CSV for a spreadsheet review with a client

***

### 📥 Input

| Field | Type | Description | Default |
| ----- | ---- | ----------- | ------- |
| `searchTerms` | Array | Keywords to search the Ad Library for. Each keyword is searched separately. | — |
| `pageIds` | Array | Numeric Facebook page IDs, to pull every ad from one advertiser. | — |
| `startUrls` | Array | Facebook Ad Library search URLs pasted from the browser. Country and filters in the URL override the settings below. | — |
| `country` | String | Two-letter country code of the Ad Library region to search. | `US` |
| `adActiveStatus` | String | `all`, `active` or `inactive`. | `all` |
| `adType` | String | `all`, `political_and_issue_ads`, `housing_ads`, `employment_ads` or `credit_ads`. | `all` |
| `mediaType` | String | Creative type to keep: `all`, `image`, `meme`, `image_and_meme`, `video` or `none` (text-only ads). | `all` |
| `publisherPlatforms` | Array | Keep only ads that ran on at least one of `facebook`, `instagram`, `messenger`, `audience_network`, `whatsapp`, `threads`. Empty means all platforms. | all |
| `dateFrom` | String | Keep ads that were running on or after this date (`YYYY-MM-DD`). | none |
| `dateTo` | String | Keep ads that were running on or before this date (`YYYY-MM-DD`). | none |
| `maxItems` | Integer | Maximum ads to scrape **per keyword, page ID or start URL** — not per run. | `10` |
| `proxyConfiguration` | Object | Proxy settings. Residential is the default and the setting this Actor is tested on. | Apify Proxy, `RESIDENTIAL` |

At least one of `searchTerms`, `pageIds` or `startUrls` is required.

#### Example Input

```json
{
  "searchTerms": ["nike"],
  "country": "US",
  "adActiveStatus": "all",
  "adType": "all",
  "mediaType": "video",
  "publisherPlatforms": ["instagram"],
  "dateFrom": "2026-01-01",
  "dateTo": "2026-09-30",
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

***

### 🔗 Supported URL Types

| URL Type | Example |
| -------- | ------- |
| **Keyword search** | `https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&search_type=keyword_unordered` |
| **Advertiser page** | `https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=GB&view_all_page_id=15087023444&search_type=page` |

***

### 📤 Output

Each dataset item is one ad. Fields that the Ad Library does not disclose come back as `null`.

| Field | Type | Description |
| ----- | ---- | ----------- |
| `adArchiveId` | String | The ad's Ad Library ID |
| `collationId` | String | Groups near-identical ads that ran together |
| `collationCount` | Number | How many ads are in that group |
| `pageId` | String | Advertiser's Facebook page ID |
| `pageName` | String | Advertiser's page name |
| `pageUrl` | String | Advertiser's Facebook page URL |
| `pageProfilePictureUrl` | String | Advertiser's profile picture |
| `pageCategories` | Array | Categories on the advertiser's page, e.g. `["Nonprofit organization"]` |
| `advertiserName` | String | Name the ad is attributed to |
| `byline` | String | Funding entity on political and issue ads |
| `isActive` | Boolean | Whether the ad was still running |
| `startDate` | String | ISO date the ad started |
| `endDate` | String | ISO date the ad stopped, when it has |
| `totalActiveTime` | Number | Seconds the ad has run, when disclosed |
| `publisherPlatforms` | Array | Where it ran: `FACEBOOK`, `INSTAGRAM`, `MESSENGER`, `AUDIENCE_NETWORK` |
| `adText` | String | The ad's body copy |
| `adTitle` | String | The ad's headline |
| `linkUrl` | String | Landing page the ad points to |
| `linkCaption` | String | Display domain under the headline |
| `ctaText` | String | Call-to-action button label, e.g. `Shop Now` |
| `ctaType` | String | Call-to-action type, e.g. `SHOP_NOW` |
| `displayFormat` | String | Creative format: `IMAGE`, `VIDEO`, `CAROUSEL`, `DCO` |
| `categories` | Array | Ad Library category, e.g. `["POLITICAL"]` |
| `images` | Array | Image URLs in the ad |
| `videos` | Array | `{ url, preview }` for each video |
| `pageLikes` | Number | Likes on the advertiser's page |
| `impressionsText` | String | Impressions range — political and issue ads only |
| `spendText` | String | Spend range — political and issue ads only |
| `currency` | String | Currency of the spend range |
| `reachEstimate` | Number | Estimated reach, when disclosed |
| `containsSensitiveContent` | Boolean | Ad Library sensitive-content flag |
| `containsDigitalCreatedMedia` | Boolean | Whether the ad declares AI-generated or digitally created media |
| `countryIsoCode` | String | Country the creative snapshot came from |
| `adLibraryUrl` | String | Direct link to the ad in the Ad Library |
| `searchTerm` | String | The keyword this ad was found with |
| `searchPageId` | String | The advertiser page ID this ad was found with |
| `country` | String | The Ad Library country searched |

#### Example Output

```json
{
  "adArchiveId": "832851291236798",
  "collationId": "1033278991403571",
  "pageId": "54779960819",
  "pageName": "United Nations",
  "pageUrl": "https://www.facebook.com/unitednations/",
  "pageProfilePictureUrl": "https://scontent.fjed5-2.fna.fbcdn.net/v/t39.35426-6/314780285_700685748005646_8648629021855123542_n.jpg",
  "pageCategories": ["Organization"],
  "advertiserName": "United Nations",
  "byline": "United Nations with Facebook Ad Credits",
  "collationCount": 1,
  "isActive": false,
  "startDate": "2022-11-07T08:00:00.000Z",
  "endDate": "2023-01-08T08:00:00.000Z",
  "totalActiveTime": null,
  "publisherPlatforms": ["FACEBOOK", "INSTAGRAM"],
  "adText": "Leaders gathered at the UNGA to tackle global challenges. You can also help protect our planet by taking climate action.",
  "adTitle": "United Nations",
  "linkUrl": "https://api.whatsapp.com/send",
  "linkCaption": "api.whatsapp.com",
  "ctaText": "Send WhatsApp message",
  "ctaType": "WHATSAPP_MESSAGE",
  "displayFormat": "CAROUSEL",
  "categories": ["POLITICAL"],
  "images": [
    "https://scontent.fjed5-2.fna.fbcdn.net/v/t39.35426-6/314001595_822824655694557_5447234307407707513_n.jpg"
  ],
  "videos": [],
  "pageLikes": 8967118,
  "impressionsText": ">1M",
  "spendText": "€15K - €20K",
  "currency": "EUR",
  "reachEstimate": null,
  "containsSensitiveContent": false,
  "containsDigitalCreatedMedia": false,
  "countryIsoCode": "DE",
  "adLibraryUrl": "https://www.facebook.com/ads/library/?id=832851291236798",
  "searchTerm": "climate",
  "searchPageId": null,
  "country": "US"
}
```

You can export the dataset as **JSON, CSV, Excel, XML, RSS, or HTML** from the Apify Console or
via the [Apify API](https://docs.apify.com/api/v2).

***

### 💰 Pricing

This Actor is **pay per event** — you pay per ad returned: **$0.0005 per ad**, so **1,000 ads cost $0.50**, plus Apify platform usage.

That is the only event it charges. There is **no Actor start fee**, so a run that returns 12 ads costs 12 ads' worth, and there is no extra charge for ad details, advertiser data or enrichment. A run that finds no matching ads returns nothing and charges nothing. A free Apify account is enough to try it.

***

### ❓ FAQ

#### What is the Facebook Ads Library Scraper?

It is a Facebook Ads Library scraper that reads the public Facebook ad library and returns each ad as a structured record — copy, creative, CTA, landing page, dates, platforms and advertiser. You search by keyword, advertiser page ID or Ad Library URL.

#### Do I need an account, cookies or an API key?

No. It reads only what the Ad Library shows the public, so there is no login, no cookies and no Facebook API token.

#### Do I need a proxy?

Keep the residential default — it is the setting this Actor is tested on, and the one these figures were measured with. You do not need to configure anything else.

#### Is there a start fee or a minimum charge?

No. The only event this Actor charges is one per ad returned, at $0.0005. There is no per-run start fee and no separate charge for ad details, advertiser information or enrichment, so a small test run costs only the ads it returns.

#### How many ads can I get per run?

`maxItems` applies **per keyword, page ID or start URL**, so three keywords with `maxItems: 100` return up to 300 ads. The Ad Library reports how many ads match your search in the run log, and paging continues until `maxItems` or the end of the results.

#### Does it handle pagination automatically?

Yes. Each search runs to `maxItems` or to the last matching ad, whichever comes first — you do not need to page, resume or stitch runs together.

#### Which ads show spend and impressions?

Only ads in the political and issue category disclose spend ranges, impressions ranges and a funding byline — that is a Facebook policy, not a limit of this Actor. Commercial ads return `null` for those fields. Set `adType` to `political_and_issue_ads` to search only the ads that disclose them.

#### Can I filter by creative type or platform?

Yes. `mediaType` keeps only videos, images, memes, images-and-memes, or text-only ads (`none`), and `publisherPlatforms` keeps only ads that ran on the placements you pick — Facebook, Instagram, Messenger, Audience Network, WhatsApp or Threads. Both are the Ad Library's own filters, so only matching ads are returned and charged. Facebook decides which platforms it lists for an ad, so a small number of results can come back without the exact placement you asked for.

#### How does the date filter work?

`dateFrom` and `dateTo` match ads that **were running** in that window, which is how the Ad Library's own date filter behaves — not ads that started inside it. An ad that started before `dateFrom` and was still running afterwards is included, so a window of `2020-01-01` to `2020-12-31` returns ads whose run overlaps 2020. Either field works on its own.

#### Can I search a specific advertiser?

Yes. Put the numeric page ID in `pageIds`, or paste the advertiser's Ad Library URL (the one with `view_all_page_id=`) into `startUrls`.

#### Can I schedule it or integrate it with my app?

Yes — every Apify Actor exposes a REST API, webhooks, and integrations with Zapier, Make, Google
Sheets and Slack, and can be called from an AI agent via the Apify MCP server.

#### Is it legal to scrape Facebook ads?

This Actor accesses only the publicly available Ad Library, which Facebook publishes for ad transparency. You are responsible for making sure your use complies with Facebook's terms of service and the laws in your jurisdiction.

#### What if Facebook changes and the Actor breaks?

Open an issue on the Actor's **Issues** tab — that is the most direct route to a fix. The Ad Library changes regularly and the Actor is maintained against it, so most changes are absorbed without you doing anything.

***

### 🧩 Part of the Facebook Scraper Suite

Goldmine's Facebook Scraper Suite covers the public surfaces of Facebook — ads, groups and pages. Also try:

- [Facebook Group Scraper](https://apify.com/logical_scrapers/facebook-group-posts-scraper) — posts, authors, reactions and photos from public Facebook groups
- [Facebook Posts Scraper](https://apify.com/logical_scrapers/facebook-page-posts-scraper) — posts from public Facebook pages and profiles, with reactions, comments and shares
- [Facebook Page Details Scraper](https://apify.com/logical_scrapers/facebook-page-details-scraper) — followers, category, contact details and about text for a page, one row per page
- [Facebook Comments Scraper](https://apify.com/logical_scrapers/facebook-comments-scraper) — comments and replies on public posts, videos, reels and photos

See every Goldmine Actor at [apify.com/logical\_scrapers](https://apify.com/logical_scrapers).

***

### 📷 Image Credit

Image credit: [facebook.com](https://www.facebook.com/ads/library/)

***

### 📬 Contact & Support

- **Issues & feature requests**: use the Issues tab on this Actor's page — that is the most direct route to a fix.
- **Email**: `coredev.dan@gmail.com`
- **If this Actor saved you time, please leave a ⭐ rating on the Apify Store.** It helps us keep
  it maintained.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search the Ad Library for. Each keyword is searched separately and returns up to the maximum number of ads below.

## `pageIds` (type: `array`):

Numeric Facebook page IDs to pull every ad from one advertiser. Find a page ID in the Ad Library URL of an advertiser's ads (view\_all\_page\_id=…).

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

Facebook Ad Library search URLs, pasted straight from the browser — for example https://www.facebook.com/ads/library/?active\_status=active\&ad\_type=all\&country=GB\&q=running%20shoes. Country and filters in the URL override the ones set below.

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

Two-letter country code of the Ad Library region to search (for example US, GB, DE). The Ad Library returns ads shown in that country.

## `adActiveStatus` (type: `string`):

Whether to return ads that are currently running, ads that have stopped, or both.

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

Restrict the search to one of the Ad Library's special categories. Political and issue ads are the only category that discloses impressions and spend ranges.

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

Return only ads whose creative is of this type. "No image or video" returns text-only ads.

## `publisherPlatforms` (type: `array`):

Return only ads that ran on at least one of the selected platforms. Leave empty for all platforms. Facebook decides which platforms it lists for an ad, so a few results can come back without the platform you picked.

## `dateFrom` (type: `string`):

Keep only ads that were running on or after this date (YYYY-MM-DD). This is the Ad Library's own date filter: it matches ads whose run overlaps the window, so an older ad still running in the window is included.

## `dateTo` (type: `string`):

Keep only ads that were running on or before this date (YYYY-MM-DD). Combine with the field above for a window, or use either on its own.

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

Maximum number of ads to scrape for each keyword, advertiser page ID or start URL — not for the run as a whole.

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

Proxy configuration. Defaults to Apify residential proxies, which is what the Ad Library was measured working through; it refuses unrecognised clients until they pass a verification check.

## Actor input object example

```json
{
  "searchTerms": [
    "nike"
  ],
  "country": "US",
  "adActiveStatus": "all",
  "adType": "all",
  "mediaType": "all",
  "publisherPlatforms": [],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "searchTerms": [
        "nike"
    ],
    "country": "US",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logical_scrapers/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 = {
    "searchTerms": ["nike"],
    "country": "US",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("logical_scrapers/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 '{
  "searchTerms": [
    "nike"
  ],
  "country": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call logical_scrapers/facebook-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,logical_scrapers/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/I3y13msMVw9WAocwq/builds/OB420OrKmU1EuesaM/openapi.json
