# LinkedIn Ad Library Scraper (`aboo.script/linkedin-ads-scraper`) Actor

\[💰$3.5 / 1K] ⚡ Fast LinkedIn Ad Library scraper that works on Cloudflare-protected pages. No login, no API key. Scrape ads by keyword, advertiser, country, date or URL: advertiser, payer, ad copy, headline, CTA, landing page, images, videos, run dates, impressions by country and targeting.

- **URL**: https://apify.com/aboo.script/linkedin-ads-scraper.md
- **Developed by:** [Aboo Script](https://apify.com/aboo.script) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.45 / 1,000 results

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?

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

## LinkedIn Ad Library Scraper

![LinkedIn Ad Library Scraper](https://i.ibb.co/27XCPz28/linkedin-ads-banner.png)

**LinkedIn Ad Library Scraper** extracts ads from the [LinkedIn Ad Library](https://www.linkedin.com/ad-library/) into clean, structured data you can download as JSON, CSV, Excel, or HTML. Paste an Ad Library search URL or type a few keywords, and get the advertiser, who paid for the ad, ad copy, headline, call to action, landing page, images and videos, run dates, impressions by country, and targeting for every ad. No account or login required.

### Introduction

The [LinkedIn Ad Library](https://www.linkedin.com/ad-library/) is LinkedIn's public archive of the ads that companies and people promote on the platform. It shows the creative of each ad and, for ads shown in the European Union, when it ran, how many impressions it got, in which countries, and how it was targeted. It is a goldmine for B2B marketers who want to see what competitors are advertising.

This actor collects the same public information you see in your browser and turns it into a ready-to-use dataset. You can run it once, schedule it to run daily, or connect it to your own tools. It works on the Cloudflare-protected Ad Library pages.

### What data can you extract from the LinkedIn Ad Library?

- 🏢 Advertiser name, LinkedIn page URL, company ID, and logo
- 👤 Person who posted the ad (for thought leader ads), with profile URL and headline
- 💳 Who paid for the ad
- 📝 Ad copy, headline, article description, and call to action
- 🔗 Landing page URL
- 🖼️ Images, videos with their cover image, carousel cards, and document pages
- 🗂️ Ad format (single image, video, carousel, document, article, follower ad, and more)
- 📅 Start date, end date, and number of days the ad ran
- 📊 Total impressions (as shown and as numeric minimum and maximum) and impressions share by country
- 🎯 Targeting: included and excluded languages and locations, plus which other targeting types were used
- 🔗 Direct URL and ID of each ad

### Use Cases

- 🕵️ **Competitor monitoring**: see every ad a competitor runs on LinkedIn, the message they use, and where they send traffic.
- 📈 **Market research**: track which topics, offers, and formats are being promoted in your industry.
- 🎨 **Creative inspiration**: collect headlines, copy, and visuals from successful B2B campaigns.
- 🤝 **Lead generation**: find companies that actively spend on LinkedIn advertising, and the agencies that pay for their ads.
- 🤖 **AI and automation**: feed clean, structured ad data into spreadsheets, dashboards, or AI workflows.

### How to scrape the LinkedIn Ad Library step by step

1. Paste one or more LinkedIn Ad Library URLs into **Start URLs**, or type keywords into **Search queries**.
2. Optionally set the search filters (advertiser, paid by, countries, date range, sort order) for your keywords.
3. Set **Maximum number of results** to how many ads you want per URL or per query.
4. Click **Start** and wait for the run to finish.
5. Download your data in JSON, CSV, Excel, or HTML from the **Output** tab.

### Input

- **Start URLs**: LinkedIn Ad Library URLs to scrape. Supported pages: search result pages (`https://www.linkedin.com/ad-library/search?...`) and single ad pages (`https://www.linkedin.com/ad-library/detail/...`). Any filters you apply on the website (advertiser, payer, keyword, countries, dates, and more filters) are kept in the results.
- **Search queries**: keywords to search in the Ad Library, one per line. Each query is scraped separately.
- **Advertiser**: only ads from this company, for example `microsoft`. Applies to search queries.
- **Paid by**: only ads paid for by this company or agency. Applies to search queries.
- **Countries**: only ads shown in these countries. Applies to search queries.
- **Date range**: only ads that ran in the last 30 days, the current month, the current year, or the last year. Applies to search queries.
- **Custom start date** and **Custom end date**: a custom date range instead of a preset (both dates are needed). Applies to search queries.
- **Sort order**: newest or oldest ads first. Applies to search queries.
- **Maximum number of results**: how many ads to collect for each start URL or search query.
- **Proxy configuration**: residential proxies are required, because LinkedIn refuses most other connections. The default setting already uses them.

You can use start URLs, search queries, or both in the same run. To get all ads of one company, paste its Ad Library search URL, for example `https://www.linkedin.com/ad-library/search?accountOwner=microsoft`.

### Input Examples

Scrape all ads of an advertiser from an Ad Library search URL:

```json
{
  "startUrls": [{ "url": "https://www.linkedin.com/ad-library/search?accountOwner=microsoft" }],
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

Search by keywords:

```json
{
  "searchQueries": ["cloud security"],
  "sortOrder": "newest",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

Search by keywords with filters:

```json
{
  "searchQueries": ["cloud security"],
  "advertiser": "microsoft",
  "countries": ["DE", "FR"],
  "dateRange": "last-30-days",
  "sortOrder": "newest",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Output

Each ad is saved as one item in the dataset. Here is an example of a single item:

```json
{
  "url": "https://www.linkedin.com/ad-library/detail/1594261693",
  "adId": "1594261693",
  "adFormat": "Single Image Ad",
  "creativeType": "SPONSORED_STATUS_UPDATE",
  "advertiserName": "Aptranet",
  "advertiserUrl": "https://www.linkedin.com/company/98406148",
  "advertiserId": "98406148",
  "advertiserLogoUrl": "https://media.licdn.com/dms/image/v2/D4D0BAQF_LnAehkr1fA/company-logo_100_100/B4DaFXB3DLLAAI-/0/1792461468121/aptranet_logo?e=1794441600&v=beta&t=ofNFocWhWr80z3OL8H2bqHm5dyWOBnz90ZZfn1Dwni0",
  "postedByName": null,
  "postedByUrl": null,
  "postedByHeadline": null,
  "paidBy": "APTRANET LIMITED",
  "commentary": "Meet Aptranet Cloud, a cloud platform designed to help you scale globally, seamlessly.\n\nPowered by our global network spanning over 210 locations, we bring performance, reliability, and security toget...",
  "headline": "Turn Global Traffic into Local Performance",
  "description": null,
  "callToAction": "Learn more",
  "destinationUrl": "https://cloud.aptranet.com/",
  "imageUrls": [
    "https://media.licdn.com/dms/image/v2/D4D10AQFFwFBkxoFgtg/image-shrink_1280/B4DaF0xS2JHMAc-/0/1792960442144/AptranetCloud?e=2147483647&v=beta&t=-AhvBIOkB4FXFEzCK-yX_2YYsfugG-v517V0LjDSdrQ"
  ],
  "videoUrls": [],
  "videoPosterUrl": null,
  "carouselCards": [],
  "document": null,
  "startDate": "2026-10-25T00:00:00.000Z",
  "endDate": "2026-10-26T00:00:00.000Z",
  "daysRunning": 2,
  "totalImpressions": "50k-100k",
  "impressionsMin": 50000,
  "impressionsMax": 100000,
  "impressionsByCountry": [],
  "targeting": [
    { "parameter": "Language", "included": ["English"], "excluded": [] },
    { "parameter": "Location", "included": ["European Union"], "excluded": [] }
  ],
  "targetingFlags": [
    { "parameter": "Audience", "targeted": false, "excluded": false },
    { "parameter": "Demographic", "targeted": false, "excluded": false },
    { "parameter": "Company", "targeted": false, "excluded": false },
    { "parameter": "Education", "targeted": false, "excluded": false },
    { "parameter": "Job", "targeted": false, "excluded": false },
    { "parameter": "Member Interests and Traits", "targeted": false, "excluded": false }
  ]
}
```

When LinkedIn shows the country split, `impressionsByCountry` lists each country with its share, for example `{ "country": "Germany", "percentage": 21, "percentageText": "21%" }`. Video ads also return `videoUrls` and `videoPosterUrl`, carousel ads return `carouselCards` (title and image of each card), and document ads return `document` (title, page count, and page images).

You can download the dataset in JSON, CSV, Excel, XML, or HTML, or access it through the Apify API.

### Notes

- Residential proxies are required. Runs without them, or with datacenter proxies, are refused by LinkedIn most of the time.
- Run dates, impressions, impressions by country, and targeting are only published by LinkedIn for ads shown in the European Union. For other ads these fields are `null` or empty.
- Impressions are ranges set by LinkedIn (for example `50k-100k` or `> 1M`). Country shares below 1% are shown as `< 1%` with `percentage` set to `null`.
- Only Ad Library search and ad pages are supported. Other LinkedIn URLs, such as company pages, are skipped.
- The search filters (advertiser, paid by, countries, dates, sort order) apply to search queries only. Start URLs keep the filters already in the URL.
- Ad copy, headline, and call to action are returned in the language of the ad.

### Why use the LinkedIn Ad Library Scraper?

- ✅ **No login needed**: works with public data only, so there is no LinkedIn account to risk.
- 🛡️ **Works on Cloudflare-protected pages**: collects the Ad Library reliably where simple tools get blocked.
- 🎯 **Keeps your filters**: paste any Ad Library search URL from your browser and get exactly what you see there.
- 📦 **Full ad details in one item**: creative, landing page, run dates, impressions, countries, and targeting together.
- 🧹 **Clean data**: numbers are real numbers, dates use one standard format, and text is free of HTML.
- 💸 **Pay for what you need**: set a result limit per URL or query and keep every run small and cheap.

### FAQ

#### How many results can I scrape?

You can set any number in **Maximum number of results**. The actor keeps going until it reaches your limit or runs out of ads for that search.

#### Do I need a LinkedIn account?

No. The actor only collects publicly available data from the Ad Library. You do not need to log in or provide any account details.

#### How do I get all ads of one company?

Open the Ad Library, search for the company in the **Company or advertiser** box, and paste the resulting URL into **Start URLs**. You can also type a keyword and set **Advertiser** to the company name.

#### Can I scrape data on a schedule?

Yes. Use Apify Schedules to run the actor every hour, day, or week, and get fresh ads automatically.

#### Can I request a new feature or filter?

Yes. Right now the actor supports start URLs, search queries, and the advertiser, paid by, countries, date, and sort filters. If you need other inputs, such as targeting filters, get in touch and they can be added.

#### Can I get a custom or private version?

Yes. The actor can be customized for your workflow, delivered as a private version, or a new scraper can be built for a different website. Use the contact details below.

***

**Need help or want a custom solution?**

- 📧 Email: aboo.script@gmail.com
- 🧩 More scrapers: [Apify profile](https://apify.com/aboo.script)

### Image Credit

Image credit: [LinkedIn Ad Library](https://www.linkedin.com/ad-library/)

# Actor input Schema

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

LinkedIn Ad Library search URLs (with any filters applied on the site) or ad detail URLs, e.g. https://www.linkedin.com/ad-library/search?accountOwner=microsoft or https://www.linkedin.com/ad-library/detail/1592204423.

## `searchQueries` (type: `array`):

Keywords to search in the LinkedIn Ad Library (ad text and advertiser). Each query is scraped separately with the filters below.

## `advertiser` (type: `string`):

Only ads from this advertiser (company name), e.g. "microsoft". Applies to search queries only; start URLs keep their own filters.

## `payer` (type: `string`):

Only ads paid for by this entity. Applies to search queries only.

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

Only ads shown in these countries. Leave empty for all countries. Applies to search queries only.

## `dateRange` (type: `string`):

Only ads that ran in this period. Leave empty for all time. Applies to search queries only.

## `startDate` (type: `string`):

Start of a custom date range (YYYY-MM-DD). Needs an end date; do not combine with Date range. Applies to search queries only.

## `endDate` (type: `string`):

End of a custom date range (YYYY-MM-DD). Applies to search queries only.

## `sortOrder` (type: `string`):

Order of the results. Applies to search queries only.

## `maxResults` (type: `integer`):

Maximum number of ads to scrape per start URL or search query.

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

Proxy settings. Residential proxy is required: LinkedIn refuses most other addresses. The scraper keeps switching addresses until it finds ones that work.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.linkedin.com/ad-library/search?accountOwner=microsoft"
    }
  ],
  "searchQueries": [
    "cloud security"
  ],
  "sortOrder": "newest",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        {
            "url": "https://www.linkedin.com/ad-library/search?accountOwner=microsoft"
        }
    ],
    "searchQueries": [
        "cloud security"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("aboo.script/linkedin-ads-scraper").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 = {
    "startUrls": [{ "url": "https://www.linkedin.com/ad-library/search?accountOwner=microsoft" }],
    "searchQueries": ["cloud security"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("aboo.script/linkedin-ads-scraper").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 '{
  "startUrls": [
    {
      "url": "https://www.linkedin.com/ad-library/search?accountOwner=microsoft"
    }
  ],
  "searchQueries": [
    "cloud security"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call aboo.script/linkedin-ads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,aboo.script/linkedin-ads-scraper"
        }
    }
}
```

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/I2hMrIaXjP81YobGv/builds/IIdObHtAo9lvZh0Ar/openapi.json
