# Facebook Ad Library Scraper 📢 \[No Login] Ads & Creatives (`viralanalyzer/facebook-ads-library`) Actor

Scrape active Meta and Facebook ads globally without login or cookies: ad copy, creative media, targeting, advertiser page, and CTA links. Pay per ad scraped.

- **URL**: https://apify.com/viralanalyzer/facebook-ads-library.md
- **Developed by:** [viralanalyzer](https://apify.com/viralanalyzer) (community)
- **Categories:** Lead generation, Social media, Automation
- **Features:** Limited permissions
- **Stats:** 497 total users, 7 monthly users, 99.5% runs succeeded, 12 bookmarks
- **User rating**: 4.91 out of 5 stars

## Pricing

from $10.00 / 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.

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 📱 Meta Ads Competitive Intelligence

> **Pay per extracted ad** · 🆓 3 free ads on your first run · 🌍 any country · 🤖 optional AI analysis
> 🔗 [View on Apify Store](https://apify.com/viralanalyzer/facebook-ads-library) · 🇺🇸 English · [🇧🇷 Português](#-português)

Turn the public **Meta Ad Library** into a structured competitor-ad dataset. Search any advertiser or keyword across **Facebook, Instagram, Messenger & Audience Network** and export ad creatives, copy, CTAs, landing URLs, formats, platform breakdown, spend/impression ranges, campaign dates and direct Ad Library links as clean JSON, CSV or Excel. Optional AI competitive report via Google Gemini.

**Who it's for:** competitive-intelligence teams, performance marketers, media buyers, brand-protection and market researchers who need to see what competitors are advertising — right now.

#### Problems this solves

- **Manual ad research is slow** — collect ads into a dataset instead of copying screenshots by hand.
- **Competitor messaging is scattered** — compare copy, creative format, CTA and landing pages in one table.
- **Campaign launches are easy to miss** — filter active/historical ads and start dates for monitoring.
- **Stakeholders need proof** — export direct Meta Ad Library links alongside every row.

***

### 🇺🇸 English

#### ✨ Features

- **Multi-platform** — ads from Facebook, Instagram, Messenger & Audience Network in one run
- **Full ad intelligence** — advertiser, ad copy, creative image/video URL, CTA, landing URL, format, status
- **Spend & impressions** — estimated ranges (available for political/social ads)
- **Any country** — search by ISO code (`BR`, `US`, `GB`, `DE`, …) or `ALL`
- **Multi-advertiser** — search several brands in one run with `Nike OR Adidas`
- **URL and Page ID input** — paste a Meta Ad Library URL or numeric Page ID when you need precise targeting
- **Date filters** — keep ads that started within a specific research window
- **Optional AI analysis** — competitive strategy report via Google Gemini 2.0 Flash
- **Active / inactive filter** — currently-running ads or historical campaigns
- **Incremental output** — ads are saved as they're found (results survive timeouts)
- **Transparent by design** — no silent failures; diagnostics are labeled and never charged

#### 💵 Pricing (Pay Per Event)

This actor uses Apify **Pay Per Event** billing. The billable event is `ad-scraped`, charged only when a valid ad row is extracted.

- The **Apify Store pricing panel is the source of truth** for the current per-ad rate and any scheduled price changes.
- 🆓 **Free tier:** your first run is capped at **3 ads / 1 advertiser** (AI off) so you can validate output before paying.
- 🛡️ **You are never charged for a diagnostic run.** If Meta blocks the request (anti-bot), the actor returns a labeled diagnostic item and **charges $0**. A run that finds no ads without a block fails honestly instead of billing you.

#### ⚙️ Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQuery` | string | — | **Required.** Advertiser/page name, keyword, Meta Ad Library URL, or numeric Page ID. Use `OR` for multiple advertisers (`Nike OR Adidas`) |
| `country` | string | `BR` | ISO country code (`US`, `GB`, `DE`, `MX`…) or `ALL` |
| `adType` | enum | `all` | `all` or `political_and_issue_ads` |
| `activeStatus` | enum | `active` | `active`, `inactive`, or `all` |
| `startDateFrom` | string | — | Keep ads that started on or after this date (`YYYY-MM-DD`) |
| `startDateTo` | string | — | Keep ads that started on or before this date (`YYYY-MM-DD`) |
| `maxAds` | integer | `50` | Max ads to extract (1–500). Use a small run first, then scale |
| `includeAiAnalysis` | boolean | `false` | Gemini competitive report (requires `GEMINI_API_KEY` in the actor's environment) |
| `proxyConfiguration` | object | — | Start **without** proxy to minimize cost; only add a **residential** proxy if Meta blocks the run or returns zero ads |

#### 📥 Input example

```json
{
    "searchQuery": "Nike",
    "country": "BR",
    "adType": "all",
    "activeStatus": "active",
    "maxAds": 50,
    "includeAiAnalysis": false
}
```

#### 📤 Output example

```json
{
    "id": "a1b2c3d4e5f6",
    "pageName": "Nike",
    "adContent": "Just Do It. Encontre os melhores tênis e roupas Nike...",
    "adFormat": "image",
    "imageUrl": "https://scontent.xx.fbcdn.net/v/t45.1600-4/...",
    "videoUrl": null,
    "landingUrl": "https://www.nike.com.br/...",
    "displayLink": "nike.com.br",
    "ctaText": "Shop Now",
    "ctaType": "SHOP_NOW",
    "country": "BR",
    "startDate": "2026-02-10",
    "status": "Active",
    "platforms": "Facebook, Instagram",
    "estimatedSpend": "1,000 - 5,000",
    "impressions": "100,000 - 500,000",
    "adLibraryId": "1234567890",
    "adLibraryUrl": "https://www.facebook.com/ads/library/?id=1234567890"
}
```

**Output fields:** `id`, `pageName`, `adContent`, `adFormat` (image/video/text), `imageUrl`, `videoUrl`, `landingUrl`, `displayLink`, `ctaText`, `ctaType`, `pageId`, `country`, `startDate`, `endDate`, `status` (Active/Inactive), `platforms`, `estimatedSpend`, `impressions`, `adLibraryId`, `adLibraryUrl`. Fields that Meta doesn't expose for a given ad come back as `null` (never faked).

#### 🔌 API quick start

For small research jobs, you can run the actor and receive dataset items in one request:

```bash
curl -X POST "https://api.apify.com/v2/actors/viralanalyzer~facebook-ads-library/run-sync-get-dataset-items?format=json&clean=true&maxTotalChargeUsd=1" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchQuery": "Nike",
    "country": "BR",
    "activeStatus": "active",
    "maxAds": 20,
    "includeAiAnalysis": false
  }'
```

Use `maxTotalChargeUsd` as a budget guard when testing automation. For larger jobs, use the standard Apify run endpoint and fetch items from the default dataset.

#### 🎯 Use cases

- **Competitive intelligence** — monitor competitor campaigns, creatives and messaging
- **Creative research** — collect winning ad formats and copy for benchmarking
- **Media planning** — see which platforms a brand is buying and when campaigns launched
- **Brand protection** — detect unauthorized use of your brand in ads
- **Political transparency** — analyze political/issue ad spend and messaging

### ✅ Capabilities & Limits

Stated up front, so you do not pay a run to find out.

**Built here:** a margin guard stops the infinite scroll when the run burns more compute than the ads pay for. After a 90-second grace period, an extraction rate under roughly 1 ad per 12 seconds ends the scroll and keeps what was already pulled - so a sparse query finishes successfully with fewer than `maxAds` instead of scrolling to the timeout.

| Input / feature | Supported | Notes |
|---|---|---|
| Advertiser name or keyword | ✅ | `searchQuery` — required |
| Country filter | ✅ | `country` as ISO-2, or `ALL` |
| Ad type | ✅ | `adType`; **Political & Issue Ads additionally expose spend and impression ranges** — regular commercial ads never do |
| **Spend / impressions for commercial ads** | ❌ | Meta publishes those only for political and issue ads. No tool can return them for a normal brand campaign |
| Active vs historical | ✅ | `activeStatus` |
| Date range | ✅ | `startDateFrom` / `startDateTo` |
| Result volume | ⚠️ | `maxAds` from 1 to 500; billed per valid ad extracted |
| AI strategy summary | ⚠️ | `includeAiAnalysis` requires **your own** Google Gemini API key |
| Login / cookies | ❌ | not needed — the Ad Library is public |
| Proxy | ⚠️ | start **without** proxy to keep cost down; the Ad Library is public |

#### ❓ FAQ

- **Do I need a Facebook login or cookies?** No. The Meta Ad Library is public; the actor handles cookie consent and login walls automatically.
- **Why are `estimatedSpend` / `impressions` sometimes empty?** Meta only publishes spend & impression ranges for **political and social-issue** ads. Commercial ads legitimately don't expose them, so those fields are `null`.
- **Can I search more than one advertiser at once?** Yes — put `OR` between names (`Nike OR Adidas OR Puma`). Ads are split evenly across `maxAds`.
- **The run returned a "diagnostic" item and no ads — was I charged?** No. A diagnostic item means Meta blocked the request; PPE is **not** charged. Add a residential proxy and retry.
- **How do I enable the AI report?** Set `includeAiAnalysis: true` and provide a `GEMINI_API_KEY` in the actor's environment variables.
- **Which countries are supported?** Any — pass the 2-letter ISO code, or `ALL`.

#### 🔧 Tips

- Start with `maxAds: 20` to validate your query before scaling.
- Use `maxTotalChargeUsd` in API tests to cap spend.
- Start **without** proxy; only add a residential proxy if Meta blocks the run.
- For political-ad transparency, set `adType: "political_and_issue_ads"`.

***

### 💰 Pricing

**$0.01 per ad returned** (`ad-scraped`). Apify platform usage of the run is included — you are not
billed separately for compute or proxy.

You are charged only for ads actually returned. A run blocked by the source, or one where the search
matched nothing, writes a labeled diagnostic row and charges no event.

### 🇧🇷 Português

A **Biblioteca de Anúncios da Meta** vira um dataset estruturado de inteligência competitiva. Pesquise qualquer anunciante ou palavra-chave no **Facebook, Instagram, Messenger e Audience Network** e exporte criativos, textos, CTAs, landing pages, formatos, plataformas, faixas de gasto/impressões, datas e links diretos em JSON, CSV ou Excel. Relatório competitivo com IA (Google Gemini) opcional.

#### ✨ Funcionalidades

- **Multi-plataforma** — anúncios de Facebook, Instagram, Messenger e Audience Network numa execução
- **Inteligência completa** — anunciante, texto, URL do criativo (imagem/vídeo), CTA, landing page, formato, status
- **Gasto & impressões** — faixas estimadas (disponíveis para anúncios políticos/sociais)
- **Qualquer país** — busca por código ISO (`BR`, `US`, `GB`, `DE`…) ou `ALL`
- **Multi-anunciante** — busque várias marcas numa execução com `Nike OR Adidas`
- **URL e Page ID** — cole uma URL da Meta Ad Library ou um Page ID numérico para segmentar melhor
- **Filtro por data** — mantenha anúncios iniciados dentro de uma janela específica
- **Análise com IA opcional** — relatório estratégico via Google Gemini 2.0 Flash
- **Filtro ativo/inativo** — anúncios em execução ou campanhas históricas
- **Saída incremental** — anúncios são salvos conforme encontrados (sobrevivem a timeouts)
- **Transparente por design** — sem falhas silenciosas; diagnósticos são rotulados e nunca cobrados

#### 💵 Preços (Pay Per Event)

Este actor usa cobrança **Pay Per Event** da Apify. O evento cobrável é `ad-scraped`, cobrado apenas quando uma linha válida de anúncio é extraída.

- O **painel de preços da Apify Store é a fonte oficial** para a taxa atual por anúncio e mudanças agendadas.
- 🆓 **Gratuito:** a primeira execução é limitada a **3 anúncios / 1 anunciante** (IA desligada) para você validar antes de pagar.
- 🛡️ **Você nunca paga por execução de diagnóstico.** Se a Meta bloquear (anti-bot), o actor devolve um item de diagnóstico rotulado e **cobra $0**. Uma execução que não encontra anúncios sem bloqueio falha honestamente em vez de cobrar.

#### ⚙️ Parâmetros de entrada

| Parâmetro | Tipo | Padrão | Descrição |
|-----------|------|--------|-----------|
| `searchQuery` | string | — | **Obrigatório.** Nome do anunciante/página ou palavra-chave. Use `OR` para vários (`Nike OR Adidas`) |
| `country` | string | `BR` | Código ISO do país (`US`, `GB`, `DE`, `MX`…) ou `ALL` |
| `adType` | enum | `all` | `all` ou `political_and_issue_ads` |
| `activeStatus` | enum | `active` | `active`, `inactive` ou `all` |
| `startDateFrom` | string | — | Mantém anúncios iniciados em ou depois desta data (`YYYY-MM-DD`) |
| `startDateTo` | string | — | Mantém anúncios iniciados em ou antes desta data (`YYYY-MM-DD`) |
| `maxAds` | integer | `50` | Máx. anúncios (1–500). Comece pequeno, valide e depois escale |
| `includeAiAnalysis` | boolean | `false` | Relatório Gemini (requer `GEMINI_API_KEY` no ambiente) |
| `proxyConfiguration` | object | — | Comece **sem** proxy; só adicione **residencial** se a Meta bloquear ou voltar zero anúncios |

#### 📥 Exemplo de entrada

```json
{
    "searchQuery": "Magazine Luiza",
    "country": "BR",
    "adType": "all",
    "activeStatus": "active",
    "maxAds": 50,
    "includeAiAnalysis": false
}
```

#### 📤 Exemplo de saída

```json
{
    "id": "a1b2c3d4e5f6",
    "pageName": "Magazine Luiza",
    "adContent": "Ofertas imperdíveis! Até 50% OFF em eletrônicos...",
    "adFormat": "image",
    "imageUrl": "https://scontent.xx.fbcdn.net/v/t45.1600-4/...",
    "videoUrl": null,
    "landingUrl": "https://www.magazineluiza.com.br/...",
    "displayLink": "magazineluiza.com.br",
    "ctaText": "Comprar agora",
    "ctaType": "SHOP_NOW",
    "country": "BR",
    "startDate": "2026-01-15",
    "status": "Active",
    "platforms": "Facebook, Instagram",
    "estimatedSpend": "5,000 - 10,000",
    "impressions": "500,000 - 1,000,000",
    "adLibraryId": "9876543210",
    "adLibraryUrl": "https://www.facebook.com/ads/library/?id=9876543210"
}
```

**Campos de saída:** `id`, `pageName`, `adContent`, `adFormat`, `imageUrl`, `videoUrl`, `landingUrl`, `displayLink`, `ctaText`, `ctaType`, `pageId`, `country`, `startDate`, `endDate`, `status`, `platforms`, `estimatedSpend`, `impressions`, `adLibraryId`, `adLibraryUrl`. Campos que a Meta não expõe voltam como `null` (nunca inventados).

#### 🎯 Casos de uso

- **Inteligência competitiva** — monitore campanhas, criativos e mensagens dos concorrentes
- **Pesquisa criativa** — colete formatos e textos vencedores para benchmarking
- **Planejamento de mídia** — veja em quais plataformas a marca anuncia e quando começou
- **Proteção de marca** — detecte uso não autorizado da sua marca em anúncios
- **Transparência política** — analise gasto e mensagens de anúncios políticos/sociais

#### ❓ Perguntas frequentes

- **Preciso de login/cookies do Facebook?** Não. A Biblioteca de Anúncios é pública; o actor trata consentimento de cookies e login walls automaticamente.
- **Por que `estimatedSpend` / `impressions` às vezes vêm vazios?** A Meta só publica gasto e impressões para anúncios **políticos e de questões sociais**. Anúncios comerciais não expõem esses dados — por isso vêm `null`.
- **Posso buscar mais de um anunciante?** Sim — use `OR` entre os nomes (`Nike OR Adidas`). Os anúncios são divididos igualmente no `maxAds`.
- **A execução voltou um item "diagnóstico" e nenhum anúncio — fui cobrado?** Não. Item de diagnóstico = a Meta bloqueou; PPE **não** é cobrado. Adicione proxy residencial e tente de novo.
- **Como ativo o relatório de IA?** Defina `includeAiAnalysis: true` e informe `GEMINI_API_KEY` nas variáveis de ambiente do actor.

***

### 🔗 Data source / Fonte dos dados

All data comes from the public [Meta Ad Library](https://www.facebook.com/ads/library/) — Meta's official transparency tool. Todos os dados vêm da Biblioteca de Anúncios da Meta (oficial e pública).

### 🔗 Related actors / Actors relacionados

- [Google Ads Transparency Scraper](https://apify.com/viralanalyzer/google-ads-transparency)
- [LinkedIn Ad Library Scraper](https://apify.com/viralanalyzer/linkedin-ads-library)
- [Instagram Reels & Posts Scraper](https://apify.com/viralanalyzer/instagram-reels-scraper)
- [TikTok Viral Scanner](https://apify.com/viralanalyzer/tiktok-viral-scanner)
- [Reclame Aqui Scraper](https://apify.com/viralanalyzer/reclameaqui-scraper)
- [Mercado Livre Scraper](https://apify.com/viralanalyzer/mercadolivre-scraper)

### 📝 Changelog

- **v1.4** — Pay Per Event pricing optimized for ad-level extraction; 2 GB memory for reliable Playwright rendering; GraphQL + DOM dual extraction; block-gated diagnostics (SUCCEEDED only on confirmed anti-bot block, otherwise honest fail — never charges for a broken run); `OR` multi-advertiser search; free tier (3 ads).
- **v1.1** — Improved extraction selectors, cookie-consent handling, login-wall bypass, infinite-scroll reliability.
- **v1.0** — Initial release: Meta Ad Library scraping with optional AI analysis.

### License

ISC © 2026 Viral Analyzer Platform

***

💡 **Need AI analysis on top of this data — sentiment, trend detection and a dashboard, with no API keys to manage?**
[ViralAnalyzer](https://viralanalyzer.com.br) runs this actor + 42 more data sources with built-in AI. JSON + insights in one call.

# Actor input Schema

## `searchQuery` (type: `string`):

Three ways to search: (1) an advertiser/page name or keyword — e.g. 'Nike', 'Magazine Luiza', 'coffee subscription'; (2) paste a Meta Ad Library URL straight from your browser — every filter in that URL is honoured; (3) a numeric Page ID — e.g. '15087023444'. Tip: search several advertisers in one run with ' OR ' — e.g. 'Nike OR Adidas'.

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

Two-letter ISO country code to filter ads (e.g. BR, US, GB, DE, MX). Use 'ALL' for every country. Use the ISO code, not the country name.

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

Filter by ad type. 'Political & Issue Ads' also exposes spend and impression ranges.

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

Return currently-running ads, historical (inactive) ads, or both.

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

Keep only ads whose start date is on or after this date, e.g. '2026-01-01'. Leave empty for no lower bound. Ads whose start date Meta does not expose are always kept.

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

Keep only ads whose start date is on or before this date, e.g. '2026-06-30'. Leave empty for no upper bound.

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

Maximum number of ads to extract (1–500). Billed per valid ad extracted according to the Apify Store pricing panel. Free-tier runs are capped at 3 ads. Start with 20 to validate your query before scaling.

## `includeAiAnalysis` (type: `boolean`):

Use Google Gemini to summarize ad strategy, dominant format, key messages and competitive insights. Requires a GEMINI_API_KEY in the actor's environment variables.

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

Proxy settings. Start WITHOUT proxy to minimize cost — Meta Ad Library is public and usually loads over datacenter. Only enable a RESIDENTIAL proxy if a run is blocked or returns zero ads.

## Actor input object example

```json
{
  "searchQuery": "Nike",
  "country": "BR",
  "adType": "all",
  "activeStatus": "active",
  "maxAds": 50,
  "includeAiAnalysis": false
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset containing all scraped results. Each item follows the dataset schema.

# 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 = {
    "searchQuery": "Nike",
    "country": "BR",
    "maxAds": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("viralanalyzer/facebook-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 = {
    "searchQuery": "Nike",
    "country": "BR",
    "maxAds": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("viralanalyzer/facebook-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 '{
  "searchQuery": "Nike",
  "country": "BR",
  "maxAds": 50
}' |
apify call viralanalyzer/facebook-ads-library --silent --output-dataset

```

## MCP server setup

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