# Meta Ads Library Scraper 📣 $0.75/1k (`123webdata/meta-ads-library-scraper`) Actor

Collect structured Meta and Facebook ad data from Ad Library searches and advertiser Page URLs. Very high data coverage: up to 48 fields are available for each ad.

- **URL**: https://apify.com/123webdata/meta-ads-library-scraper.md
- **Developed by:** [123 Webdata](https://apify.com/123webdata) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Meta Ads Library Scraper

Collect live and historical ads from Meta's public Ad Library. Scrape keyword searches, Ad Library filters, and ads run by specific Facebook Pages. The Actor returns structured ad, advertiser, creative, spend, reach, transparency, and regional-registration data without opening an ad page in a browser.

### Issues and feature requests

If you encounter an issue or need a field added, open an issue on the Actor page or write to hello@123webdata.com.

For custom requirements, contact [123 Web Data](https://www.123webdata.com/).

### Output example (simplified)

| Advertiser | Ad | Active | Started | Platforms | Currency | Position |
| --- | --- | --- | --- | --- | --- | --- |
| Nike | https://www.facebook.com/ads/library/?id=1550534860016399 | true | 2024-03-04 12:00:00 | FACEBOOK, INSTAGRAM | USD | 1 |

Every row also contains the complete Meta creative snapshot and the other declared fields listed below.

### How to scrape the Meta Ad Library

1. Open [Meta Ad Library](https://www.facebook.com/ads/library/).
2. Choose a country, ad category, active status and any keyword or filters.
3. Copy the final URL from the address bar.
4. Paste one or more URLs into **Ad Library URLs**.

Example search URL:

```text
https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike
```

The Actor sends supported search filters from the pasted URL to Meta's own JSON search endpoint. It does not reject a URL because of its locale, regional hostname, path, query names, filter combination, or pagination state. Unsupported or inaccessible page shapes are reported in the run status and recorded in the Actor's support notes.

#### Scrape advertiser Pages

Paste Facebook Page or advertiser URLs into **Advertiser Page URLs**. Vanity names, numeric IDs, `profile.php?id=` URLs and regional hostnames are accepted.

```text
https://www.facebook.com/depop
https://www.facebook.com/profile.php?id=156405867784232
```

Optional Page filters control active status, date period, sort order and country for advertiser Page runs.

#### Collect creative details

Enable **Include ad details** to make an additional JSON request for each emitted ad. This adds advertiser registration, AAA eligibility, violation, verification and location-transparency data. Leave it disabled for faster, lower-cost runs.

#### Pagination and limits

Enable **Use pagination** to follow Meta's result cursor until a limit is reached. Disable it to collect only the first result page. **Maximum ads per source** applies to each URL. **Maximum ads to save** is the global cap across all URLs.

### Pricing

This Actor uses pay-per-event pricing. Its running costs are included.

- **Actor start:** `$0.015` per GB. The default 2 GB memory allocation charges `$0.03` once per run.
- **Ad:** `$0.00075` each (`$0.75 per 1,000`). One event is charged for each saved unique ad.

| Ads in one run | Ads | Actor start | Total |
| ---: | ---: | ---: | ---: |
| 100 | $0.075 | $0.03 | $0.105 |
| 1,000 | $0.75 | $0.03 | $0.78 |

[Apify's Free plan](https://apify.com/pricing) currently includes $5 in monthly usage credits. If the full $5 is available for this Actor, one run covers about 6,600 ads after the start charge. Other Apify usage reduces the available credit.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `adLibraryUrls` | array | Meta Ad Library search and filter URLs |
| `advertiserPageUrls` | array | Facebook advertiser or Page URLs |
| `maxTotalResults` | integer | Maximum ads saved across every source |
| `maxResultsPerSource` | integer | Maximum ads saved from each source |
| `scrapeAdDetails` | boolean | Add the detail-only fields listed below |
| `usePagination` | boolean | Follow Meta cursors beyond the first result page |
| `pageAdFilters` | object | Active status, period, sort order and country for advertiser Pages |
| `proxyConfiguration` | object | Optional Apify Residential proxy controls, including `countryCode` |
| `runTag` | string | Optional label copied unchanged to every row |

The Actor always requires Apify Residential proxy because Meta applies stricter limits to datacenter traffic.

### What data you get in each mode

Every saved ad is one record. A unique ad is charged once.

#### Standard result

The standard result contains:

`ad_archive_id`, `ad_id`, `collation_count`, `collation_id`, `is_active`, `page_id`, `page_is_deleted`, `page_name`, `snapshot`, `has_user_reported`, `report_count`, `menu_items`, `state_media_run_label`, `impressions_with_index`, `gated_type`, `categories`, `is_aaa_eligible`, `contains_digital_created_media`, `reach_estimate`, `currency`, `spend`, `start_date`, `end_date`, `start_date_formatted`, `end_date_formatted`, `publisher_platform`, `targeted_or_reached_countries`, `contains_sensitive_content`, `total_active_time`, `regional_regulation_data`, `hide_data_status`, `fev_info`, `url`, `ad_library_url`, `total`, `position`, `runTag`, `ads_count`, `scraped_at`

Page-scoped searches also include `pageInfo`.

#### Detailed result

**Include ad details** adds:

`advertiser`, `aaa_info`, `insights`, `violation_types`, `verified_voice_context`, `transparency_by_location`, `is_siep_advertiser_eligible_for_ai_disclosure`, `is_violating_eu_siep`

Creative text, titles, calls to action, links, cards, images and videos remain in the nested `snapshot` object exactly as Meta returns them.

### Output example (full)

```json
{
  "ad_archive_id": "1550534860016399",
  "collation_count": null,
  "collation_id": null,
  "is_active": true,
  "page_id": "115939511520844",
  "page_is_deleted": false,
  "page_name": "Nike",
  "snapshot": {
    "body": {
      "text": "Example ad copy"
    },
    "title": "Example title",
    "cta_text": "Shop now",
    "link_url": "https://www.nike.com/",
    "images": [],
    "videos": [],
    "cards": []
  },
  "publisher_platform": [
    "FACEBOOK",
    "INSTAGRAM"
  ],
  "start_date": 1709553600,
  "end_date": 1712232000,
  "start_date_formatted": "2024-03-04 12:00:00",
  "end_date_formatted": "2024-04-04 12:00:00",
  "currency": "USD",
  "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike",
  "ad_library_url": "https://www.facebook.com/ads/library/?id=1550534860016399",
  "total": 10000,
  "position": 1,
  "runTag": "campaign-2026-10",
  "ads_count": 1,
  "scraped_at": "2026-10-23T16:00:00.000Z"
}
```

### Use cases

- Monitor ads by competitor, brand or Facebook Page
- Research creative and copy across markets
- Build political, issue and regional-transparency datasets
- Track active periods, spend ranges, impressions and reach
- Compare placement and platform behavior
- Create recurring ad-monitoring workflows through the Apify API

### Limitations

- Meta controls the data it exposes and can rate-limit requests across a residential address.
- Some fields are valid only for political, issue, EU, UK or Brazil transparency datasets and are empty elsewhere.
- Advertiser Page rows include the complete `pageInfo` object when Meta returns it in the Page JSON response. The current logged-out Page search can omit that auxiliary object; the ad rows remain complete, but the Actor does not fetch Page HTML merely to reconstruct it.
- Exact spend and reach ranges depend on the country and ad category selected in the supplied URL.
- The Actor follows Meta's cursors and limits; it does not invent additional ads after Meta stops returning pages.
- A public Page URL can be valid while Meta still refuses its Page search. The exact limitation is recorded in the Actor's support documentation when observed.

### Integrations

Use the Actor with the Apify API, JavaScript or Python clients, webhooks, schedules, Make, Zapier, Google Sheets, Airtable, BigQuery or your own data pipeline. Every ad is one dataset item for simple export and event billing.

Questions or custom integrations: hello@123webdata.com.

# Actor input Schema

## `adLibraryUrls` (type: `array`):

Paste one or more Meta/Facebook Ad Library search URLs. Search text, status, country, date, media, platform and other filters encoded in the URL are forwarded when Meta exposes them.

Example:

- https://www.facebook.com/ads/library/?active_status=active\&ad_type=all\&country=US\&q=nike

Leave blank when using advertiser Page URLs.

## `advertiserPageUrls` (type: `array`):

Paste Meta/Facebook advertiser or Page URLs. Accepts vanity URLs, numeric Page URLs, profile.php?id= URLs and regional hostnames.

Examples:

- https://www.facebook.com/depop
- https://www.facebook.com/profile.php?id=156405867784232
- https://de-de.facebook.com/156405867784232

## `maxTotalResults` (type: `integer`):

Maximum number of ad records to save across every supplied source.

## `maxResultsPerSource` (type: `integer`):

Maximum number of ad records to collect from each URL. The total limit can stop the run earlier.

## `scrapeAdDetails` (type: `boolean`):

Fetch Meta's ad-details JSON for each selected ad. This adds advertiser, AAA, violation, verification and regional-transparency fields and increases request time.

## `usePagination` (type: `boolean`):

Continue through Meta's result cursor until each source or total limit is reached. Disable this to save only the first result page.

## `pageAdFilters` (type: `object`):

Optional filters applied only to advertiser Page URLs. Use {"activeStatus":"all|active|inactive","period":"last24h|last7d|last14d|last30d","sortBy":"most_recent|impressions_desc","countryCode":"US"}.

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

Optional proxy controls. The Actor always uses Apify Residential proxy. Set {"countryCode":"US"} to request a residential country; automatic selection is used when omitted.

## `runTag` (type: `string`):

Optional label copied unchanged to every result for provenance.

## Actor input object example

```json
{
  "adLibraryUrls": [
    "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
  ],
  "advertiserPageUrls": [],
  "maxTotalResults": 10,
  "maxResultsPerSource": 10,
  "scrapeAdDetails": false,
  "usePagination": false,
  "pageAdFilters": {},
  "proxyConfiguration": {},
  "runTag": ""
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per unique Meta ad.

# 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 = {
    "adLibraryUrls": [
        "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
    ],
    "maxTotalResults": 10,
    "maxResultsPerSource": 10,
    "scrapeAdDetails": false,
    "usePagination": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("123webdata/meta-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 = {
    "adLibraryUrls": ["https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"],
    "maxTotalResults": 10,
    "maxResultsPerSource": 10,
    "scrapeAdDetails": False,
    "usePagination": False,
}

# Run the Actor and wait for it to finish
run = client.actor("123webdata/meta-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 '{
  "adLibraryUrls": [
    "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=nike&search_type=keyword_unordered&media_type=all"
  ],
  "maxTotalResults": 10,
  "maxResultsPerSource": 10,
  "scrapeAdDetails": false,
  "usePagination": false
}' |
apify call 123webdata/meta-ads-library-scraper --silent --output-dataset

```

## MCP server setup

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