LinkedIn Ads Library Scraper - No Cookies avatar

LinkedIn Ads Library Scraper - No Cookies

Pricing

$19.99/month + usage

Go to Apify Store
LinkedIn Ads Library Scraper - No Cookies

LinkedIn Ads Library Scraper - No Cookies

Search the LinkedIn Ad Library by keyword or by advertiser and export every single ad with its headline, body copy, format, media and destination link. See exactly which campaigns your competitors are running now, and build creative swipe files for your paid social team, with no login needed.

Pricing

$19.99/month + usage

Rating

0.0

(0)

Developer

SilentFlow

SilentFlow

Maintained by Community

Actor stats

1

Bookmarked

17

Total users

0

Monthly active users

6 days ago

Last modified

Share

LinkedIn Ads Library Scraper

This monthly rental is being retired on 1 October 2026. Apify is removing monthly rentals across the platform. The pay-per-result version of this scraper is LinkedIn Ads Library Scraper: same data, same inputs, and you are billed for what a run returns instead of a fixed monthly fee. Move across whenever you are ready, your runs and integrations work the same way.

Scrape LinkedIn Ads Library without cookies or login. Extract ad creatives, targeting data, impressions, and advertiser information from any LinkedIn ad campaign.

What does LinkedIn Ads Library Scraper do?

This Actor allows you to extract comprehensive data from LinkedIn's public Ads Library. You can:

  • Search by keywords - Find ads containing specific terms like "AI", "SaaS", "recruiting"
  • Scrape by advertiser - Get all ads from specific companies (NVIDIA, Microsoft, etc.)
  • Direct URL scraping - Extract data from specific ad detail pages
  • Filter by country - Target ads shown in specific regions
  • Filter by date - Focus on recent campaigns or historical data

No authentication or LinkedIn account required - the scraper works with publicly available data.

What LinkedIn publishes, and what it does not

Four columns are on every row, in every mode, and this one is a promise: the ad's identifier (adId), its link on LinkedIn (url), the search term, company page or ad link that produced it (sourceQuery), and detailsStatus, which says why that row's published columns are filled or empty.

Everything else depends on the ad and on the page LinkedIn shows for it. A text ad carries no image, an ad whose button is not a link carries no destination, and an ad link pasted straight into adUrls sometimes opens on a page that no longer names its advertiser. In all of those cases the column comes back empty rather than filled with something invented, which is why the advertiser name is on 100% of the rows of a keyword search below and on 2 of 4 rows of a run made only of pasted ad links.

Run dates, impressions and targeting are a case apart. LinkedIn only publishes those for ads that were shown in Europe, and it publishes them one at a time, so an ad can come back with an impression range and no targeting at all. No scraper can fill them for an ad LinkedIn never published them for. This is a limit of the Ad Library itself, not of this Actor.

They also depend on one choice of yours. With skipDetails on, a keyword or company search stops at the search list and never opens the ad pages, so those three columns are empty on every row of that scan, whatever the ad, and each row says exactly that in detailsStatus. Ad links pasted in adUrls always open their own page, so their rows keep the full data even with the option on.

So rather than promise columns, here is what five real runs delivered, counted row by row:

Column12 sources, 8 ads asked for12 sources, 70 ads asked forSame input, run again4 pasted ad linksSame 12 sources, skipDetails on
ad id, ad link, source, detailsStatus8 of 870 of 7070 of 704 of 470 of 70
advertiser name8 of 869 of 7070 of 702 of 470 of 70
format8 of 869 of 7070 of 703 of 470 of 70
body copy8 of 869 of 7070 of 703 of 469 of 70
media8 of 867 of 7057 of 703 of 462 of 70
paying advertiser8 of 869 of 7023 of 703 of 43 of 70
headline5 of 831 of 7030 of 702 of 455 of 70
call to action4 of 826 of 707 of 701 of 42 of 70
destination link1 of 824 of 7011 of 700 of 41 of 70
run dates2 of 810 of 706 of 701 of 41 of 70
impressions2 of 811 of 704 of 701 of 41 of 70
targeting2 of 811 of 706 of 701 of 41 of 70

The third column is the same input as the second, run again a few minutes later. It is there because a run can also have a bad day: that time, 47 of the 70 ad pages did not open before the time given to their source ran out, so those rows carry search results only and say so in detailsStatus, and the columns that come from the ad page drop accordingly. The run says the same thing in its own status message, so you never have to guess which run you got.

The last column is the same 12 sources as the second, this time with skipDetails on. 67 of its 70 rows came from the search list alone: their ad pages were never opened, so run dates, impressions, targeting, the paying advertiser and the destination link are empty on all of them, and every one of those rows says so in detailsStatus. The 3 rows that still carry the full data are the pasted ad links, which open their own page in every mode. That is the trade: the columns the search list shows, delivered much faster.

Every row also carries a detailsStatus column telling you exactly which case it is:

