# LinkedIn Ad Library Scraper - Ads, Impressions, Targeting (`om_kh/linkedin-ad-library-scraper`) Actor

Scrape LinkedIn's public Ad Library by keyword, advertiser, company page, pasted search link, country or date: full ad text, headline, CTA, landing page, images, video, run dates, impressions by country and targeting. No login. $1 per 1,000 ads with full details.

- **URL**: https://apify.com/om_kh/linkedin-ad-library-scraper.md
- **Developed by:** [Khandji Omar](https://apify.com/om_kh) (community)
- **Categories:** Lead generation, Social media
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.55 / 1,000 ads

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 — Ads, Impressions, Targeting

> Scrape **LinkedIn's public Ad Library** by keyword, advertiser, country or date: the full
> ad text, headline, call to action, **landing page**, images and video, **run dates**,
> **estimated impressions with the split by country**, and the **targeting** the advertiser
> chose (languages, locations, job / company / audience criteria). No login, no cookies.
> **$1 per 1,000 ads with full details, no start fee.**

### Free tier — 20 results free on every run

**The first 20 results of every run are free**, on every run you ever make — not a one-off trial. One guard: the free allowance never covers more than half of a run, so the offer stays sustainable.

### What does this LinkedIn Ad Library scraper do?

Give it keywords (`crm`), advertisers (`HubSpot`), specific ad links, or just a list of
countries. It searches LinkedIn's Ad Library, then opens every ad's detail page so each row
is **complete**: text, media, landing page, dates, impressions and targeting — the data you
would otherwise copy by hand, ad by ad.

### Why use it

1. **Full details included in the price.** Impressions by country, targeting and landing page
   on every ad, not only the search card. $0.001 per ad, no start fee.
2. **Competitor B2B ad intelligence.** See which messages, offers and formats a competitor has
   been running, where, for how long and to whom.
3. **Landing pages with UTM tags.** Reveal the campaigns and funnels behind each ad.
4. **Filters:** keyword, advertiser (with optional exact match), countries, date range.
5. **Never charged for incomplete rows.** If LinkedIn refuses an ad's detail page, you still
   get the search card, flagged `detailsIncluded: false`, and it is **not charged**.
6. **API, n8n, Make, Zapier and MCP ready.**

### How to use it in 3 steps

1. Click **Try for free** — a keyword and an advertiser are prefilled.
2. Add keywords, advertisers or ad links; optionally countries and dates.
3. Click **Start** and download JSON, CSV or Excel.

### Input

| Field | What it does |
|---|---|
| `searchTerms` | Keywords (ad text or advertiser). |
| `advertisers` | Company or person names that paid for the ads. |
| `exactAdvertiserMatch` | Keep only ads whose advertiser name equals yours (drops partners and resellers). |
| `adUrls` | Specific `linkedin.com/ad-library/detail/...` links or ad IDs. |
| `startUrls` | Pasted LinkedIn links: an Ad Library search link (run again with its filters), a company page like `linkedin.com/company/nvidia` (every ad of exactly that company), or a single ad link. |
| `countries` | Two-letter codes (US, FR, DE…) where the ads were shown. |
| `dateRange` | All time, last 30 days, this month, this year, last year. |
| `startDate` / `endDate` | Custom range (YYYY-MM-DD). |
| `maxAdsPerSearch` | 1 to 5,000. Default 50. |
| `includeDetails` | Full details (default on). Off = search cards only, faster. |
| `maxTotalChargeUsd` | Optional hard cost cap for the run. |

```json
{
  "advertisers": ["HubSpot"],
  "exactAdvertiserMatch": true,
  "countries": ["US", "GB"],
  "dateRange": "last-30-days",
  "maxAdsPerSearch": 200
}
```

### Output

Real example (text, video and targeting lists trimmed):

```json
{
  "adId": "1578467644",
  "adUrl": "https://www.linkedin.com/ad-library/detail/1578467644",
  "advertiser": "Altera",
  "advertiserUrl": "https://www.linkedin.com/company/15226690",
  "format": "Video Ad",
  "text": "Accelerate Design in the AI Era at Altera Innovators Day.\nJoin us on October 28 in San Jose…",
  "headline": "Join us on October 28 in San Jose for a full day of technical sessions, demos, and conversations…",
  "callToAction": "Register",
  "landingUrl": "https://go.altera.com/innovators-day-san-jose-registration?utm_source=linkedin&utm_medium=paid_social&utm_campaign=Raghib-Keynote-alterainnovatorsday2026-sanjose",
  "videoUrl": "https://dms.licdn.com/playlist/vid/v2/…/mp4-720p-30fp-crf28/…",
  "paidBy": "Altera",
  "startDate": "2026-09-28",
  "endDate": "2026-09-29",
  "totalImpressions": "< 1k",
  "impressionsMin": 0,
  "impressionsMax": 1000,
  "impressionsByCountry": [
    {"country": "Japan", "percent": "46%"},
    {"country": "United States", "percent": "28%"},
    {"country": "India", "percent": "23%"}
  ],
  "targetingLanguages": ["English"],
  "targetingLocations": ["Greater Tokyo Area", "San Francisco Bay Area", "Chennai", "Tel Aviv District", "Israel"],
  "targetingParameters": {
    "Job": {"targeted": true, "excluded": false},
    "Company": {"targeted": false, "excluded": true}
  },
  "detailsIncluded": true,
  "status": "ok"
}
```

### How much does it cost?

| Event | Price |
|---|---|
| Ad (with full details) | **$0.001** ($1 per 1,000) |
| Start fee | none |

Up to 20 ads of every run are free (at most half of the run). An ad whose details could not be
read is delivered but never charged. Paid Apify plans get lower tier prices.

### Use cases

- **Competitor monitoring** — every ad a competitor ran this month, with landing pages.
- **B2B ad creative research** — hooks, formats and CTAs that run the longest.
- **Agency pitches** — show a prospect what their competitors spend attention on.
- **Market research** — who advertises on a topic, in which countries, to which jobs.

### Use it from code (API)

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("om_kh/linkedin-ad-library-scraper").call(run_input={
    "advertisers": ["HubSpot"],
    "exactAdvertiserMatch": True,
    "dateRange": "last-30-days",
})
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["startDate"], ad.get("totalImpressions"), ad.get("landingUrl"))
```

```bash
curl -X POST "https://api.apify.com/v2/acts/om_kh~linkedin-ad-library-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms": ["crm"], "countries": ["FR"], "maxAdsPerSearch": 24}'
```

### Integrations and MCP

Schedule it weekly per competitor and push new ads to Slack, Google Sheets or Airtable with
n8n, Make or Zapier. AI agents can call it through `https://mcp.apify.com` as
`om_kh/linkedin-ad-library-scraper`.

