# Facebook Ads Library Scraper - Meta & Instagram Ad Library (`s-r/meta-ads-library`) Actor

Scrape the Facebook (Meta) Ads Library by brand name, page ID or a pasted Ad Library URL. Get every ad an advertiser runs on Facebook and Instagram: ad text, images, videos, CTA, run dates, platforms, spend and reach ranges, plus page details.

- **URL**: https://apify.com/s-r/meta-ads-library.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Social media, Marketing, Business
- **Features:** Limited permissions
- **Stats:** 233 total users, 22 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.46 / 1,000 ad scrapeds

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: Meta and Instagram Ad Library

This Facebook Ads Library Scraper exports the ads any advertiser runs on Facebook, Instagram and other Meta placements. Search by advertiser name, Facebook page ID, or a pasted Ad Library URL, and get structured advertising records with creative text, media links, run dates, placements, call to action and advertiser details. Each dataset row represents an ad creative variant reported by Meta. Use the dataset to review campaign messaging, compare creative formats, track public advertiser activity, or export records to your own analysis tools.

### What the Facebook Ads Library Scraper does

The Meta Ad Library is public, but browsing it by hand stops working once you need more than a handful of ads. The page loads ads in small batches, there is no export button, and comparing advertisers means copying text and screenshots into a spreadsheet. This Actor resolves the advertiser, pages through its full ad inventory up to your limit, and returns one clean JSON row per ad creative. You can download the result as JSON, CSV, Excel or XML, or read it from the Apify API in your own pipeline.

### Input

Choose one of three starting points. Use `search` when you know the advertiser's name, `page_id` when you already know its Facebook page ID, or `url` when you have copied an address from the Ad Library. The Actor resolves a name to one advertiser page; it does not return every page whose name contains the search term. Page selection considers name match, country, verification and page likes, in that order.

The `country` setting uses a two-letter code such as `NL` or `US` and defaults to `US`. `active_only` defaults to `true`, which requests active advertisements. Set it to `false` to include other statuses that Meta makes available. `max_ads` defaults to 100 and accepts values from 1 to 5000. The number delivered also depends on the advertiser's available inventory in the selected country.

An explicit `page_id` takes precedence over the page ID in a URL. An explicit `search` takes precedence over the URL's search text. A country in the URL takes precedence over the separate `country` setting. The URL's active-status filter applies only when `active_only` was not supplied; Apify fills the default value for this setting. A URL containing `country=ALL` does not replace the selected country. Keeping these rules consistent helps existing integrations continue to return the same kind of results.

A recorded working input is `{"search":"coolblue","country":"NL","max_ads":100}`. Another recorded input is `{"page_id":"124955570892789","country":"US","active_only":false,"max_ads":30}`. These inputs were checked against the public library on 1 October 2026. Inventories change, so an older example does not guarantee the same advertisement IDs on a later date.

### Output

Rows retain `ad_id`, `page_id`, `page_name`, `is_active`, `start_date`, `end_date`, `total_active_time` and `publisher_platform`. The creative fields include `display_format`, `title`, `body_text`, `images`, `videos`, `link_url`, `link_description`, `caption`, `cta_text` and `cta_type`. Images are URL strings. Each video contains `hd_url`, `sd_url` and `preview_image_url`; the high-definition URL may be null.

Advertiser information includes `page_profile_uri`, `page_profile_picture_url`, `page_like_count` and `page_categories`. Disclosure fields include `byline`, `disclaimer_label`, `contains_digital_created_media`, `contains_sensitive_content`, `state_media_run_label`, `page_is_deleted` and `branded_content`. Other reported fields include `collation_count`, `collation_id`, `categories`, `targeted_or_reached_countries`, `country_iso_code`, `reach_estimate`, `currency`, `spend`, `impressions_text`, `impressions_index`, `spend_text` and `spend_index`.

Political and issue advertisements can include reported spending and reach bands. In the recorded Bernie Sanders response, `spend` included `$500K-$600K`, `reach_estimate` included `>1M`, and `currency` was `USD`. These are ranges published by the source. They are preserved as strings, not converted into exact spending amounts. Commercial records can have null values for these fields, and unavailable data is not estimated.