detailsStatusMeaning
run dates, impressions or targeting publishedLinkedIn published at least one of the three for this ad. Which ones are filled is visible on the row itself
no run dates, impressions or targeting published by LinkedInThis ad was not shown in Europe, so all three columns are empty at the source
ad page could not be readThis row's ad page was asked for and answered nothing usable, so the row carries search results only. Running the same input again a few minutes later usually returns it
ad page not opened before this source ran out of timeThis row's ad page was never asked for: its keyword, company page or ad link ran out of time first. Running the same input again returns the same rows. Ask for fewer ads, or fewer sources, and they come back filled in
ad page still opening when this source ran out of timeThis row's ad page was asked for and was still being read when its keyword, company page or ad link ran out of time. Same answer as the row above: running the same input again returns the same rows, and asking for fewer ads, or fewer sources, brings them back filled in
ad page not opened because detail pages were skippedYou ran with skipDetails on, so this row is what the search list showed. Run dates, impressions and targeting are never filled on these rows, whatever the ad. Turn the option off to collect them

The run's own status message counts those three columns separately, on the rows that really carry each one, so you can see at a glance how much of a run carries what. Rows are grouped by what actually happened to them, and each group gets the reason that is true of it: the run dates, impressions and targeting figures are divided by the rows whose ad page was really read and by nothing else, rows from a skipDetails scan are named against the option you left on, rows whose page answered nothing are counted apart from rows the time ran out on. That last distinction is the difference between an input worth running again and an input worth trimming, so you are never sent to re-run something that would return exactly the same rows. The rows the time ran out on are counted together in that message, because you do the same thing about all of them, and detailsStatus still tells you row by row which were never opened and which were still being read when the time was up. After that, and for as long as the run page has room to show it, the message says what became of the keywords, company pages and ad links you listed: how many ran out of time and returned only part of what they had, how many returned no ad, and how many added no row because the number of ads you asked for was already reached. The reasons your rows are empty come first and are always there in full, because that is what you cannot work out from anywhere else. If you need impressions and targeting on most rows, leave skipDetails off and search with countries set to European countries.

Use Cases

Competitive Intelligence

Monitor your competitors' advertising strategies. Track what messaging they use, which audiences they target, and how their campaigns evolve over time.

Market Research

Analyze advertising trends in your industry. Discover what types of ads perform well, common messaging patterns, and targeting strategies across different sectors.

Ad Creative Inspiration

Build a library of successful ad creatives for inspiration. See what headlines, images, and CTAs top advertisers are using in your niche.

Brand Monitoring

Track how your brand or products are being mentioned in LinkedIn advertising. Monitor unauthorized use of your brand assets.

Academic Research

Study digital advertising patterns, targeting practices, and EU transparency compliance for research purposes.

Sales Prospecting

Identify companies actively advertising on LinkedIn as potential sales leads - they have marketing budget and are growth-focused.

Input Parameters

ParameterTypeDescriptionDefault
keywordsarrayKeywords to search for ads (e.g., ["AI", "software"])[]
startUrlsarrayAd Library URLs pasted straight from your browser (search, ad, or company)[]
adUrlsarrayDirect LinkedIn ad URLs to scrape[]
advertiserUrlsarrayLinkedIn company URLs to get ads from[]
countriesarrayISO country codes to filter by (e.g., ["US", "GB"])[]
dateRangestringDate range filter"last-30-days"
skipDetailsbooleanFaster list-only scan. Keyword and company searches stop at the search list, ad links pasted in adUrls still open their own pagefalse
maxItemsintegerMaximum ads to return in total (replaces the older limit)50
proxyobjectProxy configurationResidential proxy

Date Range Options

  • last-30-days - Ads from the last 30 days
  • this-month - Ads from this month
  • this-year - Ads from this year
  • last-year - Ads from last year
  • all-time - All ads since June 2023

Example Input

Search by Keywords

{
"keywords": ["AI", "machine learning"],
"countries": ["US"],
"dateRange": "last-30-days",
"maxItems": 50
}

Scrape Specific Ads

{
"adUrls": [
"https://www.linkedin.com/ad-library/detail/722903093",
"https://www.linkedin.com/ad-library/detail/723011893"
]
}

Get Ads from a Company

{
"advertiserUrls": [
"https://www.linkedin.com/company/nvidia",
"https://www.linkedin.com/company/microsoft"
],
"dateRange": "this-month",
"maxItems": 25
}

Output Format

Each ad in the output contains comprehensive data including advertiser info, ad creative, targeting, and performance metrics (for EU ads):

