# Facebook Ad Library Scraper Lowcost (0.3$/1K 🤑) (`sones/facebook-ads-library-scraper-lowcost`) Actor

Scrape Meta Ad Library ads by keyword, page or URL: creatives, copy, links, dates, platforms and spend, with optional EU reach. $0.30 per 1,000 ads.

- **URL**: https://apify.com/sones/facebook-ads-library-scraper-lowcost.md
- **Developed by:** [Samy](https://apify.com/sones) (community)
- **Categories:** Marketing, 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.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.

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 Lowcost

Get every ad of a Facebook Ad Library search as data: the advertiser, the text, the images and videos, the dates and the platforms it runs on. Paste Ad Library URLs, type keywords, or give Facebook page ids, and get one row per ad creative, with the ids of the ads the Ad Library lists for it, for **$0.30 per 1,000 ads**.

Marketers and agencies use it to:

- Watch what competitors advertise, and since when.
- Collect ad creatives and their texts for inspiration or analysis.
- Track political and issue ads with their spend and impressions.
- Measure the EU reach and audience of ads shown in the European Union.

### What it does

For each search you enter, it collects the ads the Ad Library shows, in the same order, up to the number you choose. Each ad comes with:

- The advertiser: page name, id, link, profile picture, likes and categories.
- The creative: text, headline, caption, link, call-to-action button, images, videos, and every card of carousel and catalogue ads.
- The ad's status, the day it started, the day it stopped, and the platforms it runs on (Facebook, Instagram, Messenger, Audience Network, Threads).
- How many ads share the same creative, and the ids of the ones the Ad Library lists with it.
- For ads about social issues, elections or politics: spend and impressions.
- How many ads the Ad Library counts for the search.
- With the EU transparency add-on: the EU reach, the reach by country, age and gender, the audience the ad targeted, and who paid for it and for whom.

You don't need a Facebook account.

### Why it costs less

You pay $0.30 per 1,000 ads, and $0.005 per run start (per GB of memory; runs use 1 GB by default). Other Ad Library scrapers on Apify Store charge between $0.40 and $5.80 per 1,000 ads (October 2026). There is no monthly rent. A run that finds 40 ads costs $0.017.

It is also fast. In our tests, one search of 1,000 ads took 2 to 3 minutes, and 20 searches of 100 ads each took 30 seconds together.

### How to use it

1. Enter what to scrape: Ad Library URLs, search terms, page ids, or a mix of them. Each entry is one search.
2. For search terms and page ids, choose the country, the active status, the ad category, the media type and the dates. Ad Library URLs keep their own filters.
3. Set **Maximum ads per search**.
4. Turn on **Add EU transparency details** if you need them.
5. Click **Start**, then download the ads as JSON, CSV, Excel or HTML.

#### Paste Ad Library URLs

Search the [Facebook Ad Library](https://www.facebook.com/ads/library/) as usual, then copy the URL from your browser. Every filter you set there is kept: country, category, active status, media type, platforms, language, dates and sort order. A link to one ad (a URL with `?id=`) is not a search, so it is skipped.

```json
{
    "urls": [
        "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=DE&media_type=video&q=bmw&search_type=keyword_unordered",
        "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&view_all_page_id=15087023444"
    ],
    "maxAdsPerSearch": 200
}
```

#### Search by keyword

Each term is one search. Put a term in double quotes to match the exact phrase.

```json
{
    "searchTerms": ["running shoes", "\"black friday\""],
    "country": "FR",
    "activeStatus": "active",
    "mediaType": "video",
    "maxAdsPerSearch": 500
}
```

#### Get every ad of a Facebook page

Give the page's numeric id. It is the number after `view_all_page_id=` in the page's Ad Library URL, and the page's **Page transparency** section shows it too.

```json
{
    "pageIds": ["15087023444"],
    "country": "ALL",
    "activeStatus": "all",
    "maxAdsPerSearch": 1000
}
```

#### Filter by date

**Shown on or after** and **Shown on or before** keep the ads shown during those days, whenever they started. An ad that started in January and still ran in October is in an October range.

### Output

One row per ad creative, as the Ad Library shows its results. Fields the Ad Library does not publish are `null`.

```json
{
    "adArchiveId": "1936432480352751",
    "adLibraryUrl": "https://www.facebook.com/ads/library/?id=1936432480352751",
    "pageId": "739783715881879",
    "pageName": "BagIt",
    "pageUrl": "https://www.facebook.com/61578816363458/",
    "pageProfilePictureUrl": "https://scontent.fclj4-1.fna.fbcdn.net/…",
    "pageLikeCount": 784,
    "pageCategories": ["Home care"],
    "isActive": true,
    "startDate": "2026-07-09",
    "endDate": null,
    "publisherPlatforms": ["FACEBOOK"],
    "collationId": "2169601026953377",
    "collationCount": 1,
    "collatedAdArchiveIds": ["1936432480352751"],
    "displayFormat": "VIDEO",
    "body": "Pourquoi tes baskets blanches ne sont jamais vraiment propres ?…",
    "title": "Des baskets propres. Sans effort.",
    "caption": "shopbagit.com",
    "linkUrl": "https://www.shopbagit.com/products/sac-de-lavage-bagit",
    "ctaText": "Shop now",
    "ctaType": "SHOP_NOW",
    "images": [],
    "videos": [
        {
            "hdUrl": "https://video.fclj4-1.fna.fbcdn.net/…",
            "sdUrl": "https://video.fclj4-1.fna.fbcdn.net/…",
            "previewImageUrl": "https://scontent.fclj4-1.fna.fbcdn.net/…"
        }
    ],
    "cards": [],
    "spend": null,
    "impressions": null,
    "currency": null,
    "euTransparency": {
        "reach": 1494741,
        "targetedAgeMin": 18,
        "targetedAgeMax": 65,
        "targetedGender": "All",
        "targetedLocations": [{ "name": "Belgium", "type": "countries", "excluded": false }],
        "reachBreakdown": [
            { "country": "BE", "ageRange": "18-24", "male": 1758, "female": 855, "unknown": 37 }
        ],
        "payer": "BagIt",
        "beneficiary": "BagIt"
    },
    "totalResultsOfSearch": 6409,
    "input": "nike",
    "searchUrl": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=FR&media_type=all&q=nike&search_type=keyword_unordered",
    "scrapedAt": "2026-10-20T23:04:19.892Z"
}
```

- `endDate` is `null` while the ad still runs.
- One row is one result of the Ad Library: an ad creative. `collationCount` is how many ads share it, and `collatedAdArchiveIds` holds the ids of the ads the Ad Library lists with it, this row's ad first.
- `videos` holds the videos of video ads. Carousel, dynamic and catalogue ads hold theirs in `cards`.
- `spend`, `impressions` and `currency` are only published for ads about social issues, elections or politics.
- `euTransparency` is only filled with the add-on, and only for ads shown in the European Union.
- `totalResultsOfSearch` is the Ad Library's own count. `50001` means more than 50,000.
- `searchUrl` opens the same search in the Ad Library.

Besides the ads, every run stores a `RUN_SUMMARY` record with the result of each search.

### Pricing

| What                             | Price                                                             |
| -------------------------------- | ----------------------------------------------------------------- |
| Run start                        | $0.005 per run start (per GB of memory; runs use 1 GB by default) |
| Ads                              | $0.30 per 1,000 ads                                               |
| EU transparency details (add-on) | $0.30 per 1,000 ads with EU transparency details                  |

For example, a run that gets 1,000 ads costs $0.305. With the add-on, each ad that comes with EU transparency details also costs the add-on price in the table. An ad never shown in the EU costs the same as without the add-on.

The run stops at your maximum charge per run, and you only pay for the ads you receive.

### Limits

- Up to 10,000 ads per search. The Ad Library counts up to 50,000.
- The add-on looks up each ad once more. In our tests, a search of 100 ads took 35 seconds with it and 21 seconds without.
- A few ads are hidden from visitors who are not logged in to Facebook. They come with their page and text only.
- Meta stopped running ads about social issues, elections or politics in the European Union in October 2025, so these searches find few or no ads in EU countries.
- The Ad Library does not take Cuba, Iran, North Korea or Sudan as a country, so they are not offered.

### FAQ

#### Do I need a Facebook account or cookies?

No. The Ad Library is public, and the Actor reads it as any visitor would.

#### Why did I get fewer ads than the count?

You get no more than your **Maximum ads per search**. The count is the Ad Library's own figure, and ads that share a creative show as one result.

#### Why does a search show "not a valid Ad Library search"?

The Ad Library refused it, for example a page id that belongs to no page, or a URL with a filter value it does not take. The run log names the search, and the others go on.

#### What happens to a URL or page id I typed wrong?

It is skipped and counted in the run log: a URL that is not an Ad Library search, a page id that is empty or not a number, or a date that does not exist. Page ids are numbers, and a page's name is not its id.

#### Can I run it every day?

Yes. Schedule it in Apify Console, and send the ads to Google Sheets, Slack, a webhook or your own app with Apify integrations.

### Is it legal?

The Ad Library is the public transparency archive Meta publishes so that anyone can see who advertises what. This Actor collects only what the Ad Library shows any visitor. Advertiser pages, payers and beneficiaries can include the names of people. If you store or process them, you are responsible for doing so lawfully, for example under the GDPR.

# Actor input Schema

## `urls` (type: `array`):

Searches copied from the Facebook Ad Library (facebook.com/ads/library), keyword searches or an advertiser's page of ads (a URL with view_all_page_id). Every filter in the URL is kept, and the filters below do not change it. A link to a single ad is skipped.

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

Keywords to search the Ad Library for, one search each, with the filters below. Wrap a term in double quotes to match the exact phrase, such as "running shoes".

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

Numeric ids of Facebook pages, to get every ad each page runs, with the filters below. A page's id is the number after view_all_page_id= in its Ad Library URL, and is shown in the page's Page transparency section.

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

Only ads shown in this country. Applies to search terms and page ids.

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

Ads still running, ads that stopped, or both.

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

All ads, or only one of the categories the Ad Library keeps apart. Spend and impressions are only published for ads about social issues, elections or politics.

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

Only ads with this kind of media.

## `deliveredAfter` (type: `string`):

Only ads shown on or after this day. This is the day the ad was shown, not the day it started: an ad that started earlier and still ran on this day is included.

## `deliveredBefore` (type: `string`):

Only ads shown on or before this day. An ad that ran on this day is included, even if it kept running after it.

## `maxAdsPerSearch` (type: `integer`):

The most ads to get from each search, in the order the Ad Library shows them.

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

For each ad shown in the European Union, also get what Meta publishes under the EU Digital Services Act: the people it reached in the EU, its reach by country, age and gender, the ages, gender and places it targeted, and who paid for it and for whom. Paid add-on, charged only for the ads that have these details. Makes the run slower.

## `proxy` (type: `object`):

Leave on automatic to use the proxies the Actor provides. To send every request through your own proxies instead, choose 'Own proxies' and enter their URLs.

## Actor input object example

```json
{
  "urls": [
    "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&q=running%20shoes&search_type=keyword_unordered&media_type=all"
  ],
  "searchTerms": [
    "nike",
    "\"running shoes\""
  ],
  "pageIds": [
    "15087023444"
  ],
  "country": "ALL",
  "activeStatus": "active",
  "adType": "all",
  "mediaType": "all",
  "maxAdsPerSearch": 20,
  "includeAdDetails": false,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `runSummary` (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"
    ],
    "maxAdsPerSearch": 20,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sones/facebook-ads-library-scraper-lowcost").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"],
    "maxAdsPerSearch": 20,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("sones/facebook-ads-library-scraper-lowcost").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"
  ],
  "maxAdsPerSearch": 20,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call sones/facebook-ads-library-scraper-lowcost --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sones/facebook-ads-library-scraper-lowcost"
        }
    }
}
```

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/FMhwTrPcAM8w3IYMj/builds/pVuOGzwsRGi2EhQ8C/openapi.json
