# Facebook Ad Library Scraper (Audience Data, No Login) (`locaihost/facebook-ad-library`) Actor

Scrape the Meta Ad Library for Facebook and Instagram ads by keyword, advertiser Page or Ad Library link. Get ad text, headline, link, images and videos, start date, platforms, political spend and impressions. Optional EU and UK reach with age and gender split. No login. From $0.70 per 1,000 ads.

- **URL**: https://apify.com/locaihost/facebook-ad-library.md
- **Developed by:** [locaihost data](https://apify.com/locaihost) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 Ad Library Scraper (Audience Data, No Login)

Get every ad a brand, a competitor or a keyword runs on Facebook, Instagram, Messenger and Threads, straight from Meta's public Ad Library, as clean rows you can sort, chart and schedule.

### What people use it for

- **Competitor ad research:** every live ad a rival runs, with its text, headline, offer, landing page and creative, and how long each ad has been running (long-running ads are the ones that work).
- **Creative swipe files:** pull hundreds of ads for a keyword ("meal kit", "crm software") with their images and videos, and filter by format, platform or start date.
- **Political and issue ad monitoring:** who paid, how much they spent, how many impressions, and (with audience data) the age, gender and regional split Meta discloses.
- **EU and UK reach data:** for ads delivered in Europe, Meta publishes reach by country, age and gender, plus who paid and who benefited. This Actor reads it for you.
- **New-ad alerts:** schedule it daily with "Only new ads" on and get only the ads that appeared since the last run.

### Quick start

1. Type a keyword (or paste a Page link under Advertisers), pick a country, and press **Start**.
2. Or call it from code with input like this:

```json
{
    "searchTerms": ["running shoes"],
    "advertisers": ["https://www.facebook.com/Fit2RunSuperstore", "Gymshark"],
    "country": "US",
    "activeStatus": "active",
    "maxAds": 100
}
```

You can also search on facebook.com/ads/library with any filters and paste the link into **Ad Library links**.

### What data can I get?

| Field | What it is |
|---|---|
| `adArchiveId`, `adLibraryUrl` | The ad's Ad Library ID and link |
| `pageName`, `pageId`, `pageUrl`, `pageLikes`, `pageCategories` | The advertiser's Facebook Page |
| `status`, `startDate`, `endDate`, `daysActive` | Whether it is running, when it started and stopped, and for how many days |
| `platforms` | Facebook, Instagram, Messenger, Audience Network, Threads, WhatsApp |
| `displayFormat` | Image, video, carousel, dynamic creative or catalogue ad |
| `bodyText`, `headline`, `linkDescription`, `ctaText` | The ad's copy and button |
| `linkUrl`, `linkDomain`, `caption` | Where the ad sends people |
| `imageUrls`, `videoUrls`, `thumbnailUrls`, `cards` | The creative files, and each card of a carousel or catalogue ad |
| `variationCount` | How many versions of this creative the advertiser runs |
| `paidForBy`, `spend`, `impressions`, `reachEstimate` | For political and issue ads: who paid, the spend range with currency, and the impressions range |
| `audience` ($) | Political and issue ads: share of impressions by age and gender, and by region |
| `euTransparency`, `ukTransparency` ($) | Ads delivered in the EU or UK: total reach, targeting (age, gender, locations) and reach by country, age and gender |
| `payerBeneficiary` ($) | Who paid for the ad and who it was for, as disclosed in the EU |
| `pageDetails` ($) | The advertiser's Page likes, Instagram followers and username, verification and category |
| `searchInput`, `searchCountry`, `scrapedAt` | Which search found the ad, and when |

One real row (image links shortened):

```json
{
  "adArchiveId": "1476276287628343",
  "adLibraryUrl": "https://www.facebook.com/ads/library/?id=1476276287628343",
  "pageId": "153470341405993",
  "pageName": "Fit2Run, The Runner's Superstore",
  "pageUrl": "https://www.facebook.com/Fit2RunSuperstore/",
  "pageCategories": ["Sportswear"],
  "pageLikes": 55434,
  "status": "ACTIVE",
  "isActive": true,
  "startDate": "2026-04-06",
  "endDate": null,
  "daysActive": 209,
  "platforms": ["FACEBOOK", "INSTAGRAM"],
  "displayFormat": "IMAGE",
  "bodyText": "Find the perfect fit for every run with top brands like On, HOKA, Brooks, ASICS, and Nike. Run in, shop local - or browse online anytime!",
  "headline": "Visit Online or In Store",
  "linkDescription": "Fuel your movement.",
  "ctaText": "Learn more",
  "ctaType": "LEARN_MORE",
  "linkUrl": "https://www.fit2run.com/",
  "linkDomain": "fit2run.com",
  "caption": "www.fit2run.com",
  "imageUrls": ["https://scontent-sin2-2.xx.fbcdn.net/v/t39.35426-6/668340220..."],
  "videoUrls": [],
  "cards": [],
  "variationCount": 4,
  "paidForBy": null,
  "spend": null,
  "impressions": null,
  "pageDetails": {
    "likes": 55434,
    "instagramFollowers": 45356,
    "instagramUsername": "fit2run_therunnerssuperstore",
    "verification": "NOT_VERIFIED",
    "category": "Sportswear shop"
  },
  "detailsStatus": "no-audience-data",
  "searchInput": "https://www.facebook.com/Fit2RunSuperstore",
  "searchCountry": "US",
  "scrapedAt": "2026-11-01T12:08:31.512Z"
}
```

### How much does it cost?

You pay per ad returned. Prices per 1,000:

| Event | Free and Starter | Scale | Business |
|---|---|---|---|
| Ad | $0.70 | $0.525 | $0.385 |
| Ad with audience data ($, only with "Audience data" on, and only for ads where Meta shows audience data) | $2.00 | $1.50 | $1.10 |

Plus a one-time $0.00005 per run.

**Free:** advertisers that can't be found, searches with no matching ads, ads already returned by an earlier run (with "Only new ads" on), and the same ad found by two of your searches (charged once). With "Audience data" on, an ad where Meta shows no audience data is charged as a plain ad.

Apify's free $5 monthly credit covers about 7,100 ads.

### Limits, stated up front

- **Public ads only, logged out.** This Actor reads what anyone sees on the Ad Library without an account. It never logs in and never asks for cookies.
- **Audience data is only where Meta discloses it:** political and issue ads (any country), and ads delivered in the EU or UK. For other ads (for example a US shop's product ads) Meta shows no spend, reach or demographics, and neither can we.
- **Image and video links are signed by Meta and expire after a few days.** Download the files you want to keep.
- Meta caps its own result count at about 50,000 per search. Split very large searches by country, date or keyword.
- Pages are read about 10 ads at a time, so 1,000 ads from one search take a few minutes. Several searches run side by side.
- Advertiser names are matched to the Page with that exact name among ads that mention it. For an exact match every time, paste the Page link or Page ID.
- Free plan: up to 1,000 ads per run. Any paid Apify plan removes the cap.

### Only new ads, and scheduling

Turn on **Only new ads** and schedule the Actor (Apify Console, Schedules) daily or weekly. Each run remembers the ads it returned for the same searches and filters, and skips them for free, so you get only ads that appeared since the last run. Changing the keywords or filters starts a fresh memory.

### Integrations

- **API:** run it and read results with the Apify API or the JavaScript and Python clients.
- **n8n and Make:** use the Apify node or module, pick this Actor, and pass the input above.
- **Agents (MCP):** add it to Apify's MCP server and call it from any MCP client.
- **Exports:** CSV, Excel, JSON, XML from the dataset, or straight into Google Sheets.

### FAQ

**How much will a run cost me?** 100 ads cost $0.07 on the Starter price. The run's maximum charge (in the run options) caps it: the Actor stops cleanly when it is reached.

**Can I use it through the API?** Yes. Every input field works the same through the API, and results come back as JSON, CSV or Excel.

**Can agents use it?** Yes, through Apify's MCP server. It is paid per event, so an agent pays only for the ads it gets.

**Is it legal?** The Ad Library is a public transparency tool that Meta publishes for anyone to read without an account, and this Actor only reads what a logged-out visitor sees. You are responsible for how you use the data; check the rules that apply to you, especially for any personal data in ad text.

**Why is a field empty?** It means Meta does not show it for that ad. Spend, impressions and audience data exist only for political and issue ads and for ads delivered in the EU or UK; headline and button are missing on ads that have none; `endDate` is empty while an ad is still running.

**Why did a run end with "No ads matched"?** Nothing in the Ad Library matched your keyword with those filters. Nothing was charged. Try country "All countries", status "Active and inactive", or a broader keyword.

### More from locaihost data

- [TikTok Trends Scraper](https://apify.com/locaihost/tiktok-trends): TikTok's top ads, hashtags and videos.
- [Google Maps Leads & Emails Scraper](https://apify.com/locaihost/google-maps-leads): local businesses with website checks.
- [Website Traffic Checker](https://apify.com/locaihost/website-traffic): visits, sources and referral shares for any site.
- [Domain to Company Data Lookup](https://apify.com/locaihost/company-profile): logo, socials and role emails from a domain.
- [TikTok Shop Scraper](https://apify.com/locaihost/tiktok-shop): products with exact sold counts.

Did it help? A rating on the Store helps other people find it.

**Support:** open an issue on this Actor's Issues tab. We answer issues within 24 hours.

# Changelog

This Actor's version history is a separate document: https://apify.com/locaihost/facebook-ad-library/changelog.md

# Actor input Schema

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

Search ad text and advertiser names, as the Ad Library search box does. Each keyword is its own search.

## `advertisers` (type: `array`):

Every ad an advertiser runs. Paste the Facebook Page's link (facebook.com/nike), its Page ID, or its exact name. A link or ID is exact; a name is matched against advertisers whose ads mention it.

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

Search on facebook.com/ads/library with any filters, then paste the link here. Its own filters are used as they are.

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

Ads shown in this country. "All countries" covers every country. For audience data on non-political ads, pick an EU country or the UK.

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

All ads, or only one of the special categories Meta lists separately. Political and issue ads include spend, impressions and who paid.

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

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

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

Only ads with this kind of creative.

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

Only ads shown on these platforms. Empty means all.

## `startDateFrom` (type: `string`):

Only ads that started running on or after this date: YYYY-MM-DD, or a relative "7 days" / "2 weeks" / "3 months".

## `startDateTo` (type: `string`):

Only ads that started running on or before this date: YYYY-MM-DD, or a relative "7 days".

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

Match keywords as an exact phrase instead of all the words in any order.

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

Stop each keyword, advertiser or link after this many ads. 0 means every ad the search has.

## `includeDetails` (type: `boolean`):

Open each ad's details for the audience data Meta discloses: age and gender split and regions for political and issue ads; reach by country, age and gender, targeting, payer and beneficiary for ads delivered in the EU or UK. Also adds the advertiser's Page likes, Instagram followers and verification. Only ads where Meta shows audience data are charged at the higher price.

## `onlyNew` (type: `boolean`):

Skip ads an earlier run with the same searches and filters already returned (free). Turn on for scheduled runs to get only ads that appeared since.

## Actor input object example

```json
{
  "searchTerms": [
    "running shoes",
    "meal kit",
    "crm software"
  ],
  "advertisers": [
    "https://www.facebook.com/Fit2RunSuperstore",
    "153470341405993",
    "Gymshark"
  ],
  "startUrls": [
    "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=GB&q=coffee&search_type=keyword_unordered"
  ],
  "country": "US",
  "adType": "all",
  "activeStatus": "active",
  "mediaType": "all",
  "startDateFrom": "30 days",
  "exactPhrase": false,
  "maxAds": 20,
  "includeDetails": false,
  "onlyNew": false
}
```

# Actor output Schema

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

One row per ad: advertiser, status, dates, platforms, format, headline, text, button, link, images and videos.

## `spend` (type: `string`):

Paid-for-by, spend and impressions ranges, and audience data where Meta discloses it.

## `full` (type: `string`):

Every field of every ad, including carousel cards and EU/UK reach breakdowns.

## `summary` (type: `string`):

Ads per search, advertisers not found, skipped input, pages read and cost.

# 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"
    ],
    "country": "US",
    "maxAds": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("locaihost/facebook-ad-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 = {
    "searchTerms": ["running shoes"],
    "country": "US",
    "maxAds": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("locaihost/facebook-ad-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 '{
  "searchTerms": [
    "running shoes"
  ],
  "country": "US",
  "maxAds": 20
}' |
apify call locaihost/facebook-ad-library --silent --output-dataset

```

## MCP server setup

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