# Facebook Ad Library Scraper: Competitor Ads

> Facebook Ad Library scraper: get ads by keyword, domain, page or ad ID. Ad text, creative links, landing page, days running and winner score. No login.

URL: https://cliqtomedia.com/actors/facebook-ad-library/

Category: Search, SEO & ads · Status: live on Apify Store · Apify page: https://apify.com/cliqtomedia/facebook-ad-library?fpr=cliqto

Get ads from the public Meta Ad Library by keyword, domain, advertiser page or ad ID. Each ad is one row with text, creative links, landing page, start date and days running. EU and political ads add reach and spend ranges.

## How to use it: 3 steps

1. **Make a free Apify account.** Apify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
2. **Paste your input and press Start.** No code needed: you fill in a form (the input). It already has a working example. For example: `apify` in Search terms, domains or Ad Library links. Each start is one run.
3. **Download the results.** When the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

## What it does

Facebook Ad Library Scraper collects ads from the public [Meta Ad Library](https://www.facebook.com/ads/library/). Add keywords, website domains, advertiser pages or ad IDs, pick one or more countries, and get one row per ad: text, creative links, landing page with UTM tags, start date, days running, a 0–100 winner score, variant count and, for EU and political ads, reach and spend ranges.

- Who: page name, page ID, page link, likes and categories.
- What: ad text, headline, call-to-action, format (`IMAGE`, `VIDEO`, `CAROUSEL`, `DCO`, `DPA`…), image and video links, detected language.
- Where it leads: landing link without the Facebook redirect, `landingDomain`, and `utmSource`, `utmMedium`, `utmCampaign`, `utmContent`, `utmTerm`.
- How long and how strong: `startDate`, `endDate`, `daysRunning`, `variantCount` (how many versions Facebook groups together) and `winnerScore` (0–100).
- Political and EU data: spend and impression ranges, "Paid for by" text, and with Add EU reach, demographics and payer details on: EU and UK reach, age, gender, locations, payer and beneficiary.
- Change tracking: `changeStatus` `new` or `seen` and a list of ads that stopped since the last run.

### Good for

- Find a competitor's long-running ads, the ones they keep paying for.
- Collect ad copy, hooks and calls-to-action for a keyword or a niche.
- Watch a list of advertisers every day and get only the new ads.
- Check political and issue ads: who paid, spend range and impressions.
- Compare 2–3 advertisers side by side with the advertiser summary.

## Price

Pay per event. Apify bills you, not us.

| What you pay for | Price | When |
|---|---|---|
| Start fee | $0.001 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
| Ad | $0.0007 (from $0.00049 on paid Apify plans) | One unique ad saved to the Dataset. |
| Ad details | $0.0003 | EU/UK reach, targeting and payer details successfully added to one ad (only when Ad details is on). |
| Saved ad image | $0.001 | One ad image saved to the key-value store (only when Save ad images is on). |
| Search | $0.0003 | One search term, page or Ad Library URL that got an answer from Facebook, even when it has no ads. |
| Already seen ad checked | $0.00025 | One ad skipped because an earlier run already delivered it (only when Only new ads is on). |

- One result: about $0.0017.
- 1,000 results: about $0.70.
- Every day 100 results, for 30 days: about $2.13 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Prices checked on 8 November 2026. Current price: https://apify.com/cliqtomedia/facebook-ad-library?fpr=cliqto

## Questions

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

No. The tool reads the public Ad Library with no login.

### Can I get ad spend for normal ads?

Only where Facebook shows it: political and issue ads, and some ads in the EU and UK.

### Why are there fewer rows than Facebook shows?

Facebook counts every ad version. The tool returns one row per ad and counts the versions in variantCount.

### How fresh is the data?

Each run reads the Ad Library at that moment. `fetchedAt` shows when each ad was read. `daysRunning` counts up to today for active ads.

### Why is `language` empty for some ads?

The language is detected from the ad text. Very short texts give `null`.

## Data fields

- `adArchiveId` (string): Ad Library ID of the ad (ad_archive_id).
- `adLibraryUrl` (string): Public Ad Library link to this ad.
- `pageId` (string): Facebook page ID of the advertiser.
- `pageName` (string): Advertiser page name.
- `pageUrl` (string): Advertiser Facebook page link.
- `pageLikeCount` (integer): Page likes shown with the ad.
- `pageCategories` (array): Page categories, e.g. Clothing (Brand).
- `isActive` (boolean): true while the ad is running.
- `startDate` (string): First day the ad ran (YYYY-MM-DD).
- `endDate` (string): Last day the ad ran for stopped ads; null while active.
- `daysRunning` (integer): Days the ad has run, counting the start day; up to today for active ads.
- `platforms` (array): Where it runs: facebook, instagram, messenger, audience_network, threads, whatsapp.
- `displayFormat` (string): Creative format: IMAGE, VIDEO, CAROUSEL, MULTI_IMAGES, DCO (dynamic creative), DPA (catalog).
- `body` (string): Primary ad text.
- `title` (string): Headline.
- `linkDescription` (string): Link description under the headline.
- `caption` (string): Display link caption (often the domain).
- `ctaText` (string): Call-to-action button text, e.g. Shop now.
- `ctaType` (string): Call-to-action type, e.g. SHOP_NOW, LEARN_MORE.
- `linkUrl` (string): Landing page link (Facebook redirect removed).
- `landingDomain` (string): Domain of the landing page, without www.
- `utmSource` (string): utm_source of the landing link.
- `utmMedium` (string): utm_medium of the landing link.
- `utmCampaign` (string): utm_campaign of the landing link.
- `utmContent` (string): utm_content of the landing link.
- `utmTerm` (string): utm_term of the landing link.
- `images` (array): Image links (Facebook CDN; they expire after some days — use Save ad images to keep them).
- `videos` (array): Videos: hdUrl, sdUrl, previewImageUrl.
- `cardsCount` (integer): Number of carousel or dynamic cards.
- `variantCount` (integer): How many versions of this ad Facebook groups together (1 when only this one).
- `collationId` (string): Facebook group ID shared by the ad versions.
- `spendText` (string): Spend range as shown, e.g. €7K-€8K (political and EU ads).
- `spendLower` (number): Lower bound of spend.
- `spendUpper` (number): Upper bound of spend.
- `currency` (string): Currency of the spend range.
- `impressionsText` (string): Impressions range as shown, e.g. 10K-15K.
- `impressionsLower` (number): Lower bound of impressions.
- `impressionsUpper` (number): Upper bound of impressions.
- `reachText` (string): Estimated audience size text when shown.
- `paidForBy` (string): "Paid for by" line of political and issue ads.

## Input settings

- `searchTerms` (array): Keywords ("running shoes"), website domains ("nike.com") or pasted Ad Library search links. Each entry is one search per country. Up to 50.
- `pageUrls` (array): Facebook page links (facebook.com/nike), numeric page IDs (15087023444), or single-ad links (facebook.com/ads/library/?id=…). Lists every ad of that advertiser. Up to 50.
- `countries` (array): Two-letter country codes where the ads are shown (US, GB, DE, …), or ALL for every country. Each country is a separate search. Up to 10.
- `activeStatus` (string): Which ads to return. Facebook keeps inactive commercial ads in the library for a limited time; political ads for 7 years.
- `adType` (string): Ad Library category. Political ads include spend ranges and the "Paid for by" disclaimer.
- `mediaType` (string): Keep only ads with this kind of creative.
- `maxAds` (integer): Stop each search (one term or page in one country) after this many ads. You pay per ad delivered.
- `sortBy` (string): Order of the ads inside each search. Sorting applies to the ads collected up to Max ads.
- `includeAdDetails` (boolean): For each ad, open the Ad Library detail panel: EU and UK reach, age and gender breakdown, target locations, payer and beneficiary, page verification and Instagram followers. Charged as an extra event per ad that returns details.
- `saveMedia` (boolean): Download the first image (or video thumbnail) of each ad into the run's key-value store, because Facebook image links expire. Charged per saved file.
- `trackChanges` (boolean): Remember which ads each search returned. Every ad gets changeStatus new or seen, and the CHANGES record lists ads that stopped since the last run. Use with a schedule to monitor competitors.
- `onlyNew` (boolean): Deliver only ads not seen by the same search in earlier runs. Each skipped, already seen ad costs a small ad-checked fee instead of the full ad price. Turns on change tracking.
- `stateName` (string): Name of the key-value store that keeps the tracking memory. Use different names for independent monitors. Lowercase letters, digits and hyphens.
- `includeAdvertiserSummary` (boolean): Write an ADVERTISER_SUMMARY record: per advertiser ad count, average days running and winner score, top ads, formats, platforms, CTAs and landing domains. Put 2–3 competitors in one run to compare them. Free.
- `outputFormat` (string): Flat puts every field in its own column. Nested groups fields into advertiser, creative, link, metrics, analysis and details objects.
- `proxyConfiguration` (object): Proxy used to open the Ad Library search page, ad details and images. The default (Apify Proxy, automatic datacenter IPs) works for most runs. Next result pages always go through Apify residential IPs of the search country, because Facebook limits them from datacenter IPs. If a datacenter request keeps failing, the Actor retries it through residential IPs.
- `deliveryConnector` (string): Your Slack, Notion or other MCP connector. After the run the Actor posts a short summary there. Connect services once in Apify Console → MCP connectors.
- `deliveryTarget` (string): Where to post the summary: a Notion page link (each run is added on top of that page) or a Slack channel ID. Leave empty to let the connector decide.

## Step by step on Apify

1. Open the Input tab. Search terms, domains or Ad Library links has `apify` in it (box 1). Replace it with your keyword, a domain such as `nike.com`, or leave it.
2. To list every ad of one advertiser, add the page link (for example `https://www.facebook.com/nike`) in Advertiser pages or ad IDs instead.
3. Keep Countries at `US` and Max ads per search at `10` (boxes 2 and 3), or choose your own. Use `ALL` for every country.
4. Start the run with the button at the bottom of the page.
5. Open the Output tab. The Ads view (box 1) shows page, days running, winner score, variant count (box 2), ad text and landing domain. Export (box 3) downloads CSV, JSON or Excel.

## Use cases

| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Find winning ads in a niche | `searchTerms`, `sortBy` = `winnerScore` | ad | `winnerScore`, `daysRunning`, `variantCount`, `body` | Winner analysis view, export to CSV |
| Spy on a competitor | `pageUrls`, `includeAdvertiserSummary` | ad + advertiser summary | `landingDomain`, `utmCampaign`, `ctaText`, `topAds` | Compare 2–3 pages in one run |
| Daily new-ad alerts | `pageUrls`, `onlyNew`, schedule | new ad | `changeStatus`, `firstSeenAt`, `adLibraryUrl` | Slack or Notion delivery |
| Political ads and EU reach | `adType` = `political_and_issue_ads`, or `includeAdDetails` with an EU country | ad | `paidForBy`, `spendText`, `euTotalReach`, `payers` | EU reach & political view |
| Keep creatives | `saveMedia` | ad + image file | `mediaKeys`, `mediaUrls` | Download from the key-value store |

## Tips

- Start with 10 ads for one keyword. Then raise the limit.
- Turn on tracking and Only new ads, and run daily to see new ads only.
- Turn on Save ad images. Facebook image links expire after some days.

## Limits



- Up to 3,000 ads per search (one entry in one country), 50 search terms, 50 pages and 10 countries per run, and at most 100 searches per run (entries × countries: 50 terms in 2 countries is the maximum). A bigger input fails at the start with `INVALID_INPUT` and only the start event is charged. For more, split the job across runs.
- Each run makes at most 3,000 requests to Facebook. A search page holds about 10 ads, and Add ad details makes one more request per ad. Tested maximum: 3,000 ads without details in about 11 minutes, or 1,000 ads with details in about 10 minutes. With details on, keep the total of all searches under about 2,500 ads per run.
- A run works at most 1 hour (or your run timeout, if shorter), then saves what it has as `PARTIAL`.
- Saved images are limited to 8 MB each; a bigger image is skipped and not charged.
- The run status is FAILED for invalid input, and for `ERROR` (no ads because every search failed) or `PARTIAL` after a source failure. Rows already saved stay in the Dataset and `RUN_SUMMARY` names the reason.
- The Actor shows only what the public Ad Library shows. Commercial ads outside the EU and UK have no spend, reach or targeting data. Facebook keeps stopped commercial ads for a limited time and political ads for 7 years.
- `targetedCountries` is usually empty: the public guest view does not show it.
- Image and video links from Facebook expire after some days. Turn on Save ad images to storage to keep them.

## Sample result

```json
{
  "adArchiveId": "1550534860016399",
  "pageName": "Perfect themes",
  "isActive": true,
  "startDate": "2026-05-19",
  "daysRunning": 166,
  "platforms": ["facebook", "instagram", "audience_network", "messenger", "threads"],
  "variantCount": 1,
  "winnerScore": 75,
  "ctaText": "Install now",
  "landingDomain": "play.google.com",
  "language": "eng",
  "detailsStatus": "ok",
  "euTotalReach": 53398,
  "endDate": null
}
```

## Use it from code

Actor ID: `cliqtomedia/facebook-ad-library`

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/facebook-ad-library").call(run_input={
    "searchTerms": [
        "apify"
    ],
    "countries": [
        "US"
    ]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

```bash
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~facebook-ad-library/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms": ["apify"], "countries": ["US"]}'
```

```python
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/facebook-ad-library")
result = tool.invoke({"run_input": {"searchTerms": ["apify"], "countries": ["US"]}})
print(result)
```

run-sync waits up to 300 seconds; for longer runs start a run and use a webhook. LlamaIndex and MCP: https://cliqtomedia.com/actors/ai-agents/

## Use cases with this tool

- [Know what your competitors do](https://cliqtomedia.com/actors/use-cases/competitor-monitoring/): See what your competitors launch, hire, change and advertise. Every week, without opening their sites.

## Similar tools

- [Google Ads Transparency Scraper - Ad Text, No Login](https://cliqtomedia.com/actors/google-ads-transparency-scraper/)
- [Threads Scraper — Posts, Profiles, Replies & Search](https://cliqtomedia.com/actors/threads-scraper/)
- [Google Autocomplete Scraper: Keyword Suggestions](https://cliqtomedia.com/actors/google-autocomplete-scraper/)
- [Website JSON-LD Structured Data Scraper](https://cliqtomedia.com/actors/website-jsonld-structured-data-scraper/)
- [XML Sitemap URLs Extractor: Indexes & Gzip](https://cliqtomedia.com/actors/xml-sitemap-urls-extractor/)
- [Website Metadata & Open Graph Scraper: Meta Tags & Canonical](https://cliqtomedia.com/actors/website-metadata-open-graph-scraper/)