{
"adId": "1126085984",
"url": "https://www.linkedin.com/ad-library/detail/1126085984",
"advertiserName": "Evija Iesalniece",
"advertiserId": "evija-iesalniece-b693128",
"advertiserUrl": "https://www.linkedin.com/in/evija-iesalniece-b693128",
"advertiserLogo": "https://media.licdn.com/dms/image/...",
"advertiserTitle": "Global HR Director Capital Equipment | Human Capital Strategy",
"adFormat": "single_image",
"adContent": "The Most Important Human Skill in 2026 - Critical Thinking...",
"headline": "The #1 Human Skill in 2026 is Critical Thinking",
"callToAction": "Learn More",
"destinationUrl": "https://example.com/landing-page",
"mediaUrl": "https://media.licdn.com/dms/image/...",
"mediaType": "image",
"startDate": "Jan 18, 2026",
"endDate": "Jan 19, 2026",
"adDuration": "Jan 18, 2026 - Jan 19, 2026",
"countries": ["DE", "US"],
"impressions": "10k-20k",
"impressionsByCountry": [
{"country": "United States", "percentage": "45%"},
{"country": "Germany", "percentage": "30%"}
],
"targeting": {
"language": "English",
"locations": ["Germany", "United States"]
},
"payingAdvertiser": "Hyva",
"detailsStatus": "run dates, impressions or targeting published",
"sourceQuery": "AI",
"scrapedAt": "2026-01-20T16:06:02Z"
}

Output Fields

Core Fields

FieldDescription
adIdUnique LinkedIn ad identifier
urlLinkedIn Ads Library URL
advertiserNameCompany/advertiser name
advertiserIdLinkedIn company or profile ID
advertiserUrlAdvertiser's LinkedIn page
advertiserLogoAdvertiser logo URL
advertiserTitleAdvertiser's job title/position

Ad Creative Fields

FieldDescription
adFormatAd type: single_image, video, carousel, text, document
adContentAd body text/description
headlineAd headline
callToActionCTA button text (Learn More, Sign Up, etc.)
destinationUrlLanding page URL
mediaUrlPrimary media URL (image creative, video poster, or first page of a document ad)
mediaTypeMedia type: image, video, carousel, document
mediaUrls / imageUrlsEvery page of a document ad, every slide image of a carousel
slidesCarousel slides, each with its own headline and image
videoUrlVideo file of a video ad
documentUrlDocument file of a document ad
ctasEvery call-to-action label found on the ad

Timing Fields

FieldDescription
startDateWhen the ad started running
endDateWhen the ad stopped (if applicable)
adDurationHuman-readable duration (e.g., "Jan 1 - Jan 31, 2026")

Targeting & Reach (ads shown in Europe only)

LinkedIn publishes these for ads that ran in Europe. For every other ad they come back empty, and detailsStatus says so on the row.

FieldDescription
countriesCountry codes taken from the published reach and targeting, never guessed from page text
impressionsImpression range (e.g., "10k-20k")
impressionsByCountryBreakdown by country with percentages
targetingStructured targeting object
targeting.languageTarget language
targeting.locationsTarget regions/countries

Other Fields

FieldDescription
payingAdvertiserEntity paying for the ad
detailsStatusWhy this row's run dates, impressions and targeting are filled or empty
sourceQueryKeyword, company or link that produced this row
scrapedAtTimestamp when scraped

Notes

  • Data availability: LinkedIn Ads Library contains ads that ran after June 1, 2023
  • Ad retention: Ads remain visible for one year after their last impression
  • Run dates, impressions and targeting: published by LinkedIn only for ads shown in Europe, and never collected at all for a skipDetails scan, for an ad page that answered nothing, for one the run never got to, or for one that was still being read when the time ran out. Every row without them says which of the five it is in detailsStatus
  • Headline and call to action: only ads whose creative carries them return them. An ad with no button returns an empty callToAction rather than a made-up one
  • Best results: search with countries set to European countries when you need impressions and targeting on most rows

URL Formats

https://www.linkedin.com/ad-library/search?keyword=AI

Ad Detail Page

https://www.linkedin.com/ad-library/detail/722903093
https://www.linkedin.com/ad-library/search?accountOwner=nvidia

Integrations

This Actor can be integrated with:

  • Apify API - Call programmatically from any language
  • Webhooks - Get notified when scraping completes
  • Scheduled runs - Monitor ads on a regular basis
  • Google Sheets - Export directly to spreadsheets
  • Zapier/Make - Connect to 1000+ apps

Building Locally

# Install dependencies
go mod download
# Build
go build -o actor .
# Run with test mode
TEST_MODE=true ./actor
# Run with input file
./actor

Other LinkedIn Scrapers

Check out our other LinkedIn scraping tools:

ActorDescription
LinkedIn Jobs ScraperExtract job listings with salary, requirements, and company info
LinkedIn Profile ScraperScrape profile data, work experience, education, and skills
LinkedIn Posts ScraperExtract posts, reactions, comments, and author details
LinkedIn Sales Navigator ScraperScrape leads and accounts from Sales Navigator
LinkedIn Events ScraperExtract event details, attendees, and organizer info

Support

Every run ends with a status message saying how many ads reached your dataset, then how many rows had their ad page read, how many of those carry run dates, how many carry impressions and how many carry targeting, counted one column at a time on the rows that really carry it, and what became of each source you listed. Rows whose ad page answered nothing and rows the time ran out on are counted apart from each other and from everything else, because the first is worth running again and the second is worth trimming the input for. While a run works it repeats where it stands every few seconds, counting the same thing: rows already written, never pages opened. If a run returns less than you expected, that message and the detailsStatus column tell you why before you have to ask anyone.


Made by SilentFlow