# LinkedIn Competitor Ads Scraper (`blueskyscraper/linkedin-competitor-ads-scraper`) Actor

Get every LinkedIn ad a competitor runs: paste a LinkedIn company page URL, company ID or name and get its ads from the LinkedIn Ad Library — copy, format, creative, CTA, landing page and UTM, run dates, impressions by country and targeting. Daily only-new-ads monitoring. No login.

- **URL**: https://apify.com/blueskyscraper/linkedin-competitor-ads-scraper.md
- **Developed by:** [BlueskyScraper](https://apify.com/blueskyscraper) (community)
- **Categories:** Marketing, Social media, Business
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.12 / 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 Competitor Ads Scraper** shows you **every ad a company runs on LinkedIn**. Paste a competitor's **LinkedIn company page** (`https://www.linkedin.com/company/hubspot/`), its **company ID** or just its **name**, and get its ads from the public LinkedIn Ad Library: **ad copy, headline, format, image or video, carousel cards, call to action** — and, with one switch, **who paid, run dates, impressions, impressions by country, targeting and the landing page with its UTM parameters**. One row per ad, no LinkedIn login. **$1.6 per 1,000 ads, no start fee.**

### What is LinkedIn Competitor Ads Scraper?

A **LinkedIn ad spy tool** for B2B marketers, agencies and founders who want to know what competitors advertise on LinkedIn — without opening the Ad Library one company at a time. Put ten competitors in the list and get one table: who runs how many ads, in which formats, with which offers, since when, and — for ads that reached the EU — where and to whom they were shown.

The company page URL is turned into LinkedIn's numeric company ID automatically, so you get **exactly that company's ads**, not those of partners or agencies with a similar name. A plain name uses LinkedIn's own advertiser-name search, which is broader.

### What data do you get for each competitor ad?

| Field | Example |
|---|---|
| `advertiserName`, `advertiserType` | `HubSpot`, `company` |
| `format` | `Single Image Ad`, `Video Ad`, `Carousel Ad`, `Document Ad`, `Event Ad`, `Message Ad`… |
| `text`, `headline` | `Remote-first and built on trust…`, `Sell from anywhere, close everywhere.` |
| `imageUrl`, `videoUrl`, `carouselCards` | the creative itself |
| `isThoughtLeaderAd`, `memberName` | a company promoting an employee's post, and whose |
| `url`, `adId` | `https://www.linkedin.com/ad-library/detail/1560106944` |
| `companyInput`, `searchTerm`, `position` | the company you entered, its ID `68529`, rank of the ad (newest first) |

With **Add impressions, countries, targeting and landing page** on, each row also gets:

| Field | Example |
|---|---|
| `paidBy` | `HubSpot, Inc.` |
| `ranFrom`, `ranTo`, `runDays` | `2026-09-14`, `2026-10-02`, `19` |
| `impressions`, `impressionsMin`, `impressionsMax` | `50k-100k`, `50000`, `100000` |
| `impressionsByCountry`, `topCountry` | United Kingdom 43%, Ireland 19%, Germany 18%…; `United Kingdom` |
| `targetingLanguages`, `targetingLocations`, `targetingExcludedLocations` | `["English"]`, `["Dallas, TX", "Germany", "Chicago, IL"…]`, `["India"…]` |
| `targetedParameters` | `["Company", "Job"]` — whether they target by company list, job, audience, demographics |
| `ctaText`, `landingUrl`, `landingDomain`, `utmParameters` | `Learn more`, the landing page, its domain and `utm_*` / `hsa_*` parameters |

LinkedIn publishes impressions, run dates and targeting for ads that reached the EU (the Digital Services Act). Put `DE`, `FR` or `NL` into **Countries** to see those ads with every field; in our test 10 of 10 HubSpot ads shown in Germany came with impressions by country and targeting.

### 💰 How much does it cost to scrape competitor ads?

Pay per ad, nothing else. Every row is billed once, by what it contains:

| Event | Free plan | Starter (Bronze) | Scale (Silver) | Business, Platinum, Diamond |
|---|---|---|---|---|
| **Ad** — one ad from the Ad Library search | $0.0016 ($1.6 / 1K) | $0.00144 ($1.44 / 1K) | $0.00128 ($1.28 / 1K) | $0.00112 ($1.12 / 1K) |
| **Ad with details** — the same ad plus impressions, countries, targeting and landing page | $0.0032 ($3.2 / 1K) | $0.00288 ($2.88 / 1K) | $0.00256 ($2.56 / 1K) | $0.00224 ($2.24 / 1K) |
| Searches with no ads, error rows, start of a run | free | free | free | free |

An ad is billed as **either** an ad **or** an ad with details, never both. On the Apify Free plan the monthly $5 credit buys about **3,125 ads** or **1,562 ads with details**. For comparison, the most-used LinkedIn ads actor in Apify Store charges $2 per 1,000 ads and $4 per 1,000 ads with details on the Free plan (Store prices on 3 October 2026) — this Actor is 20% below that. **Max cost per run** in the run options is respected to the cent: the run stops by itself, green, once the next ad would go over it.

A typical check of 5 competitors × 24 ads costs about $0.19 on the Free plan; with details about $0.38.

### How to see all LinkedIn ads of a competitor

1. Press **Try for free** (an Apify account is free).
2. In **Competitors** paste company pages, one per line: `https://www.linkedin.com/company/hubspot/`, `https://www.linkedin.com/company/salesforce/`. A company ID (`68529`) or a name (`Pipedrive`) works too.
3. Set **Ads per company** (24 by default, up to 5,000).
4. Optionally pick **Countries** and a **Date range**, and turn on **impressions, countries, targeting and landing page**.
5. Press **Start** — the default run (HubSpot, 24 ads) takes about 30 seconds.
6. Download the table as Excel, CSV or JSON.

### ⬇️ Input

```json
{
    "companies": [
        "https://www.linkedin.com/company/hubspot/",
        "https://www.linkedin.com/company/salesforce/",
        "Pipedrive"
    ],
    "maxAdsPerSearch": 50,
    "countries": ["DE"],
    "includeDetails": true,
    "dateRange": "last-30-days"
}
```

| Field | What it does |
|---|---|
| `companies` | Company page URL, company ID or name — one competitor per line |
| `maxAdsPerSearch` | Ads per company, newest first (default 24, max 5,000) |
| `countries` | Only ads shown in these countries (`US`, `GB`, `DE`…) |
| `includeDetails` | Impressions, countries, targeting, landing page ($) |
| `dateRange`, `startDate`, `endDate` | When the ads ran |
| `sortOrder` | `newest` or `oldest` |
| `onlyNewRowsStore` | Memory name: later runs return only new ads |

#### Company page, ID or name?

- **Company page URL** — `linkedin.com/company/<name>/` (also `/showcase/` pages). The Actor opens the public page once, reads the company ID and returns exactly that company's ads.
- **Company ID** — the number LinkedIn uses (`68529` is HubSpot, `1337` is LinkedIn). Fastest, exact.
- **Name** — LinkedIn's advertiser-name search. Partial matching: `hubspot` also returns partners such as *IXTENSA 🧡 HubSpot*. Useful when you want the whole ecosystem around a brand.

### ⬆️ Output

```json
{
    "type": "ad",
    "adId": "1560106944",
    "url": "https://www.linkedin.com/ad-library/detail/1560106944",
    "advertiserName": "HubSpot",
    "format": "Single Image Ad",
    "headline": "Sell from anywhere, close everywhere.",
    "text": "Remote-first and built on trust. Sell from wherever you're sharpest, on your own rhythm…",
    "imageUrl": "https://media.licdn.com/dms/image/v2/…",
    "searchType": "companyId",
    "searchTerm": "68529",
    "companyInput": "https://www.linkedin.com/company/hubspot/",
    "position": 1,
    "detailsScraped": true,
    "paidBy": "HubSpot, Inc.",
    "ranFrom": "2026-09-14",
    "ranTo": "2026-10-02",
    "impressions": "50k-100k",
    "topCountry": "United Kingdom",
    "targetedParameters": ["Company", "Job"],
    "ctaText": "Learn more"
}
```

A company with no ads in the Ad Library returns one free row: `"error": "Not found: no ads in the LinkedIn Ad Library for this search — this company may not advertise on LinkedIn right now"`. A company page that does not exist returns a free row saying so.

### 🔁 Get only new LinkedIn ads — schedule it

A one-off export is useful once; a feed of **new** ads is useful every day. Fill **Only new ads — memory name** (for example `competitors-weekly`) and the Actor remembers every ad it delivered under that name. Every later run with the same name writes — and charges — **only ads you have not received before**. Ads delivered earlier are skipped before their page is even opened, so details are not paid twice either.

1. Run once with the memory name to load the current ads.
2. Open the run → **Actions → Schedule** (or [Schedules](https://console.apify.com/schedules)) and pick daily or weekly.
3. Read the new ads from each run's dataset, or connect a webhook, Slack, n8n, Make or Zapier.

Each memory name is separate: one per competitor list or market. To start over, use a new name.

### Use cases

#### Weekly competitor ad report

Five competitors, a memory name, a weekly schedule: every Monday you get only the ads they launched that week, ready for Slack or a Google Sheet.

#### Positioning and messaging research

Read every headline and offer a competitor tests. Formats and `runDays` show what they keep paying for — the ads that work.

#### Where competitors spend

`impressionsByCountry` and `targetingLocations` show which markets get the budget; `targetedParameters` shows whether they target job titles, company lists or audiences.

#### Agency pitches

Show a prospect exactly what their competitors run on LinkedIn, with impressions and targeting, before the first call.

### Integrations

#### Apify API (Python and JavaScript)

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("blueskyscraper/linkedin-competitor-ads-scraper").call(run_input={"companies": ["https://www.linkedin.com/company/hubspot/", "https://www.linkedin.com/company/salesforce/"], "maxAdsPerSearch": 50})
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad.get("advertiserName"), ad.get("format"), ad.get("impressions"))
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('blueskyscraper/linkedin-competitor-ads-scraper').call({ companies: ['https://www.linkedin.com/company/hubspot/'], countries: ['DE'], includeDetails: true });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### No-code: n8n, Make, Zapier, Google Sheets

Use the Apify app in n8n, Make or Zapier: *Run Actor* → *Get dataset items*. For Google Sheets, use the Google Sheets integration on the Actor's Integrations tab, or download the run as Excel or CSV.

#### MCP server for AI agents

Connect `https://mcp.apify.com/?actors=blueskyscraper/linkedin-competitor-ads-scraper` to Claude, ChatGPT, Cursor or any MCP client, then ask in plain words — for example *"Which LinkedIn ads did HubSpot and Salesforce launch in the last 30 days, and what do they offer?"* The input fields are written so an agent can call the Actor correctly without reading this page.

### 🤖 For AI agents

Actor `blueskyscraper/linkedin-competitor-ads-scraper`. **Purpose:** every LinkedIn ad of the companies you name. **Minimal input:** `{"companies": ["https://www.linkedin.com/company/hubspot/"]}`. A company URL or numeric ID is exact; a plain name uses partial advertiser-name matching. `includeDetails: true` adds impressions, impressions by country, run dates, payer, targeting and landing page (empty when LinkedIn does not publish them — EU-reached ads have them). Billed per row as `ad` or `ad-with-details`; error rows are free.

### ❓ FAQ

#### Is it legal to scrape the LinkedIn Ad Library?

The Ad Library is a public transparency tool that LinkedIn publishes for anyone to search without logging in, and this Actor reads only those public pages. It does not log in or touch private profiles. Ads can contain names of people (Thought Leader ads, message senders); if you store or process them, the GDPR and similar laws apply to you. Check LinkedIn's terms and consult a lawyer for your specific use.

#### Does it need a LinkedIn account or cookies?

No. Nothing is logged in, so there is no account to get restricted, and no browser either — runs finish in seconds.

#### Can I use LinkedIn Competitor Ads Scraper with the Apify API?

Yes. Every run can be started and read over the REST API or the Python and JavaScript clients above, so it works as an unofficial **LinkedIn Ads API** for ad intelligence.

#### Can I use it through an MCP server?

Yes, through the Apify MCP server — see Integrations.

#### Can I integrate it with other apps?

Yes: n8n, Make, Zapier, Google Sheets, Slack, webhooks, and anything that can call an HTTP API.

#### Why are impressions or targeting empty for some ads?

LinkedIn publishes run dates, impressions and targeting only for ads it reports under the EU Digital Services Act — ads that reached people in the EU. For ads shown only outside the EU those fields stay empty. **Impressions by country** appear once LinkedIn publishes them, which can take up to 48 hours after an ad starts; very fresh ads show the total impressions range but no country split yet. The Actor never estimates numbers LinkedIn does not show.

#### What happens when a search finds nothing?

You get one free row with `type: "error"` saying so, with a hint (remove the country filter, widen the dates). A search with no ads is a valid answer, not a failure, and nothing is charged.

#### Is it one row per ad?

Yes. The same ad found by two searches or two companies in one run appears once.

#### How do I find a company's LinkedIn ID?

You do not need to: paste the company page URL and the Actor finds the ID. If you want it anyway, it is `advertiserCompanyId` in any detailed row, and `searchTerm` in every row found through a company URL.

#### Does it show ads the company ran in the past?

It shows what the LinkedIn Ad Library keeps, newest first. Use **Date range** (last 30 days, this month, this year, last year) or **Start date / End date** to pick a period, and **Order: oldest first** to start from the oldest.

### Your feedback

Something missing or wrong? Open an issue on the Issues tab — we answer quickly. If the Actor saves you time, a review helps other buyers find it.

### You might also like

| Actor | What it does |
|---|---|
| [LinkedIn Ads Scraper](https://apify.com/blueskyscraper/linkedin-ads-scraper) | Search the LinkedIn Ad Library by keyword, advertiser, payer or company ID |
| [LinkedIn Ad Details Scraper](https://apify.com/blueskyscraper/linkedin-ad-details-scraper) | Impressions by country, run dates, payer, targeting and landing page of each ad |
| [LinkedIn Company Details Scraper](https://apify.com/blueskyscraper/linkedin-company-details-scraper) | Size, industry, website and followers of the advertisers you find |
| [LinkedIn Company Posts Scraper](https://apify.com/blueskyscraper/linkedin-company-posts-scraper) | A company's organic posts next to its paid ads |
| [LinkedIn Company Jobs Scraper](https://apify.com/blueskyscraper/linkedin-company-jobs-scraper) | Who the advertiser is hiring right now |
| [LinkedIn Scraper](https://apify.com/blueskyscraper/linkedin-scraper) | Profiles, companies and posts in one Actor, no login |

**Also known as:** LinkedIn competitor ads, LinkedIn ad spy, competitor ads scraper, LinkedIn company ads, see competitor LinkedIn ads, LinkedIn Ad Library by company, B2B ads tracker.

# Actor input Schema

## `companies` (type: `array`):

Competitors whose LinkedIn ads you want, one per line: a LinkedIn company page (<code>https://www.linkedin.com/company/hubspot/</code>), a company ID (<code>68529</code>) or a name (<code>HubSpot</code>). A page URL or ID returns exactly that company's ads; a name uses LinkedIn's advertiser-name search, which also matches partners with the name in theirs.

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

Keep only ads shown in these countries — two-letter codes: <code>US</code>, <code>GB</code>, <code>DE</code>, <code>FR</code>… Empty = all countries. Impressions and targeting are published for ads that reached the EU, so <code>DE</code> or <code>FR</code> gives the fullest detail rows.

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

How many ads to take for each company, newest first. LinkedIn serves 24 per page; up to 5,000 per company per run.

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

Opens each ad's page in the Ad Library: full ad text, who paid, run dates, total impressions and impressions by country, targeted languages and locations, which targeting criteria were used (audience, company, job, demographic…), call-to-action button, landing page URL with its UTM parameters, video file. Impressions and targeting exist only for ads LinkedIn reports under the EU Digital Services Act; for other ads those fields stay empty. Such an ad is billed as an ad with details.

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

Keep only ads that ran in this period. For exact dates use Start date / End date below instead.

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

Custom range start, YYYY-MM-DD (for example <code>2026-01-01</code>). Overrides Date range.

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

Custom range end, YYYY-MM-DD (for example <code>2026-03-31</code>). Overrides Date range.

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

Newest ads first (LinkedIn's default) or oldest first.

## `onlyNewRowsStore` (type: `string`):

Give this run a name — <code>my-ads-watch</code> — and the Actor remembers every ad it delivered under that name. Every later run with the same name writes and charges <b>only ads you have not received before</b>. Schedule the Actor daily to get a feed of new LinkedIn ads instead of the whole list each time. Leave empty to get everything found, every time.

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

How many ad pages to open at once when details are on. 4 is safe; higher is faster but gets more refusals.

## Actor input object example

```json
{
  "companies": [
    "https://www.linkedin.com/company/hubspot/"
  ],
  "maxAdsPerSearch": 24,
  "includeDetails": false,
  "dateRange": "any",
  "sortOrder": "newest",
  "maxConcurrency": 4
}
```

# Actor output Schema

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

One row per ad from the LinkedIn Ad Library: advertiser, format, ad copy, headline, image or video, carousel cards, document and event details; with details also who paid, run dates, total impressions, impressions by country, targeting, call to action and landing page. Error rows explain inputs that could not be read.

# 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 = {
    "companies": [
        "https://www.linkedin.com/company/hubspot/"
    ],
    "maxAdsPerSearch": 24
};

// Run the Actor and wait for it to finish
const run = await client.actor("blueskyscraper/linkedin-competitor-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 = {
    "companies": ["https://www.linkedin.com/company/hubspot/"],
    "maxAdsPerSearch": 24,
}

# Run the Actor and wait for it to finish
run = client.actor("blueskyscraper/linkedin-competitor-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 '{
  "companies": [
    "https://www.linkedin.com/company/hubspot/"
  ],
  "maxAdsPerSearch": 24
}' |
apify call blueskyscraper/linkedin-competitor-ads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,blueskyscraper/linkedin-competitor-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/pdZZ49pfsdxDXxjDp/builds/RCvzZJd5dv5qHpAEn/openapi.json