### Tips and limits

- Run dates, impressions, country split and targeting are published by LinkedIn for ads shown
  in the EU (DSA transparency). Add an EU country (`FR`, `DE`, `NL`…) to get them; for ads shown
  only outside the EU these fields are empty — LinkedIn does not publish them.
- LinkedIn's advertiser search is fuzzy — use `exactAdvertiserMatch` for one company.
- Spend and clicks are not public on LinkedIn, so no scraper can provide them.

### FAQ

**Do I need a LinkedIn account or cookies?** No.

**Is it legal?** It reads the Ad Library LinkedIn publishes for transparency. Use the data in
line with the laws and terms that apply to you.

### Related Actors

- [Facebook Ads Library Scraper - Copy, Spend, Reach](https://apify.com/om_kh/facebook-ads-library-scraper) — the same competitors on Meta.
- [Google Ads Transparency Scraper - Copy, Spend, Advertiser](https://apify.com/om_kh/google-ads-transparency-scraper) — their Google ads.
- [LinkedIn Company Scraper - Size, Industry, Employee Count](https://apify.com/om_kh/linkedin-company-scraper) — the advertiser's company profile.

### Your feedback

Did this Actor save you time? A short review on the **Reviews** tab helps other people find it, and every review is read. Something missing or broken? Open an issue on the **Issues** tab: it is answered and fixed fast.

# Actor input Schema

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

Search the Ad Library by keyword (ad text or advertiser), one per line. Up to 20 searches per run.

## `advertisers` (type: `array`):

Company or person names that paid for the ads, e.g. HubSpot. LinkedIn's advertiser search is fuzzy; turn on exact match below to keep only that name.

## `exactAdvertiserMatch` (type: `boolean`):

Keep only ads whose advertiser name equals what you typed (drops partners and resellers).

## `adUrls` (type: `array`):

Specific ads: linkedin.com/ad-library/detail/... links or ad IDs.

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

Paste any of: an Ad Library search link (run again with its filters), a company page such as https://www.linkedin.com/company/nvidia (all the ads of exactly that company), or a single ad link.

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

Two-letter country codes where the ads were shown, e.g. US, FR, DE. Leave empty for all countries.

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

When the ads ran. Ignored if you set a start or end date.

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

Custom range start (YYYY-MM-DD).

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

Custom range end (YYYY-MM-DD).

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

1 to 5,000. Default 50.

## `includeDetails` (type: `boolean`):

Full text, landing page, media, run dates, impressions by country and targeting (one extra page per ad, same price). Default on.

## `maxTotalChargeUsd` (type: `number`):

Optional hard cost cap for this run.

## Actor input object example

```json
{
  "searchTerms": [
    "crm"
  ],
  "advertisers": [
    "HubSpot"
  ],
  "exactAdvertiserMatch": false,
  "dateRange": "",
  "maxAdsPerSearch": 24,
  "includeDetails": true
}
```

# Actor output Schema

## `report` (type: `string`):

A visual summary of delivery, charges, and source issues.

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

Ads in a sortable table. No JSON knowledge required.

## `csv` (type: `string`):

Results ready for spreadsheets, CRMs, and analytics tools.

## `excel` (type: `string`):

Results as an Excel workbook for non-technical teams.

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

Machine-readable delivery, billing, and source diagnostics.

# 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": [
        "crm"
    ],
    "advertisers": [
        "HubSpot"
    ],
    "maxAdsPerSearch": 24
};

// Run the Actor and wait for it to finish
const run = await client.actor("om_kh/linkedin-ad-library-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 = {
    "searchTerms": ["crm"],
    "advertisers": ["HubSpot"],
    "maxAdsPerSearch": 24,
}

# Run the Actor and wait for it to finish
run = client.actor("om_kh/linkedin-ad-library-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 '{
  "searchTerms": [
    "crm"
  ],
  "advertisers": [
    "HubSpot"
  ],
  "maxAdsPerSearch": 24
}' |
apify call om_kh/linkedin-ad-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,om_kh/linkedin-ad-library-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/mGiTUTfy0jw0gLWGv/builds/S7TKGm3ehnXtqgGUO/openapi.json
