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

Scrape the Meta Ad Library by keyword, advertiser page or Library link with every filter: ad text, images, videos, dates, platforms, EU reach by age, gender and country, political ad spend, and advertiser phone, email and website. Free result counts. No login.

- **URL**: https://apify.com/calm_builder/facebook-ads-library-scraper.md
- **Developed by:** [Coder](https://apify.com/calm_builder) (community)
- **Categories:** Social media, Developer tools
- **Features:** Limited permissions
- **Stats:** 31 total users, 6 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 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

Collect ads from the **Facebook Ads Library (Meta Ad Library)**: no login, no cookies, no browser.

Search by **keyword**, by **advertiser** (any Facebook page) or paste any **Ads Library link** with your filters already set. You get every ad's text, images, videos, carousel cards, link, button, dates, platforms and advertiser, plus optional extras:

- **Ad details**: EU reach (and UK / Brazil where Meta shows it) with the age × gender × country breakdown, the targeted audience (ages, gender, locations), who paid for the ad and who benefits, and an advertiser summary (about text, page likes, Instagram account and followers, verified badge).
- **Every version of an ad**: Meta groups versions ("3 ads use this creative and text"); turn this on for one row per version.
- **Advertiser page details**: each advertiser's phone, email, website, address, followers, rating, opening hours and page creation date, in a separate Advertisers table.
- **Result counts**: just the number of ads a search matches, as the Ads Library shows it, one row per search, charged per search counted.
- **Monitoring**: on a schedule, save only new ads.

Political and issue ads also include **spend**, **impressions** and **reach** as Meta publishes them.

### How to use it

1. Type one or more **search terms**, and/or paste **Ads Library links** or **Facebook page links** (for example `https://www.facebook.com/nike`).
2. Pick your filters: countries, ad status, category, media type, platforms, languages, dates, sort order.
3. Choose how many ads per search, and turn on any extras.
4. Click **Start**. Ads appear in the **Ads** tab as they are found and can be exported to JSON, CSV, Excel or via the API.

**Tip:** set up a search on [facebook.com/ads/library](https://www.facebook.com/ads/library/) and copy the link. All its filters (country, status, category, media type, language, platform, dates, sort) are used as they are.

### Output

#### Ads

| Field | Example |
|---|---|
| adArchiveId, adLibraryUrl | 925321173274919, https://www.facebook.com/ads/library/?id=925321173274919 |
| pageName, pageUrl, pageId | Nordstrom Rack, https://www.facebook.com/NordstromRack/, 89516513179 |
| text, title, linkUrl, ctaText | Buy online and pick up in store for free!…, Fast & Free Pickup, …, Learn more |
| displayFormat | IMAGE, VIDEO, CAROUSEL, DPA (catalog), DCO (dynamic) |
| imageUrls, videos, cards | full-size image links; video HD/SD links with preview; carousel cards with their own text, link and media |
| isActive, startDate, endDate, daysRunning | true, 2026-08-03T07:00:00Z, 2026-10-01T07:00:00Z, 60 |
| platforms | FACEBOOK, INSTAGRAM, MESSENGER, AUDIENCE_NETWORK, THREADS |
| versionCount, versionGroupId | 2, 1022906600523558 |
| pageCategories, pageLikes | Clothing (Brand), 2518386 |
| spendMin, spendMax, impressionsText, currency | political / issue ads only |
| totalResults, searchQuery, position | 38469, running shoes, 1 |

With **ad details** on: `euTotalReach`, `euReachBreakdown` (country, ageRange, male, female, unknown), `targetAgeMin`, `targetAgeMax`, `targetGender`, `targetLocations`, `ukTransparency`, `payerBeneficiary`, `advertiser` (about, likes, instagramUsername, instagramFollowers, verification, category).

#### Advertisers

The same fields as our Facebook Pages Scraper: name, category, followers, phone, email, website, social links, address with coordinates, rating, price range, opening hours, about text, page creation date, whether it runs ads, admin countries and name changes. One row per advertiser per run.

#### Count-only mode

With *Only count the results* on, the Ads table gets one row per search instead of ads: the search, its link and `totalResults` (Meta stops counting at 50,000+, shown as 50001). Each count is charged as one *Ad count* event. Ad details, advertiser pages and ad versions are skipped in this mode.

### Options

| Option | What it does |
|---|---|
| Search terms | Keywords; each is its own search. Turn on *Match the exact phrase* for exact matches |
| Ads Library links or advertiser pages | Library links keep their own filters; a page link returns all ads of that advertiser; `?id=` links return that one ad |
| Maximum ads per search | Ads collected from each search term, link or page |
| Countries | One, several or all countries |
| Ad status | Active, inactive or all ads |
| Ad category | All, political and issue, housing, employment, financial products |
| Media type | Images, videos, memes, or ads without media |
| Platforms, Languages | Facebook / Instagram / Messenger / Audience Network / Threads / WhatsApp; two-letter language codes |
| Shown on or after / before | Ads delivered within a date range: a date (`2026-09-01`) or a period (`30 days`) |
| Sort by | Most impressions first, or most relevant first (the two orders the Ads Library offers) |

**Monitoring:** turn on *Only new ads* and schedule the Actor. Each run saves only ads it has not collected before for the same search.

If you are coming from another Ads Library scraper, the common input names (`startUrls`, `urls`, `resultsLimit`, `activeStatus`, `onlyAdsNewerThan`, `onlyAdsOlderThan`, `isDetailsPerAd`, `includeAboutPage`, `onlyTotal`) work here too.

### Notes

- Only what Meta shows logged-out visitors in the Ads Library is collected. Reach and audience data exists for ads shown in the EU, the UK and Brazil, and for political and issue ads.
- Meta caps result counts at 50,000+ and shows ads in pages of 10 to 30; very large searches take longer.

# Actor input Schema

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

Keywords to search the Ads Library for, one per line (for example running shoes). Each term is its own search.

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

Ads Library links (set filters on facebook.com/ads/library, then copy the link - its filters are used), Facebook page links for all ads of that advertiser (for example https://www.facebook.com/nike), or page IDs. A link to one ad (?id=...) returns that ad.

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

Off: ads containing all the words in any order. On: ads containing the words exactly as typed.

## `maxAds` (type: `integer`):

How many ads to collect from each search term, link or page.

## `countries` (type: `array`):

Ads shown in these countries. All countries by default.

## `activeStatus` (type: `string`):

Ads running now, ads that have stopped, or both.

## `adCategory` (type: `string`):

Political and issue ads also carry spend, impressions and audience data.

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

Only ads with this kind of creative.

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

Only ads shown on these platforms. Empty = all.

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

Only ads in these languages, as two-letter codes (en, es, de...). Empty = all.

## `onlyAdsNewerThan` (type: `string`):

Only ads shown (delivered) on or after this date. A date, or a period back from now such as 30 days.

## `onlyAdsOlderThan` (type: `string`):

Only ads shown on or before this date. Combine with 'Shown on or after' for a date range.

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

The two orders the Ads Library offers.

## `includeAdDetails` (type: `boolean`):

Per ad: reach in the EU (and UK / Brazil where shown) with the age, gender and country breakdown, the targeted audience, who paid for the ad and who benefits, and an advertiser summary (about text, likes, Instagram account, verification). Charged per ad.

## `expandVersions` (type: `boolean`):

Some ads run in several versions ("3 ads use this creative and text"). Off: one row per ad with the number of versions. On: one row per version.

## `includeAdvertiserPage` (type: `boolean`):

Each advertiser's Facebook page, once per run, in the Advertisers table: phone, email, website, address, followers, rating, opening hours, page creation date and more. Charged per advertiser.

## `onlyNewAds` (type: `boolean`):

For scheduled runs: save only ads that an earlier run of the same search did not collect.

## `onlyTotalCount` (type: `boolean`):

Return just the number of ads each search matches (as the Ads Library shows it, up to 50,000+): one row per search with Total results. Charged per search counted. When on, all other output options are ignored.

## Actor input object example

```json
{
  "searchTerms": [
    "running shoes"
  ],
  "exactPhrase": false,
  "maxAds": 100,
  "countries": [
    "ALL"
  ],
  "activeStatus": "active",
  "adCategory": "all",
  "mediaType": "all",
  "sortBy": "impressions",
  "includeAdDetails": false,
  "expandVersions": false,
  "includeAdvertiserPage": false,
  "onlyNewAds": false,
  "onlyTotalCount": false
}
```

# Actor output Schema

## `ads` (type: `string`):

No description

## `advertisers` (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": [
        "running shoes"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("calm_builder/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": ["running shoes"] }

# Run the Actor and wait for it to finish
run = client.actor("calm_builder/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": [
    "running shoes"
  ]
}' |
apify call calm_builder/facebook-ads-library-scraper --silent --output-dataset

```

## MCP server setup

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