# LinkedIn Ads Library Scraper (`datatrilha/linkedin-ads-library`) Actor

Collect ads from the public LinkedIn Ad Library by keyword, advertiser or company ID: ad text, format, advertiser, run dates, impressions and targeting.

- **URL**: https://apify.com/datatrilha/linkedin-ads-library.md
- **Developed by:** [Datatrilha](https://apify.com/datatrilha) (community)
- **Categories:** Marketing, Lead generation, Social media
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 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.

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 Ads Library Scraper

Collect ads from the public [LinkedIn Ad Library](https://www.linkedin.com/ad-library) without logging in. Search by keyword, advertiser name or company ID, and get each ad's text, format, advertiser, run dates, impressions and targeting as clean JSON, CSV or Excel.

### What you can use it for

- **Competitor research:** see every ad a competitor is running on LinkedIn, and for how long.
- **Creative inspiration:** collect B2B ad copy, formats and calls to action by keyword.
- **Agency reporting:** monitor clients' and competitors' ads on a schedule.
- **AI agents:** call it as a tool through the Apify MCP server to answer "what is X advertising on LinkedIn?"

### Input

| Field | What it does |
| --- | --- |
| `keywords` | One search per keyword |
| `advertisers` | Search by advertiser name |
| `payers` | Search by who paid for the ads |
| `companyIds` | Every ad from a LinkedIn company ID |
| `startUrls` | Any Ad Library search or ad URL |
| `countries` | Two-letter codes, for example `US`, `GB`, `BR` |
| `dateOption` | All time, last 30 days, current month or year, last year, or a custom range |
| `maxAdsPerSearch` | Cap per search (default 100) |
| `includeDetails` | Open each ad for full text, payer, headline, call to action and video files (default on) |
| `delaySecs` | Pause between requests; LinkedIn rate-limits fast clients (default 2) |

### Output

```json
{
  "adId": "1665182406",
  "adUrl": "https://www.linkedin.com/ad-library/detail/1665182406",
  "format": "Video Ad",
  "creativeType": "SPONSORED_VIDEO",
  "advertiserName": "Capsule",
  "advertiserUrl": "https://www.linkedin.com/company/71307670",
  "advertiserLinkedinId": "71307670",
  "paidBy": "Capsule",
  "bodyText": "Hey BigCommercers 👋\nYour team just got personalized videos from us...",
  "headline": "BigCommerce, Scale On-Brand Video With Capsule 🤝",
  "ctaText": "Learn more",
  "videoUrls": ["https://dms.licdn.com/playlist/vid/v2/..."],
  "videoPosterUrl": "https://media.licdn.com/dms/image/v2/...",
  "searchKey": "keyword:hubspot",
  "scrapedAt": "2026-10-31T18:00:00.000Z"
}
```

LinkedIn shows run dates, impressions and targeting only for some ads (mainly ads shown in the EU). When it does, you also get:

```json
{
  "firstSeen": "Oct 29, 2026",
  "lastSeen": "Oct 31, 2026",
  "impressions": "200k-300k",
  "targeting": {
    "Language": { "included": ["English"], "excluded": [] },
    "Location": { "included": ["Italy", "United States", "France", "..."], "excluded": [] }
  },
  "targetingParameters": [
    { "parameter": "Company", "targeted": true, "excluded": false },
    { "parameter": "Job", "targeted": true, "excluded": false }
  ]
}
```

### Pricing

Pay per ad returned. You never pay for duplicates or failed pages. Set a maximum charge per run in the run options to cap spend.

### Tips

- Keep the residential proxy on. LinkedIn sits behind Cloudflare and blocks plain HTTP clients and datacenter IPs, so this Actor drives a real browser and reads pages from inside it.
- Use `companyIds` for complete results from one company; keyword search can mix advertisers.
- Turn off `includeDetails` for a faster run with truncated ad text and no payer or video files.

### Development

```bash
npm install
npm test            # parser tests against real HTML saved in fixtures/
apify run           # local run; put input in storage/key_value_stores/default/INPUT.json
apify push          # deploy to your Apify account
```

# Actor input Schema

## `keywords` (type: `array`):

Search the ad library for these keywords. One search per keyword.

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

Search by advertiser (account owner) name, for example "microsoft".

## `payers` (type: `array`):

Search by the entity that paid for the ads (the "Paid for by" line).

## `companyIds` (type: `array`):

Numeric LinkedIn company IDs. The most precise way to get every ad from one company.

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

Search or ad detail URLs copied from linkedin.com/ad-library. Use this for filters not covered above.

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

Two-letter country codes where the ads ran, for example US, GB, BR. Leave empty for all countries.

## `dateOption` (type: `string`):

When the ads ran.

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

YYYY-MM-DD. Used only with the custom range.

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

YYYY-MM-DD. Used only with the custom range.

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

Stop each search after this many ads. You pay only for ads returned.

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

Open each ad for the full text, "Paid for by", headline, call to action and video files, plus run dates, impressions and targeting where LinkedIn shows them. Slower, but much richer.

## `delaySecs` (type: `integer`):

LinkedIn rate-limits fast clients. Lower values are faster but get blocked more often.

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

LinkedIn rate-limits datacenter IPs. Residential proxies are recommended.

## Actor input object example

```json
{
  "keywords": [
    "hubspot"
  ],
  "dateOption": "all",
  "maxAdsPerSearch": 100,
  "includeDetails": true,
  "delaySecs": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

All collected ads with full details.

## `overview` (type: `string`):

Main fields in a table.

## `targeting` (type: `string`):

Run dates, impressions and targeting, where LinkedIn shows them.

# 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 = {
    "keywords": [
        "hubspot"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datatrilha/linkedin-ads-library").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 = {
    "keywords": ["hubspot"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("datatrilha/linkedin-ads-library").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 '{
  "keywords": [
    "hubspot"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call datatrilha/linkedin-ads-library --silent --output-dataset

```

## MCP server setup

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

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/rkAeD0ZYL3tjtAfGX/builds/7njUtgofyuxCLgzuF/openapi.json