The `country` field records the effective requested country and `resolved_page_id` records the selected advertiser page. The `query` field preserves the search value, including when an explicit page ID determines the advertiser. Added fields include a UTC `fetched_at` timestamp, `source`, `platform`, `advertiser_name` and `creative_id`. Existing field names and JSON types remain available. Download the dataset through Apify's supported export formats or read it through the dataset API.

#### Example output row

This is an excerpt of a real row collected on 1 October 2026 with `{"page_id":"124955570892789","country":"US","active_only":false,"max_ads":30}`. Long media URLs (`images`, `videos`, `page_profile_picture_url`) and a few other fields are left out for readability; every value shown is exactly as returned.

```json
{
  "ad_id": "3050616791773669",
  "page_id": "124955570892789",
  "page_name": "Bernie Sanders",
  "is_active": false,
  "start_date": "2025-02-20",
  "end_date": "2025-03-26",
  "publisher_platform": [
    "FACEBOOK",
    "INSTAGRAM"
  ],
  "display_format": "VIDEO",
  "title": "Donate to Bernie Sanders",
  "body_text": "I am once again asking for your financial support to help me travel coast to coast to spread the word about the dangers of Trumpism and the rising power of oligarchs like Elon Musk. Trumpism will not be defeated by politicians inside the DC beltway. It will only be defeated by millions of Americans, in every state in this country, coming together in a strong, grassroots movement. Trump MUST and CAN be defeated. So if you’re with me, please chip in whatever you can to help me reach the American people.",
  "link_description": "Donate now",
  "caption": "secure.actblue.com",
  "cta_text": "Donate now",
  "cta_type": "DONATE_NOW",
  "reach_estimate": ">1M",
  "currency": "USD",
  "spend": "$500K-$600K",
  "categories": [
    "POLITICAL"
  ],
  "byline": "Friends of Bernie Sanders",
  "disclaimer_label": "PAID_FOR_BY",
  "page_profile_uri": "https://facebook.com/berniesanders",
  "page_like_count": 6867634,
  "page_categories": [
    "Government Official"
  ],
  "impressions_text": ">1M",
  "country": "US",
  "resolved_page_id": "124955570892789",
  "advertiser_name": "Bernie Sanders",
  "fetched_at": "2026-10-01T13:01:14.430Z"
}
```

### Use cases

- **Competitor ad research.** See which creatives a competitor runs right now, which formats they favour (video, carousel, catalogue ads) and which calls to action they test.
- **Creative inspiration and swipe files.** Collect ad copy, headlines and media links from the leading brands in your market and keep them in your own library.
- **Campaign monitoring.** Schedule the Actor daily or weekly for a list of advertisers and compare `start_date`, `end_date` and `is_active` to see when campaigns launch and stop.
- **Political and issue ad transparency.** Track reported spend and reach bands, the "paid for by" line and the disclaimer label for political advertisers, for journalism and research.
- **Agency reporting and lead generation.** Find which brands actively advertise in a country and on which Meta platforms, and use the page details for outreach or market sizing.

### Facebook Ads Library Scraper compared with the alternatives

**Browsing the Ad Library by hand** is free but slow: there is no export, and every advertiser and country is a new search. This Actor turns the same public information into a dataset in one run.

**Meta's official Ad Library API** requires a developer account with identity verification and an access token, and it focuses on political and issue ads plus ads delivered in the EU. Commercial ads elsewhere are hard to reach through it. This Actor needs only an Apify account and returns commercial and political ads alike.

**Other Apify Store scrapers** cover the same library. This one keeps a stable output schema with stable field names, returns spend and reach ranges where Meta publishes them, follows pagination to up to 5000 ads per run, and charges only for delivered ads.

### Pagination and completeness

The Actor follows available pages until it reaches your requested number of ads, the inventory ends, or the run's time budget prevents further collection. Large requests continue automatically. Results are deduplicated by advertisement ID. Where Meta returns several variants within a group, each distinct variant can become its own row. The order follows the source's total-impressions sorting.

Check the `OUTPUT` or `summary` record when completeness matters. It includes `itemCount`, `partial`, `warnings` and charging information. A partial result can simply mean that your requested maximum is smaller than the advertiser's available inventory. It can also indicate that collection was interrupted. If you need more data, increase `max_ads` and allow sufficient run time. Availability can differ by country, ad status and the date of collection.

