LinkedIn Ad Library Scraper — Ads, Impressions & Targeting
Pricing
from $0.40 / 1,000 ad scraped (full details included)s
LinkedIn Ad Library Scraper — Ads, Impressions & Targeting
Scrape the LinkedIn Ad Library by company, keyword, payer, or country. Full ad copy, headlines, CTAs, destination URLs, payer entity, run dates, total impressions, impressions by country, targeting parameters, and raw media links (images, video streams, documents). Export JSON/CSV.
Pricing
from $0.40 / 1,000 ad scraped (full details included)s
Rating
5.0
(2)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
0
Bookmarked
30
Total users
7
Monthly active users
a day ago
Last modified
Categories
Share
Turn any LinkedIn Ad Library search into a structured stream of sponsored ads. Start from a company, keyword, payer, country, or a pasted Ad Library URL, and get full ad copy, creative links, run dates, impression ranges, per-country impression splits, and targeting parameters as clean rows.
Why use this scraper?
- Impressions and targeting, not just creatives — impression ranges, per-country splits, and the targeting facets an advertiser used, parsed into typed fields.
- Filter before you pay — narrow by impression volume and by targeting category server-side, so you only get charged for rows you actually want.
- Many searches, one run — each entry in
searchescarries its own company, country, date window, and filters. - Numeric impressions —
totalImpressionsMin/totalImpressionsMaxalongside the raw"5k-10k"string, so you can sort and threshold without parsing text. - No browser — every page is fetched over plain HTTP, which is why runs are fast and cheap.
- You are not billed for failures — an ad whose detail page fails is logged and skipped, never pushed and never charged.
Overview
The LinkedIn Ad Library publishes every sponsored ad running on LinkedIn. For ads shown to EU audiences it additionally publishes impression volumes and targeting parameters under DSA transparency rules.
This actor turns that library into a dataset: one row per ad. It's built for competitive-intelligence teams tracking a rival's creatives and spend signals, agencies auditing a category, and researchers studying commercial advertising.
Ads outside the EU still return the full creative, copy, payer, and run dates — but LinkedIn does not publish impressions or targeting for them, so those fields are absent. That's a limit of the source, not the scraper.
Supported inputs
You can start a run four ways, and mix them freely:
1. Company, keyword, or payer
{ "companies": ["HubSpot"], "keywords": ["AI agents"], "payers": ["HubSpot, Inc."] }
2. Independent searches, each with its own filters
{"searches": [{ "company": "HubSpot", "countries": ["DE"], "dateOption": "last-30-days" },{ "keyword": "AI agents", "includedTargetingFacetCategories": ["JOB"] }]}
3. A pasted Ad Library URL — search pages or a single ad detail page
{"startUrls": ["https://www.linkedin.com/ad-library/search?accountOwner=HubSpot&countries=DE","https://www.linkedin.com/ad-library/detail/1441861963"]}
4. Filters on top of any of the above — country, date window, impression range, targeting categories.
Not supported: LinkedIn feed posts, organic company posts, Campaign Manager data, ad spend in currency (LinkedIn publishes impression ranges, never cost), and any page behind a login wall.
Use cases
| Audience | What they use it for |
|---|---|
| Competitive intelligence | Track a competitor's live creatives, messaging shifts, and relative impression volume |
| Performance marketing | Mine winning hooks, headlines, and CTAs across a category before writing new ads |
| Agencies | Audit a prospect's current advertising and build the pitch deck from real data |
| Market research | Measure category-level advertising pressure and geographic mix over time |
| Policy & academic research | Study DSA-disclosed targeting parameters and impression distribution |
| Brand protection | Find who is running ads that name your brand, and which entity paid for them |
How it works
- Your companies, keywords, payers, and
searchesentries are turned into Ad Library search URLs with your filters applied. - Each search page is fetched over HTTP and read directly from the server-rendered markup.
- Pagination follows the Ad Library's own pagination endpoint until
maxItemsis reached, backing off automatically if LinkedIn rate-limits. - When
scrapeAdDetailsis on, each ad's detail page is fetched for payer, run dates, impressions, and targeting. - Rows are pushed to the dataset as they complete, ready to export as JSON, CSV, or Excel.
Input configuration
| Field | Type | Default | Description |
|---|---|---|---|
companies | array | [] | Advertiser/company names — one search each |
keywords | array | [] | Free-text keyword searches |
payers | array | [] | Paying-entity names |
countries | array | [] | ISO country codes, e.g. ["DE","FR"] |
dateOption | string | all-time | all-time, last-30-days, current-month, current-year, last-year, custom-date-range |
startDate / endDate | string | – | YYYY-MM-DD; when set they take priority over dateOption |
impressionsMinValue | integer | – | Lower impression bound, combined with its unit |
impressionsMinUnit | string | thousand | none, thousand, or million |
impressionsMaxValue | integer | – | Upper impression bound |
impressionsMaxUnit | string | thousand | none, thousand, or million |
includedTargetingFacetCategories | array | [] | Ad targeting must use these: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS |
excludedTargetingFacetCategories | array | [] | Ad targeting must NOT use these; same value list |
searches | array | [] | Independent searches; each entry may override any filter above |
startUrls | array | [] | Ad Library search or detail URLs |
maxItems | integer | 100 | Maximum ads to return |
scrapeAdDetails | boolean | true | Fetch each ad's detail page for impressions, targeting, and payer |
includeEmployerBranding | boolean | false | Include employer-brand promos alongside sponsored ads |
sessionCookie / sessionCookies | string / array | – | Optional li_at cookie(s) if a search returns only employer-brand results |
proxy | object | Apify datacenter | Proxy configuration |
maxConcurrency | integer | 3 | Parallel detail fetches |
minDelay / maxDelay | integer | 1 / 3 | Delay range in seconds between requests |
debug | boolean | false | Verbose per-request logging |
Note on impression filters: LinkedIn requires both bounds. If you set only one, the actor fills the other in automatically so your search still runs.
Example — a competitor's German ads above 100k impressions
{"companies": ["HubSpot"],"countries": ["DE"],"impressionsMinValue": 100,"impressionsMinUnit": "thousand","maxItems": 100}
Example — two unrelated searches in one run
{"searches": [{ "company": "HubSpot", "countries": ["DE"], "dateOption": "last-30-days" },{ "keyword": "AI agents", "includedTargetingFacetCategories": ["JOB"] }],"maxItems": 200}
Output overview
One row per ad. Every row carries identity (adId, adLibraryUrl), the advertiser, the creative and copy, and the CTA destination. Rows for EU-facing ads additionally carry the payer, run window, impression range, per-country impression split, and targeting facets.
Output sample
Real row, trimmed — produced by { "companies": ["HubSpot"], "countries": ["DE"] }:
{"adId": "1441861963","adLibraryUrl": "https://www.linkedin.com/ad-library/detail/1441861963","advertiserName": "HubSpot","advertiserBio": "Promoted","advertiserUrl": "https://www.linkedin.com/company/68529","isPromoted": true,"adStatus": "ACTIVE","format": "VIDEO","headline": "Routine-Anfragen erledigt? Gute Arbeit.","body": "HubSpot's Customer Agent erledigt Routineanfragen von allein und holt dich nur dazu, wenn es zählt. …","ctas": ["Mehr erfahren"],"clickUrl": "http://hubspot.de","imageUrl": "https://media.licdn.com/dms/image/v2/D4D10AQH3o7vyy-TVcA/videocover-high/…","paidBy": "HubSpot, Inc.","availabilityRaw": "Ran from Jul 1, 2026 to Jul 25, 2026","firstShownAt": "2026-07-01","lastShownAt": "2026-07-25","totalImpressionsRaw": "5k-10k","totalImpressionsMin": 5000,"totalImpressionsMax": 10000,"impressionsByCountry": [{ "country": "Germany", "percentage": 100 }],"targeting": [{ "category": "Language", "included": ["Targeting includes Deutsch"], "excluded": [] },{ "category": "Job", "included": ["Member"], "excluded": [] }],"scrapedAt": "2026-07-25T19:48:25.821Z"}
Key output fields
Identity — adId, adLibraryUrl, startUrl, scrapedAt
Advertiser — advertiserName, advertiserBio, advertiserUrl, advertiserLogo, paidBy, isPromoted
Creative — format (SINGLE_IMAGE, VIDEO, CAROUSEL, DOCUMENT, EVENT, TEXT), headline, body, imageUrl, imageUrls, videoUrl, videoPosterUrl, documentUrl
Destination — ctas, clickUrl, externalLinksInText
Run window — availabilityRaw, firstShownAt, lastShownAt, adStatus
Reach (EU-facing ads) — totalImpressionsRaw, totalImpressionsMin, totalImpressionsMax, impressionsByCountry[]
Targeting (EU-facing ads) — targeting[] with category, included[], excluded[], raw
Pricing
Pay per event, tiered by your Apify plan:
| Plan tier | Per ad |
|---|---|
| Free | $0.0015 |
| Bronze | $0.0009 |
| Silver | $0.0007 |
| Gold and above | $0.0004 |
Plus $0.00005 per actor start. Ads that fail detail extraction are never pushed and never charged.
FAQ
Do I need a LinkedIn account or cookie?
No. The actor reads the public Ad Library anonymously. sessionCookie exists only as a fallback if a particular search returns nothing but employer-brand promos.
Why are impressions and targeting missing on some ads? LinkedIn publishes them only for ads shown to EU audiences, under DSA transparency rules. A US-only campaign returns creatives and run dates but no impressions. Filtering by an EU country is the reliable way to get rows that always have them.
Can I get ad spend in dollars? No. LinkedIn publishes impression ranges, never cost. Any tool claiming a spend figure is estimating it.
Why did I get fewer ads than maxItems?
Either the search genuinely has fewer matches, or LinkedIn stopped serving more results. The run's status message says which, so a short result never looks like a complete one.
Can I filter by impressions with only a minimum? Yes. LinkedIn itself requires both bounds, so the actor fills the missing side in for you.
Does it scrape organic LinkedIn posts? No — sponsored ads from the Ad Library only.
Support
Found a bug or need a field that isn't here? Open an issue on the actor's Issues tab and it will be looked at.
Additional services
Need a tailored export, a different schema, a scheduled feed into your warehouse, or a scraper for another site? Custom work is available — get in touch through the Apify profile.
Explore more scrapers
Browse the full collection at apify.com/memo23 — scrapers for job boards, real-estate portals, review sites, social platforms, and more.
🤖 For AI Agents & LLM Apps
Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/linkedin-ads-scraper).
Purpose: Scrapes the LinkedIn Ad Library — one row per sponsored ad, including DSA-disclosed impression ranges and targeting facets for EU-facing ads.
Minimal input:
{ "companies": ["HubSpot"], "countries": ["DE"], "maxItems": 25 }
Output: one dataset row per ad — adId, adLibraryUrl, advertiserName, advertiserBio, advertiserUrl, isPromoted, adStatus, format, headline, body, ctas[], clickUrl, externalLinksInText[], imageUrl, imageUrls[], videoUrl, documentUrl, paidBy, availabilityRaw, firstShownAt, lastShownAt, totalImpressionsRaw, totalImpressionsMin, totalImpressionsMax, impressionsByCountry[{country, percentage}], targeting[{category, included[], excluded[]}], scrapedAt.
Behaviors an agent should know:
- Always set
maxItems; a broad keyword can match thousands of ads. impressionsMinValuerequires a unit (none/thousand/million); a one-sided range is completed automatically.includedTargetingFacetCategoriesaccepts only:LANGUAGE,LOCATION,AUDIENCE,DEMOGRAPHIC,COMPANY,EDUCATION,JOB,INTERESTS_AND_TRAITS.- Impressions and targeting are absent for non-EU ads — don't treat that as a scrape failure.
- Billing is per dataset item plus a per-run start fee; failed ads are not pushed and not charged.
- Set
scrapeAdDetails: falsefor a cheap, fast listing-only pass without impressions or targeting.
⚠️ Disclaimer
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn Corporation, Microsoft Corporation, or any of their subsidiaries. All trademarks mentioned are the property of their respective owners.
The scraper accesses only the publicly available LinkedIn Ad Library, which LinkedIn publishes for advertising transparency — no authenticated endpoints, paid features, or member content behind the linkedin.com login wall. The optional sessionCookie input is supplied by the user, applies only to those same public Ad Library pages, and is never required. Users are responsible for ensuring their use complies with LinkedIn's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.
SEO Keywords
linkedin ads scraper, scrape linkedin ads, linkedin ad library scraper, linkedin ads api, linkedin.com ad library scraper, Apify linkedin ads, ad library scraper, ad intelligence scraper, competitor ads scraper, ad creative scraper, ad impressions data, ad targeting data, competitive ad intelligence, ad spend research, b2b advertising data, DSA ad transparency data, marketing intelligence scraper, paid social data, adtech data extraction, b2b marketing research