# Facebook Ads Library Scraper & Meta Ads API (`atlasdata/facebook-ad-library-scraper-reliable`) Actor

Facebook Ad Library scraper & Meta ads API: track competitor Facebook & Instagram ads by keyword, advertiser page or Ad Library URL, with country, status, category, media, platform, language and date filters. Ad copy, creatives, CTA, landing page, run dates, political spend. $0.50 per 1,000 ads.

- **URL**: https://apify.com/atlasdata/facebook-ad-library-scraper-reliable.md
- **Developed by:** [Christian Machon](https://apify.com/atlasdata) (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.50 / 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 Ads Library Scraper & Meta Ads API

**Pull any brand's Facebook and Instagram ads from the Meta Ad Library (copy, images, videos, landing pages and run dates) for $0.50 per 1,000 ads.**

Scrape ads from the public **Meta Ad Library** (Facebook, Instagram, Messenger, Audience Network, Threads) by **keyword**, by **advertiser page** (page ID, page URL or username) or by pasting **Ad Library URLs**. You can use all of the Ad Library's own filters: **country, active / inactive status, ad category (political & issue, housing, employment, financial), media type, platform, language, exact phrase, date range and sort by impressions**.

Each ad is saved as one flat record: ad ID and Ad Library link, **advertiser (name, page ID, page URL, logo, likes, categories)**, **ad text, headline, link description, CTA, landing page URL**, **image and video URLs** (HD / SD plus preview image), carousel and product cards, **start / end date and days running**, active flag, platforms, display format and how many versions of the ad are running. For **political and issue ads** you also get **"Paid for by"**, **spend range, impressions range, currency** and reach estimate where Meta publishes them.

The Actor uses the same data feed the Ad Library website uses, so it doesn't need a browser. It is quick: about 200 ads per minute on a deep search. Meta rate-limits datacenter IPs, so runs go through **Apify residential proxies**, which are **included in the price**. If an IP gets rate-limited, the Actor switches to a fresh one and picks up from the same page, so nothing is skipped or saved twice.

### Who it's for and use cases

Built for performance marketers and media buyers, agencies running competitor audits, creative strategists building swipe files, market researchers and journalists, and developers or AI agents that need ad-library data through an API.

- **Competitor ad research**: see every ad a brand is running now, which creatives they use, which landing pages they send traffic to and how long each ad has been live. An ad that has run for a long time is usually one that works.
- **Creative inspiration and swipe files**: collect the image and video URLs, headlines and CTAs that ads use for a keyword in any country.
- **Lead generation for agencies**: find businesses that are actively advertising in a niche or country. You get page name, page URL, landing page and number of ads.
- **Political ad transparency and journalism**: spend and impression ranges, "Paid for by" and dates for political and issue ads.
- **Market monitoring**: schedule a daily run and track new ads for your keywords or competitors.
- Pairs with our [**Google Ads Transparency**](https://apify.com/atlasdata/google-ads-transparency-scraper-reliable), [**LinkedIn Ad Library**](https://apify.com/atlasdata/linkedin-ad-library-scraper-reliable) and [**TikTok Ad Library**](https://apify.com/atlasdata/tiktok-ad-library-scraper-reliable) scrapers to cover all the big ad platforms.

### How to use it

1. Enter **search terms** (`running shoes`, `crm software`), and/or **advertiser pages** (`15087023444`, `https://www.facebook.com/nike/`, `nike`), and/or **Ad Library URLs**. Each one is a separate search.
2. Pick a **country** (ISO code like `US`, `GB`, `DE` or a name like `Germany`). `ALL` searches all countries.
3. Optionally set **status** (active by default), **ad category**, **media type**, **platforms**, **languages**, **exact phrase**, **date range** and **sort**.
4. Set **max ads per search** and run.

Ads are saved to the dataset, which has three views: *Overview*, *Creatives* and *Political & issue ads*. A summary for each search goes to the `OUTPUT` record in the key-value store. It shows the status, the number of ads saved, the page ID a username resolved to, and any notes.

#### Paste Ad Library URLs

Set up your search on [facebook.com/ads/library](https://www.facebook.com/ads/library/) and copy the URL from the address bar, for example `https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&media_type=video&q=meal%20delivery&search_type=keyword_unordered`. The Actor reads the keyword or page (`q`, `view_all_page_id`) and the filters in the URL: `country`, `active_status`, `ad_type`, `media_type`, `search_type`, `start_date[min]` / `start_date[max]`, `content_languages`, `publisher_platforms` and `sort_data`. A single-ad URL (`?id=1234567890`) returns just that ad.

#### Advertiser pages

A numeric **page ID** is the most reliable input. To find it, open the advertiser in the Ad Library and copy `view_all_page_id` from the URL. Page URLs with an ID (`profile.php?id=...`, `/Brand-Name-123456789/`) work directly. For a username or vanity URL (`nike`, `facebook.com/NordstromRack`), the Actor looks the page up in the Ad Library and matches the page link. This only works when the page has ads in the library. `OUTPUT` shows the resolved page ID.

### Input examples

Keyword search in the US:

```json
{
  "searchTerms": ["running shoes"],
  "country": "US",
  "maxAdsPerSearch": 200
}
```

All of a brand's active ads, by page ID or URL:

```json
{
  "pageIds": ["15087023444", "https://www.facebook.com/NordstromRack/"],
  "maxAdsPerSearch": 500
}
```

Political and issue ads in the US, with spend, sorted by impressions:

```json
{
  "searchTerms": ["climate"],
  "country": "US",
  "adType": "political_and_issue_ads",
  "activeStatus": "all",
  "sortBy": "impressions"
}
```

Video ads on Instagram shown since 1 October, in English:

```json
{
  "searchTerms": ["skincare"],
  "country": "GB",
  "mediaType": "video",
  "platforms": ["instagram"],
  "languages": ["en"],
  "dateFrom": "2026-10-01"
}
```

### What data you get

Fill rates are measured on 2,551 ads from our final test runs (1,179 advertisers, 75 political / issue ads). Fill rates depend on the ad: video ads have no images, single-image ads have no cards, and commercial ads have no spend data.

| Field | What it is | Filled |
|---|---|---|
| `adArchiveId / adLibraryUrl` | Meta Ad Library ID (stable, used for de-duplication) and public link to the ad | 100% |
| `pageId / pageName / pageUrl` | Advertiser page ID, name and Facebook/Instagram page link | 100% |
| `pageProfilePictureUrl` | Advertiser logo | 100% |
| `pageLikeCount / pageCategories` | Page likes and page categories | 100% |
| `isActive / startDate / endDate / daysRunning` | Whether the ad is live, when it started and stopped (endDate is empty for active ads), days running | 100% |
| `publisherPlatforms` | facebook, instagram, messenger, audience_network, threads | 100% |
| `displayFormat` | IMAGE, VIDEO, DCO, DPA, CAROUSEL, TEXT ... | 100% |
| `bodyText` | Primary ad text | 99% |
| `title` | Headline | 86% |
| `linkDescription / caption` | Link description and display domain | 95% |
| `ctaText / ctaType` | Call-to-action button ("Shop now", SHOP_NOW) | 99% |
| `linkUrl` | Landing page URL (Facebook redirect removed) | 96% |
| `imageUrls` | Image URLs (original and resized) | 52% |
| `videos` | Video URLs: hdUrl, sdUrl, previewImageUrl | 48% |
| `cards` | Carousel / product cards with their own text, link and media | 45% |
| `collationCount / collationId` | Number of versions of this ad Meta groups together | 72% |
| `paidForBy` | "Paid for by" disclaimer - political & issue ads (92% of those) | 3% |
| `spendText / spendMin / spendMax / currency` | Spend range - political & issue ads (96% of those) | 3% |
| `impressionsText / impressionsMin / impressionsMax` | Impressions range - political & issue ads (97% of those) | 3% |
| `reachText / reachMin / reachMax / targetedOrReachedCountries` | Reach estimate and countries, where Meta publishes them | 3% |
| `adCategories / containsAiGeneratedMedia / containsSensitiveContent` | Special ad category and Meta flags | 5% |
| `searchInput / searchCountry / position / scrapedAt` | Search that found the ad, rank and scrape time | 100% |

#### Example record

```json
{
  "adArchiveId": "1016451784037642",
  "adLibraryUrl": "https://www.facebook.com/ads/library/?id=1016451784037642",
  "pageId": "15087023444",
  "pageName": "Nike",
  "pageUrl": "https://www.facebook.com/nike/",
  "pageProfilePictureUrl": "https://scontent-dfw6-1.xx.fbcdn.net/v/t39.35426-6/509357337_4088170881445143_8138324132275675252_n.jpg?stp=dst-jpg_s60x60_tt6&_nc_cat=101&ccb=1-7&_nc_sid=c53f8f&_nc_ohc=Kuq7oqYMn8UQ7kNvwEt7EB1&_nc_oc=AdqKKbmFf2rB54j7hE5t145lJaQMWk-MdxJYlyBAiJ2C01hJQJiLqyPAk_HIT_HU508&_nc_zt=14&_nc_ht=scontent-dfw6-1.xx&_nc_gid=Qp5ICQO_kRZC2cJIDq3MDA&_nc_ss=70289&oh=00_AQO0s2sTs0Z0IgygQLd-8Efzvu4HWoMU4BG4rYZQcDM3cg&oe=6AE6CBC2",
  "pageLikeCount": 39494484,
  "pageCategories": [
    "Sportswear"
  ],
  "isActive": true,
  "startDate": "2025-06-20",
  "endDate": null,
  "daysRunning": 495,
  "publisherPlatforms": [
    "facebook",
    "instagram"
  ],
  "displayFormat": "DPA",
  "bodyText": "Get the gear that goes hard on and off the field.",
  "title": "Nike Air Monarch IV",
  "linkUrl": "https://www.nike.com/us/en_us",
  "linkDescription": null,
  "caption": "NIKE.COM",
  "ctaText": "Shop now",
  "ctaType": "SHOP_NOW",
  "imageUrls": [
    "https://scontent-dfw5-1.xx.fbcdn.net/v/t39.35426-6/509094198_1485897442775736_2519419118144931021_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=c53f8f&_nc_ohc=lEQxhxJZO8QQ7kNvwGRg0p0&_nc_oc=AdojLqgBDYXoi0s-jMTQlNuyjZuRmGqLELuYOlaXCFRyu3zsA-mTFj2UHHSmEE6rxkY&_nc_zt=14&_nc_ht=scontent-dfw5-1.xx&_nc_gid=Qp5ICQO_kRZC2cJIDq3MDA&_nc_ss=70289&oh=00_AQNgYPk5i3iONR1_WV9RW3p8P1gGYDWLPOjYrtjFVcA5wQ&oe=6AE6C835"
  ],
  "videos": [],
  "cards": [
    {
      "title": "Nike Air Monarch IV",
      "body": "Get the gear that goes hard on and off the field.",
      "linkUrl": "https://www.nike.com/t/air-monarch-iv-mens-workout-shoes-extra-wide-p8qNlT/416355-001?dplnk=member",
      "linkDescription": null,
      "caption": "nike.com",
      "ctaText": "Shop Now",
      "ctaType": "SHOP_NOW",
      "imageUrl": "https://scontent-dfw5-1.xx.fbcdn.net/v/t39.35426-6/509094198_1485897442775736_2519419118144931021_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=c53f8f&_nc_ohc=lEQxhxJZO8QQ7kNvwGRg0p0&_nc_oc=AdojLqgBDYXoi0s-jMTQlNuyjZuRmGqLELuYOlaXCFRyu3zsA-mTFj2UHHSmEE6rxkY&_nc_zt=14&_nc_ht=scontent-dfw5-1.xx&_nc_gid=Qp5ICQO_kRZC2cJIDq3MDA&_nc_ss=70289&oh=00_AQNgYPk5i3iONR1_WV9RW3p8P1gGYDWLPOjYrtjFVcA5wQ&oe=6AE6C835",
      "videoHdUrl": null,
      "videoSdUrl": null,
      "videoPreviewImageUrl": null
    }
  ],
  "extraTexts": [],
  "extraLinks": [],
  "collationCount": null,
  "collationId": null,
  "paidForBy": null,
  "adCategories": [],
  "containsAiGeneratedMedia": false,
  "containsSensitiveContent": false,
  "impressionsText": null,
  "impressionsMin": null,
  "impressionsMax": null,
  "spendText": null,
  "spendMin": null,
  "spendMax": null,
  "currency": null,
  "reachText": null,
  "reachMin": null,
  "reachMax": null,
  "targetedOrReachedCountries": [],
  "brandedContentPartner": null,
  "searchInput": "15087023444",
  "searchCountry": "US",
  "position": 1,
  "scrapedAt": "2026-10-27T19:41:46.432Z"
}
```

### Pricing

Pay per event, with no monthly rental:

- **$0.50 per 1,000 ads** ($0.0005 per ad saved).
- **$0.002 per run start** (per GB of memory; the default is 256 MB, so one start event).

Residential proxy traffic and compute are included. For example, 1,000 ads cost about **$0.50**. You only pay for unique ads, never for duplicates. To cap what a run can spend, set *Maximum cost per run* in the run options. The Actor stops cleanly when the cap is reached.

### Reliability and tests

Before we published, we ran a final test matrix of **38 runs on the published build. 38 of 38 succeeded, with 2,551 ads saved.** The runs covered:

- keyword searches in 13 countries (US, GB, DE, FR, ES, NL, CH, BR, IN, AU, CA, JP, MX) and worldwide
- country given as a name ("Germany") and as a lowercase code
- exact phrase, sort by impressions, and active / inactive / all statuses
- media types image, video and none, Facebook-only and Instagram-only, and language and date-range filters
- political & issue (US, GB), housing, employment and financial categories
- advertiser page IDs, page URLs, `profile.php?id=` URLs and bare usernames
- keyword, page and single-ad Ad Library URLs, plus mixed inputs
- runs with 512 MB memory, and a run capped by *Maximum cost per run*, which stopped at exactly the cap

Three of the runs were expected to come back empty: a nonsense keyword, an unknown page, and an EU political search. All three returned a clean `NO_DATA` status with an explanation.

- **Deep searches**: 1,000 ads in 276 s and 500 ads in 133 s, each from a single search.
- **Rate limits**: Meta rate-limited the proxy IP 31 times across 19 runs. Each time the Actor rotated to a fresh IP and continued from the same page. No ads were lost and no duplicates were saved.
- **Charging**: charged ad events matched the saved ads exactly in every run (2,551 / 2,551).
- **Unit tests** cover parsing of ads, Ad Library URLs, page references, spend / impression ranges and country names.

### Limits and caveats

- **Meta rate-limits heavily.** Datacenter IPs are always refused and some residential IPs are refused after a page or two. The Actor rotates IPs and continues from the same page. In our tests every rate limit was recovered from. If Meta tightens limits further, runs get slower before they fail, and `OUTPUT` reports any search that stopped early as `PARTIAL`.
- **Max results**: the Ad Library returns 10 ads per page. A keyword search can be paged deep (we tested 1,000 ads in one search). Meta decides which ads match a keyword. Matching is loose by default, so use *Exact phrase* for strict matching.
- **Spend, impressions and reach** are only published by Meta for **political and issue ads**. For ordinary commercial ads these fields are empty. This is a Meta limit, not a scraper limit.
- **No political ads in the EU**: Meta stopped political and issue ads in the EU in October 2025, and the public Ad Library returns none for EU countries. Political searches work for the US, UK, Canada, Australia, India, Brazil and other non-EU countries. For an EU country, `OUTPUT` explains why a political search is empty.
- **Date range** follows the Ad Library's own filter, which matches ads that were **shown** in the range, not only ads that started in it.
- **Special ad categories** (political, housing, employment, financial) require a country. If you choose one with country `ALL`, the Actor uses `US` and says so in `OUTPUT`.
- **Dynamic product ads** use templates like `{{product.name}}`. When a field is only a template, the Actor uses the first product card's text instead. Real product names and images are in `cards`.
- **Media URLs** are Meta CDN links. They are signed and expire after a while, so download images and videos soon if you need to keep them.
- **Ad text** stays in the language the advertiser used.

### FAQ

**Do I need a Facebook account, cookies or my own proxy?** No. The Ad Library is public, the Actor does not log in, and residential proxies are included.

**Can I run it on a schedule?** Yes. Use Apify Schedules, for example daily for your competitors' page IDs, and send the results to Google Sheets, Slack, a webhook or your database with Apify integrations.

**Can I call it as an API?** Yes. Start the Actor through the Apify API, or use `run-sync-get-dataset-items` to get the ads back in a single HTTP call. AI agents can use it through the Apify MCP server.

**Is scraping the Meta Ad Library legal?** The Ad Library is a public transparency tool that Meta publishes so anyone can inspect ads. The Actor only collects what the Ad Library shows publicly, without logging in. You are responsible for how you use the data and for following applicable laws and Meta's terms.

**Can AI agents use it (MCP)?** Yes. Add the Apify MCP server to Claude, Cursor or any MCP client with `https://mcp.apify.com?tools=atlasdata/facebook-ad-library-scraper-reliable` and the Actor becomes a tool your agent can call.

**How do I track a competitor's ads over time?** Save your input (competitor names, domains or pages) as an Apify task and add a Schedule, for example weekly. Each run writes a new dataset, so you can compare runs or send new ads to Google Sheets, Slack or a webhook with Apify integrations.

### Related atlasdata actors

**Ad library scrapers (competitor ad tracking)**

- [Google Ads Transparency Scraper & Ad Library API](https://apify.com/atlasdata/google-ads-transparency-scraper-reliable)
- [TikTok Ads Library Scraper & TikTok Ads API](https://apify.com/atlasdata/tiktok-ad-library-scraper-reliable)
- [LinkedIn Ads Library Scraper & API](https://apify.com/atlasdata/linkedin-ad-library-scraper-reliable)

**Job data scrapers**

- [Indeed Jobs Scraper & API - 60 Countries](https://apify.com/atlasdata/indeed-jobs-scraper-reliable)
- [Google Jobs Scraper & API - Salary & Apply Links](https://apify.com/atlasdata/google-jobs-scraper-reliable)
- [Glassdoor Jobs Scraper & API - Salaries & Ratings](https://apify.com/atlasdata/glassdoor-jobs-scraper-reliable)

**Search trends**

- [Google Trends Scraper & API - No 429 Errors](https://apify.com/atlasdata/google-trends-scraper-reliable)

# Actor input Schema

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

Keywords to search in the Facebook Ad Library (ad text, advertiser names). Each keyword is a separate search.

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

All ads of an advertiser: numeric Facebook page ID (e.g. 15087023444), a page URL like https://www.facebook.com/nike or an Ad Library URL with view_all_page_id. Page-name URLs are matched to the page ID through the Ad Library itself, so they work for pages that run ads.

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

Paste URLs from facebook.com/ads/library (search pages or single ads, ?id=...). Filters in the URL (country, status, media type, dates, platforms, languages, sorting) override the filters below.

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

ISO 3166 two-letter code where the ads were shown (US, GB, DE, FR, BR, IN...) or ALL for all countries.

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

Active ads are running now; inactive ads have stopped.

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

Special categories require a country (US is used if Country is ALL).

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

Only ads with this kind of creative.

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

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

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

Only ads shown on these platforms: facebook, instagram, audience_network, messenger, threads. Empty = all.

## `languages` (type: `array`):

Two-letter language codes of the ad text (en, de, es...). Empty = all.

## `dateFrom` (type: `string`):

YYYY-MM-DD. Only ads that were shown (delivered) on or after this date - Facebook's own date filter.

## `dateTo` (type: `string`):

YYYY-MM-DD. Only ads that were shown on or before this date.

## `sortBy` (type: `string`):

Order in which Facebook returns the ads.

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

Stop each search after this many unique ads.

## `maxConcurrency` (type: `integer`):

How many searches run at the same time.

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

Residential proxy is required - Facebook rate-limits datacenter IPs. The default uses Apify residential proxy (included in the price).

## Actor input object example

```json
{
  "searchTerms": [
    "running shoes"
  ],
  "country": "ALL",
  "activeStatus": "active",
  "adType": "all",
  "mediaType": "all",
  "exactPhrase": false,
  "sortBy": "relevance",
  "maxAdsPerSearch": 100,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

## `summary` (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": [
        "running shoes"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("atlasdata/facebook-ad-library-scraper-reliable").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"] }

# Run the Actor and wait for it to finish
run = client.actor("atlasdata/facebook-ad-library-scraper-reliable").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"
  ]
}' |
apify call atlasdata/facebook-ad-library-scraper-reliable --silent --output-dataset

```

## MCP server setup

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

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/fOt4xsNgHOnQlw9mq/builds/fpDOPyNLp2SdkXekz/openapi.json