### Pricing

The existing Apify price model remains in effect. On 1 October 2026, the `scraped` event costs $0.001 per delivered advertisement. The already announced schedule beginning 2 October 2026 at 06:47:06 UTC sets tier-based prices and a `run_start` event of $0.0004 per run. The listed tier prices per ad are $0.0007 for FREE, $0.000609385 for BRONZE, $0.000530501 for SILVER and $0.000461828 for GOLD, PLATINUM and DIAMOND. The Actor's Pricing tab is the authoritative current schedule.

Only delivered rows count toward the scraped event. An empty result has no per-ad charge; a run-start fee applies when that event is active. Users without a paid Apify plan receive at most ten rows per run, preserving the existing free-plan limit. Paying users can request up to 5000 rows. Repeated collection of the same advertiser at different times is a separate run and may retrieve changed inventory.

### FAQ

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

The Ad Library is a public transparency tool published by Meta, and this Actor only collects what the library shows to any visitor. You remain responsible for how you use the data; check the rules that apply to your use case, especially for personal data in political ads.

#### Does this cover Instagram ads?

The Meta library includes placements reported for Facebook, Instagram and other Meta surfaces. Read `publisher_platform` on each record to see the reported placements. A single advertisement can list more than one platform.

#### Why are spending or reach fields empty?

The source does not publish the same information for every advertisement. Spending and reach bands are commonly available for political or issue ads, while commercial records may have null fields. An empty field is preserved rather than filled with an estimate.

#### Can I look up a page without searching its name?

Yes. Supply a numeric `page_id`, or paste an Ad Library URL containing `view_all_page_id`. This avoids ambiguity between similarly named advertiser pages. Select the country and active-status setting that match the inventory you want to inspect.

#### What happens when no advertisements are found?

The run succeeds with an empty dataset for a genuine empty search or an unavailable upstream response. The error or summary record explains the outcome. There is no per-ad charge for an empty dataset; the applicable run-start event still follows the current price model.

#### How many ads can one run return?

Up to 5000, set with `max_ads`. Users without a paid Apify plan receive at most ten rows per run. The real number also depends on how many ads the advertiser has in the selected country and status.

#### Can I run it on a schedule or through the API?

Yes. Use Apify schedules to collect the same advertisers every day or week, or start runs through the Apify API and read the dataset when the run finishes. Integrations such as webhooks, Make and Zapier work the same way as for any other Actor.

# Actor input Schema

## `url` (type: `string`):

Paste a Meta Ad Library URL. Filters in the URL (page, country, active status) are read automatically, so you can set everything up in Meta's own interface and paste the address bar here. Overrides nothing you set explicitly below.

## `search` (type: `string`):

Brand or page name to search (e.g. "coolblue"). Either search or page_id is required.

## `page_id` (type: `string`):

Direct lookup by Facebook page ID (e.g. "100445001673131").

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

ISO country code (NL, DE, US, etc.).

## `active_only` (type: `boolean`):

Filter to currently active ads only.

## `max_ads` (type: `integer`):

How many ads to return per run. The scraper pages through Meta's ad library until it reaches this number or runs out of ads. Big advertisers have thousands.

## Actor input object example

```json
{
  "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=101886952638461",
  "search": "nike",
  "country": "US",
  "active_only": true,
  "max_ads": 100
}
```

# Actor output Schema

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

One row per ad with creative, media, CTA, impressions/spend ranges and page details.

# 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 = {
    "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=101886952638461",
    "search": "nike",
    "country": "US",
    "active_only": true,
    "max_ads": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/meta-ads-library").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 = {
    "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=101886952638461",
    "search": "nike",
    "country": "US",
    "active_only": True,
    "max_ads": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/meta-ads-library").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 '{
  "url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=101886952638461",
  "search": "nike",
  "country": "US",
  "active_only": true,
  "max_ads": 100
}' |
apify call s-r/meta-ads-library --silent --output-dataset

```

## MCP server setup

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

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/faP10mPssSt7sGvJl/builds/opluHzx6GqJKnMtzL/openapi.json
