# Facebook Ads Library Scraper & Competitor Tracker (`miladamirzadeh/facebook-ads-library-tracker`) Actor

Extract public Facebook and Instagram ads by Page ID, keyword, or Meta Ads Library URL. Get copy, creatives, CTAs, landing page URLs, dates, platforms, and advertiser data. Track new, reused, changed, possibly inactive, confirmed inactive, and reactivated ads.

- **URL**: https://apify.com/miladamirzadeh/facebook-ads-library-tracker.md
- **Developed by:** [Milad Amirzadeh](https://apify.com/miladamirzadeh) (community)
- **Categories:** Social media, Automation, E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 ad or change events

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Scrape public ads from the **Facebook Ads Library (Meta Ads Library)** by exact advertiser Page ID, keyword, or a copied Ads Library URL. Export ad copy, headlines, images, videos, carousel cards, CTAs, landing page URLs, dates, platforms, advertiser details, and available transparency data.

Need ongoing ad monitoring? Enable history to see which ads and creatives are **new, reused, changed, possibly inactive, confirmed inactive, or reactivated** across scheduled runs—without treating an incomplete Meta response as evidence that an ad has stopped.

No Facebook login, Meta API token, browser, or destination-site crawling is required.

### What can you do with this Actor?

- **Research Facebook and Instagram ads:** collect creatives, copy, CTAs, media, and landing page URLs.
- **Monitor advertiser activity:** schedule exact Page ID searches and receive only meaningful change events.
- **Distinguish new Ad IDs from previously seen creatives:** tell a new ad instance from a creative already observed in the same history.
- **Build a creative swipe file:** export structured ad data to JSON, CSV, Excel, or your own database.
- **Track copy, media, and destination URL changes:** detect changes to messaging, creative assets, or landing page URLs.
- **Automate ad intelligence workflows:** run through the Apify API, schedules, webhooks, Make, Zapier, or other integrations.

### Quick start

1. Use the small prefilled example, or replace it with a **Facebook Page ID**, **search term**, or **Meta Ads Library URL**.
2. Choose the country where the ads should be visible.
3. Keep **Raw ads** selected for a one-time scrape. Enable history only for recurring monitoring.
4. Click **Start**. Results appear in the Dataset and can be downloaded in multiple formats.

Not sure which setup to use?

| Goal | Recommended input | History | Output |
|---|---|---:|---|
| Research one known advertiser | Page ID | Off | Raw ads |
| Discover ads across a market | Search term | Off | Raw ads |
| Repeat filters from Meta Ads Library | Copied Ads Library URL | Off | Raw ads |
| Monitor one competitor over time | Page ID | On | Raw ads and changes |
| Send only changes into an automation | Page ID | On | Changes only |

The simplest raw scrape looks like this:

```json
{
  "searchTerms": ["running shoes"],
  "countries": ["US"],
  "maxResultsPerTarget": 100,
  "outputMode": "raw"
}
```

### What data does it extract?

Each raw result represents a real ad returned by Meta and can include:

- Meta archive/library ID, Page ID, Ad ID, and collation identifiers;
- advertiser name, page category, profile URL, profile image, and page likes;
- active status, start date, and source-backed end date for inactive ads;
- ad body, headline, description, CTA type, and CTA text;
- display URL, Meta's source click URL, and ordered source-backed landing-page URLs;
- deduplicated images, videos, video previews, and carousel cards;
- Facebook, Instagram, Messenger, and other publisher platforms reported by Meta;
- targeted/reached countries and available public transparency fields;
- Ad, Asset, and Creative identity objects with explicit confidence and limitations;
- optionally, the complete parsed source object under `raw` when `includeRawPayload` is enabled.

Fields that Meta does not provide are returned as `null` or an empty collection. The Actor does not manufacture spend, impressions, targeting, or other unavailable values.

### Input guide

#### Choose what to scrape

You can use one or combine several input methods:

| Input | Best for | Example |
|---|---|---|
| `pageIds` | Exact advertiser scraping and scheduled monitoring | `"101694774572"` |
| `searchTerms` | Discovering ads by brand, product, or market keyword | `"running shoes"` |
| `startUrls` | Reproducing a search configured in Meta Ads Library | A full `facebook.com/ads/library/...` URL |

For reliable competitor monitoring, prefer `pageIds`. Keyword results can change because of search ranking, so keyword absence is never treated as proof that an ad stopped.

#### Filters and limits

| Input | What it controls | Recommended use |
|---|---|---|
| `countries` | Countries where the ads should be visible, such as `US`, `GB`, `DE`, or `ALL` | This is the audience country, not the advertiser's home country |
| `maxResultsPerTarget` | Maximum ads returned for each Page ID/keyword and country combination | Use a small limit for tests; leave empty for complete inactivity monitoring |
| `activeStatus` | All, active, or inactive ads | Use `all` for full history; `active` for current creative research |
| `startDateMin` / `startDateMax` | Ad start-date range | Optional |
| `adType`, `mediaType`, `contentLanguages`, `publisherPlatforms` | Advanced Meta source filters | Leave at defaults unless you need a specific source filter |
| `includeRawPayload` | Adds Meta's complete parsed source object under `raw` | Leave off for a smaller, cleaner Dataset; enable only for diagnostics or custom parsing |

One Page ID with two countries creates two targets. The result limit applies separately to each target.

#### Recommended settings for your first run

The Input tab starts with one Page ID, `US`, and a limit of `3` ads. This keeps the first test quick and inexpensive. Replace the Page ID with your advertiser when ready. Remove `maxResultsPerTarget` only when you need a complete advertiser history.

### Raw scraping examples

#### Scrape an advertiser by Page ID

```json
{
  "pageIds": ["101694774572"],
  "countries": ["US"],
  "activeStatus": "all",
  "maxResultsPerTarget": 100,
  "tracking": false,
  "outputMode": "raw"
}
```

#### Search multiple markets by keyword

```json
{
  "searchTerms": ["running shoes", "fitness app"],
  "countries": ["US", "GB"],
  "activeStatus": "active",
  "maxResultsPerTarget": 250,
  "outputMode": "raw"
}
```

#### Use a copied Meta Ads Library URL

```json
{
  "startUrls": [
    {
      "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&view_all_page_id=101694774572"
    }
  ],
  "outputMode": "raw"
}
```

### Competitor monitoring and change detection

Set `tracking` to `true`, choose a stable `trackingNamespace`, and reuse that namespace in every scheduled run of the same monitoring program.

#### Receive only changes

```json
{
  "pageIds": ["101694774572"],
  "countries": ["US"],
  "activeStatus": "all",
  "tracking": true,
  "trackingNamespace": "shoe-carnival-us",
  "outputMode": "changes"
}
```

#### Receive raw ads and changes separately

```json
{
  "pageIds": ["101694774572"],
  "countries": ["US"],
  "activeStatus": "all",
  "tracking": true,
  "trackingNamespace": "shoe-carnival-us",
  "outputMode": "rawAndChanges"
}
```

Runs with different namespaces keep independent histories. Do not reuse one namespace for unrelated brands or monitoring setups.

#### Change events

| Event | Meaning |
|---|---|
| `NEW_AD` | A previously unseen ad instance appeared |
| `NEW_CREATIVE` | A creative fingerprint has never been seen in this history |
| `REUSED_CREATIVE` | A new Ad ID reused an existing creative |
| `COPY_CHANGED` | Meaningful ad text, headline, description, or CTA changed |
| `MEDIA_CHANGED` | Image, video, or carousel identity changed |
| `LANDING_PAGE_CHANGED` | The canonical destination URL changed |
| `POSSIBLY_INACTIVE` | An ad was missing from one complete, eligible Page ID run |
| `INACTIVE_CONFIRMED` | Meta explicitly reported inactivity, or the ad was missing from two eligible runs |
| `REACTIVATED` | A previously confirmed inactive ad appeared again |

The first tracked run intentionally emits discovery events such as `NEW_AD` and `NEW_CREATIVE`. This gives monitoring workflows an initial inventory instead of an unexplained empty result. Later unchanged runs can produce an empty Changes Dataset—this means no change was detected, not that the run failed.

### Output modes

| `outputMode` | Default Dataset | Separate Changes Dataset |
|---|---|---|
| `raw` | Raw ad records | Not used |
| `changes` | Change events only | Not used |
| `rawAndChanges` | Raw ad records | Change events |

`changes` and `rawAndChanges` require `tracking: true`. The input is validated before any request is sent.

### Example raw result

```json
{
  "recordType": "ad",
  "pageName": "Example Brand",
  "pageId": "123456789",
  "archiveId": "987654321",
  "isActive": true,
  "headline": "Explore the new collection",
  "body": "Designed for everyday movement.",
  "ctaText": "Shop Now",
  "sourceClickUrl": "https://example.com/collection",
  "destinationUrl": "https://example.com/collection",
  "destinationUrls": ["https://example.com/collection"],
  "platforms": ["FACEBOOK", "INSTAGRAM"],
  "creativeIdentity": {
    "version": "v2",
    "confidence": "exact",
    "fingerprint": "v2:creative:...",
    "limitations": []
  }
}
```

### Example change event

```json
{
  "eventType": "LANDING_PAGE_CHANGED",
  "observedAt": "2026-08-15T05:53:34Z",
  "adIdentity": {
    "archiveId": "987654321",
    "pageId": "123456789"
  },
  "creativeIdentity": {
    "version": "v2",
    "confidence": "exact",
    "fingerprint": "v2:creative:...",
    "limitations": []
  },
  "details": {
    "from": "v2:landing:old-fingerprint",
    "to": "v2:landing:new-fingerprint"
  }
}
```

### How tracking distinguishes a new ad from a new creative

A new Facebook Ad Library ID does not always mean a new creative. This Actor keeps three concepts separate:

- **Ad identity:** the specific ad instance (`pageId + archiveId`).
- **Asset identity:** the image, video, or carousel media.
- **Creative identity:** the meaningful combination of media, copy, headline, CTA, and landing page.

Validated Meta video asset identifiers are used when available. Images without a stable source identifier are identified by complete-file SHA-256, not by temporary CDN URLs. Reused media is downloaded only once per run.

Meta can repeat identical carousel/card objects inside one source record. The Actor removes only semantically identical duplicates before media verification, output, and fingerprinting, while preserving the first-seen order and retaining distinct cards that share an image but have different copy or destinations. The optional `raw` payload remains unchanged.

`creativeIdentity.confidence` is `exact` when the required identity evidence is complete. If an asset cannot be verified, the raw ad is still returned, but the Actor marks confidence as `limited` and avoids definitive new/reused-creative claims.

Fingerprint algorithm upgrades use a new identity version and rebaseline already-known ads without emitting artificial copy, media, or landing-page change events.

### How tracking avoids false inactive alerts

Meta can block a session, change a response contract, or return an incomplete page. A missing ad is therefore evaluated only when the Page ID run is complete and trustworthy.

- Truncated, blocked, rate-limited, partial, or changed-contract runs never create missing/inactive transitions.
- Keyword absence never creates inactivity events.
- One eligible complete miss produces `POSSIBLY_INACTIVE`.
- A second consecutive eligible miss produces `INACTIVE_CONFIRMED`.
- An explicit `is_active: false` from Meta can confirm inactivity immediately.

Every run stores a `RUN_SUMMARY` with source health, record counts, retries, media verification metrics, output counts, and history commit status. The Actor never pushes fake error rows into your ad Dataset.

### Pricing

Pricing is based on visible Default Dataset items plus a small run-start fee. Platform compute, storage operations, and proxy usage are included:

- **$0.005 per run**;
- **$0.00075 per Default Dataset item on the Free plan** (`$0.75 per 1,000 items`);
- **$0.00070 per item on Starter**, **$0.00065 on Scale**, and **$0.00060 on Business**.

In `raw` and `rawAndChanges` mode, a billed Default Dataset item is one raw ad. In `changes` mode, it is one change event. The separate Changes Dataset in `rawAndChanges` mode is not billed as an additional result.

The first tracking baseline can produce multiple discovery events for one ad. Later `changes` runs typically return only actual changes. Use Apify's maximum charge per run setting if you need a hard budget cap.

Free-plan examples:

- 100 raw ads: `$0.005 + (100 × $0.00075) = $0.080`;
- an unchanged changes-only run: `$0.005`;
- 10 change events: `$0.005 + (10 × $0.00075) = $0.0125`.

### Performance and cost behavior

The Actor uses direct HTTP extraction instead of launching a browser. Source requests reuse a bounded residential session, while public media files use a separate direct CDN session so image/video bytes do not inflate residential proxy costs.

In a production acceptance run on 15 August 2026, a bounded test returned **40 ads from two exact Page ID targets in 9.2 seconds total runtime**, with zero retries or restarts, about 75 MiB peak memory, and approximately `$0.0032` in Apify platform usage before Store event pricing. This is one measured workload, not a speed or cost guarantee.

Actual throughput and platform cost vary with targets, countries, result volume, media size, proxy conditions, and Meta response behavior. Use each run's `RUN_SUMMARY` and Apify usage details when measuring your own workload.

### API and integrations

You can run this Facebook Ads Library scraper manually, on a schedule, through the Apify API, or from integrations such as Make and Zapier. Dataset results can be exported as JSON, CSV, Excel, XML, RSS, or HTML.

A typical scheduled competitor tracker should:

1. use exact Page IDs;
2. keep the same countries, filters, and `trackingNamespace`;
3. run at a consistent interval;
4. use `changes` to receive only events, or `rawAndChanges` when both outputs are needed.

### FAQ

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

No. The Actor reads public Meta Ads Library web data and does not require Facebook login or Graph API approval.

#### Can it scrape Instagram ads?

Yes. Meta Ads Library records can include placements reported for Facebook, Instagram, Messenger, and other Meta surfaces. `platforms` shows the placements available in the source record.

#### Should I use a Page ID or a keyword?

Use a Page ID when you know the advertiser and want reliable scheduled monitoring. Use keywords to discover ads across multiple advertisers or research a market.

#### How do I find a Facebook Page ID?

Open the advertiser in Meta Ads Library and copy the numeric value from the `view_all_page_id` parameter in the URL. You can also paste the complete Ads Library URL into `startUrls`.

#### Why is my Changes Dataset empty?

An empty Changes Dataset usually means the run succeeded but no new or changed ads were detected. Check `RUN_SUMMARY` to confirm source health and output counts.

#### Why are some values null?

Meta does not expose every transparency field for every ad, country, or ad category. Missing source values remain `null`; the Actor does not replace them with estimates.

For active ads, `endDate` is intentionally `null`. Meta's active-result `end_date` can move with the query window and is not reliable evidence of a scheduled stop. Inactive ads retain the source-backed end date when available; the untouched value is also available in `raw.end_date` when `includeRawPayload` is enabled.

#### Why do some ads contain `{{product.name}}` or similar text?

Meta returns template variables at the ad level for some dynamic product ads. These are source values, not invented placeholders. The resolved product headlines, copy, media, and destination URLs are available in the deduplicated `cards` array.

#### What is the difference between `sourceClickUrl`, `destinationUrl`, and `destinationUrls`?

`sourceClickUrl` is the canonicalized click URL reported by Meta and may still be a DoubleClick-style redirect. `destinationUrls` contains all ordered, unique destination URLs that can be determined directly from the ad and its cards without crawling another website. `destinationUrl` is populated only when a direct primary destination exists or the result is unambiguous. Each card follows the same separation through `cards[].sourceClickUrl` and `cards[].destinationUrl`. Unresolved redirect wrappers are never presented as landing pages.

#### Does the Actor download media files into storage?

It returns media URLs and, when tracking requires identity verification, streams supported assets to calculate identity. It does not save full media files as separate Dataset attachments.

#### What is `includeRawPayload`?

It adds Meta's complete parsed source record under `raw` for advanced diagnostics or custom parsing. It is off by default to keep Datasets smaller and easier to use; all documented normalized fields remain available without it.

#### Are Facebook CDN URLs permanent?

No. Meta CDN URLs can expire or change. Use them as locators, not stable identifiers. The Actor's Creative identity does not rely on the CDN URL alone.

#### Is this an official Meta API?

No. This is an independent Facebook Ads Library API alternative built from Meta's public web interface. Meta can change its private web contract; source-contract failures are reported explicitly rather than returned as silent empty results.

#### Is scraping Meta Ads Library legal?

The Actor extracts publicly available advertising data and does not access private Facebook accounts. You are responsible for using the data lawfully and complying with applicable privacy, intellectual-property, platform, and data-protection rules.

### Support

If a run fails, open the run's `RUN_SUMMARY` first. It distinguishes blocks, rate limits, partial results, valid empty results, and source-contract changes. For reproducible problems, create an issue with the Run ID, input with sensitive values removed, and the summary diagnostics.

# Actor input Schema

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

The advertiser's numeric Facebook Page ID. Use this when you want ads from one exact brand or reliable scheduled monitoring. You can find it in a Meta Ads Library URL after view\_all\_page\_id=. Example: 101694774572.

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

A brand, product, offer, or market phrase to search across advertisers, such as running shoes. Best for discovery and market research. For monitoring one known advertiser, use its Page ID instead.

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

Paste a full facebook.com/ads/library URL exactly as it appears in your browser. Filters already present in the URL are preserved. A URL containing view\_all\_page\_id identifies one exact advertiser; a general search URL is for discovery only.

## `countries` (type: `array`):

Choose the audience country where the ads should be visible—not the advertiser's home country. Enter two-letter codes such as US, GB, or DE, or ALL for Meta's all-countries view. Every advertiser/search is checked separately in each country.

## `maxResultsPerTarget` (type: `integer`):

Maximum ads returned for each advertiser or search term in each country. The prefilled value keeps the first test small. Remove the limit for complete advertiser monitoring; a limited run will not claim that missing ads became inactive.

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

Filter by the status reported by Meta: all ads, ads currently running, or ads Meta marks inactive. Choose All ads when building a complete advertiser history.

## `startDateMin` (type: `string`):

Optional earliest ad start date. Leave empty to include older ads.

## `startDateMax` (type: `string`):

Optional latest ad start date. Leave empty for no upper date limit.

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

Meta Ads Library ad\_type value. Keep all for normal commercial-ad research. Change this only when you know the exact value used by a Meta Ads Library URL.

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

Optional Meta Ads Library media\_type value. Leave empty to include images, videos, carousels, and other available formats.

## `contentLanguages` (type: `array`):

Optional two-letter ad-content language codes, for example en or de. This filters the language of the ad itself, not the country where it is shown. Leave empty for all languages.

## `publisherPlatforms` (type: `array`):

Optional placements such as facebook or instagram. Leave empty to include every platform reported by Meta for the ad.

## `tracking` (type: `boolean`):

Compare this run with earlier runs that use the same History group name. Enable it to detect new ads, reused creatives, copy/media/landing-page changes, inactivity, and reactivation.

## `trackingNamespace` (type: `string`):

A stable label that connects related scheduled runs, such as nike-us or client-a-weekly. Keep it unchanged for the same monitoring job. Use a different name for an unrelated brand, country set, or filter setup.

## `outputMode` (type: `string`):

Raw ads: full ad records for a normal scrape. Changes only: just new/changed/inactive/reactivated events. Raw ads and changes: full ads in the Default Dataset plus events in a separate Changes Dataset.

## `includeRawPayload` (type: `boolean`):

Add Meta's complete parsed source object under raw in every ad record. Leave this off for smaller, cleaner Datasets. Enable it only when you need source-level fields for diagnostics, custom parsing, or future migrations.

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

The preselected Apify Residential proxy is recommended for reliable Meta Ads Library access. Most users should leave this unchanged. Public media files are fetched directly so their bytes do not create unnecessary residential-proxy charges.

## `concurrency` (type: `integer`):

How many advertiser/search/country combinations run at once. The default is a safe balance. Higher values may finish sooner but open more proxy sessions.

## `mediaConcurrency` (type: `integer`):

How many image or video files can be verified at once when history is enabled. The default balances speed, memory, and network use.

## `requestTimeoutSecs` (type: `integer`):

How long one Meta or media request may wait before it is treated as timed out. Increase only for unusually slow network conditions.

## `maxRequestAttempts` (type: `integer`):

Maximum bounded attempts for temporary connection failures, selected server errors, and rate limits. Missing optional ad fields do not trigger a full retry.

## `checkpointEveryPages` (type: `integer`):

Save restart progress after this many completed Meta result pages. Lower values preserve finer progress after an interrupted run but create more storage operations.

## `maxMediaBytes` (type: `integer`):

Maximum size downloaded to verify one image or video when history is enabled. The default 100000000 equals 100 MB. Larger assets still appear in raw results, but the Actor avoids definitive new/reused creative claims when it cannot verify the full file.

## Actor input object example

```json
{
  "pageIds": [
    "101694774572"
  ],
  "searchTerms": [
    "running shoes"
  ],
  "startUrls": [
    {
      "url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&view_all_page_id=101694774572"
    }
  ],
  "countries": [
    "US",
    "GB"
  ],
  "maxResultsPerTarget": 100,
  "activeStatus": "all",
  "startDateMin": "2026-01-01",
  "startDateMax": "2026-12-31",
  "adType": "all",
  "contentLanguages": [
    "en"
  ],
  "publisherPlatforms": [
    "facebook",
    "instagram"
  ],
  "tracking": false,
  "trackingNamespace": "competitor-shoe-brand-us",
  "outputMode": "raw",
  "includeRawPayload": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "concurrency": 4,
  "mediaConcurrency": 2,
  "requestTimeoutSecs": 30,
  "maxRequestAttempts": 3,
  "checkpointEveryPages": 5,
  "maxMediaBytes": 100000000
}
```

# Actor output Schema

## `defaultDataset` (type: `string`):

Raw ads in raw/rawAndChanges mode, or monitoring events in changes mode.

## `changesDataset` (type: `string`):

Monitoring events when outputMode is rawAndChanges.

## `runSummary` (type: `string`):

Counts, target health, retries, identity coverage, output totals, and history commit status.

# 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 = {
    "pageIds": [
        "101694774572"
    ],
    "countries": [
        "US"
    ],
    "maxResultsPerTarget": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("miladamirzadeh/facebook-ads-library-tracker").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 = {
    "pageIds": ["101694774572"],
    "countries": ["US"],
    "maxResultsPerTarget": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("miladamirzadeh/facebook-ads-library-tracker").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 '{
  "pageIds": [
    "101694774572"
  ],
  "countries": [
    "US"
  ],
  "maxResultsPerTarget": 3
}' |
apify call miladamirzadeh/facebook-ads-library-tracker --silent --output-dataset

```

## MCP server setup

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

```

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/2a6Wfxbxbo9u4Q1Ci/builds/tLGChgSG0cZ98M4Pf/openapi.json
