LinkedIn Ads Scraper
Scrape the LinkedIn Ad Library with no login. Get the advertiser, the company paying, ad copy, headline, CTA and landing URL. $0.25 per 1,000 ads.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
companies,keywords,payers(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.00025 per ad = $0.25 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Ad scraped | One LinkedIn Ad Library ad written to your dataset: advertiser, payer, ad copy, headline, call to action, image or video creative, landing URL, ad format, and - where LinkedIn discloses it - run dates, impressions band, countries and targeting. Sample rows, duplicate ads, searches that matched nothing and ads that could not be read are never charged. | $0.00025 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-16, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
companies | Company names as they appear on LinkedIn ("HubSpot"), or LinkedIn company URLs (https://www.linkedin.com/company/hubspot). Up to 20 per run. A URL with a numeric id filters exactly; a name or a vanity URL matches the advertiser name, which can catch more than one page. | array |
keywords | Words or phrases searched inside the text of the ad. Several words in one entry are combined with AND. Up to 20 per run. | array |
payers | The entity that paid for the ad, which is often a media agency rather than the brand. Useful for mapping an agency's whole client roster. Up to 20 per run. | array |
countries | Two-letter ISO country codes, e.g. DE, FR, US. Applied to every search above. Give countries on their own to sweep everything advertised into that country. Tip: an EU country here also switches on the run dates, impressions and targeting fields, which LinkedIn only discloses for ads delivered into the EU. | array |
dateRange | Limit results to ads served in this window. Leave on "all" for everything the library holds. | string |
dateFrom | YYYY-MM-DD. Fill both custom dates to use an exact window instead of the preset above. LinkedIn only accepts dates within the last twelve months. | string |
dateTo | YYYY-MM-DD. Ignored unless the custom start date is filled in too. | string |
maxItems | Total rows to return across every search. The budget is shared evenly, so four searches and 200 rows gives you fifty of each. Default 20, hard ceiling 2,000. Keep it low while testing - you pay per ad. | integer |
includeAdDetails | On by default, and what you want. It is the only place LinkedIn publishes the untruncated ad copy, the landing URL, the run dates, the impressions band, the country split and the targeting. Switch it off for a fast advertiser/creative-only sweep; the price per ad is the same either way. | boolean |
proxyUrls | Leave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port. | array |
What you get
A structured dataset — each result includes fields like:
searchTermadvertiserNameadTypeadTextheadlinecallToActionlandingUrlimageUrlvideoUrlfirstShownDatelastShownDatetotalImpressionscountriespayerNameExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Developer & Research Tools
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
GitHub Scraper
Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.
Stack Overflow / Stack Exchange Scraper
Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.
Package Registry Scraper (npm + PyPI)
Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.
arXiv Scraper
Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.
OpenAlex Scholarly Works Scraper
Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.
Crossref Scholarly Works Scraper
Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.
Where this tool sits
- Categories
- Developer & Research Tools
LinkedIn Ads Scraper: read the LinkedIn Ad Library by company, keyword or payer
Search the public LinkedIn Ad Library without an account and get one row per ad: the advertiser, the company that actually paid, the ad copy, the headline, the call to action, the creative image or video and the landing URL.
Two things to know before you start. The library holds roughly the last twelve months, so anything older is simply not there. And the run dates, the impressions band and the targeting are only published for ads delivered into the EU, so on a US or UK search those fields come back null and that is LinkedIn's rule, not a gap in the row.
| Input | Company names or URLs, keywords, payer names, country codes |
| Output | One row per ad |
| Ceiling | 2,000 ads per run |
| Account needed | None |
| Price | $0.25 per 1,000 ads, flat on every plan |
📣 What LinkedIn Ads Scraper does
The Ad Library is open to anyone, but it is built for clicking through one advertiser at a time. This turns it into rows.
You can search four ways and mix them freely: by company, by words in the ad copy, by the payer, or by country on its own to sweep everything running into a market. Each term becomes its own search and the results are pooled into one dataset.
The advertiser and the payer are not always the same company, which is the part most people miss. A media agency often pays for a brand's ads, so searching the agency as a payer maps its whole client roster in one run. Both names are on every row.
By default the run also opens each ad's own detail page. That page is the only place LinkedIn publishes the untruncated copy, the landing URL, the country split and the EU disclosure fields. Turning it off makes a run faster and the price per ad does not change.
📥 What you give it
{
"companies": ["HubSpot"],
"countries": ["DE"],
"dateRange": "last-30-days",
"maxItems": 100
}
Everything is optional, but give it at least one company, keyword, payer or country. A run with none of those returns a free sample row and stops.
| Field | Starts as | What it is |
|---|---|---|
companies | prefilled with an example | Up to 20. A company name, or a LinkedIn company URL. A URL with a numeric id matches exactly; a plain name matches on advertiser name, which can pull in more than one page with that name. |
keywords | empty | Up to 20. Words searched inside the ad text. Several words in one entry are treated as AND. |
payers | empty | Up to 20. The entity billed for the ad, often an agency. |
countries | empty | Up to 20 two-letter codes, DE, FR, US. Applied to every search above, and usable on its own to sweep everything running into a market. Put an EU code here to switch on the run dates, impressions and targeting. |
dateRange | all | all, last-30-days, current-month, current-year, last-year. |
dateFrom, dateTo | empty | YYYY-MM-DD. Fill both to use an exact window instead of the preset. LinkedIn only accepts dates inside the last twelve months. |
maxItems | 20 | 1 to 2,000. Rows across the whole run. |
includeAdDetails | on | Opens each ad's detail page. Leave it on unless you only want advertiser and creative. |
proxyUrls | empty | Leave it empty. It is here for callers who want the traffic to leave through servers they already pay for, written as http://user:pass@host:port. Anything unusable in that list is reported as a free PROXY_INPUT_ADJUSTED row. |
The row budget is split evenly between your searches. Four searches and maxItems: 200 gives you fifty of each, not two hundred of the first. Set maxItems below the number of searches and each one returns a single row.
📤 What you get back
A real row from a recent run, with the media links cut short:
{
"ok": true,
"charged": true,
"recordType": "ad",
"searchTerm": "HubSpot",
"searchType": "company",
"adId": "1552531503",
"adUrl": "https://www.linkedin.com/ad-library/detail/1552531503",
"advertiserName": "HubSpot",
"advertiserUrl": "https://www.linkedin.com/company/68529",
"advertiserId": "68529",
"payerName": "HubSpot, Inc.",
"adType": "Video Ad",
"creativeType": "SPONSORED_VIDEO",
"adText": "HubSpot vereint Kundendaten, historische Daten und Teams. So wirken Kampagnen schneller, Teams arbeiten besser zusammen und nichts bleibt liegen.",
"headline": "Ergebnisse für den 9-Uhr-Termin um 8:56",
"callToAction": "Learn more",
"landingUrl": null,
"imageUrl": "https://media.licdn.com/dms/image/v2/D4D10AQH8c-Ni0tRqCQ/videocover-high/...",
"videoUrl": "https://dms.licdn.com/playlist/vid/v2/D4D10AQH8c-Ni0tRqCQ/progressive-servable-video/...",
"firstShownDate": null,
"lastShownDate": null,
"runDates": null,
"totalImpressions": null,
"countries": [],
"impressionsByCountry": [],
"targeting": [],
"isRestricted": false,
"restrictionDetails": null,
"scrapedAt": "2026-09-21T01:33:25.034Z"
}
That row is a German-language ad found by company search, and the EU fields are empty because the search was not scoped to an EU country. Add "countries": ["DE"] and they fill in.
| Field | What it is |
|---|---|
adId, adUrl | The library's own id and the page a human can open. adId is your dedupe key. |
payerName | Who paid. Often an agency, sometimes a legal entity name that differs from the brand. |
adText, headline | The copy. Full text when the detail page was opened, about 150 characters when it was not. |
landingUrl | Where the ad points. Click-tracking is stripped, campaign parameters are kept. null when details are switched off or the ad has no link. |
videoUrl | A direct link to the highest-quality version of the video, for video ads. |
totalImpressions | A band, not an exact number, because that is how it is published. EU delivery only. |
impressionsByCountry, targeting | The country split and the targeting facets, EU delivery only. |
isRestricted | true when LinkedIn has withheld the creative. The advertiser and card details still come through. |
🧾 Reading the output
Three kinds of row, and only ads cost anything.
| Row | How to spot it | Charged |
|---|---|---|
| An ad | recordType: "ad" | yes |
| The sample row | recordType: "sample", _sample: true | no |
| A diagnostic | recordType: "diagnostic", ok: false | no |
The charged field is a row marker, not a receipt. It is what separates a real ad row from a sample or a diagnostic, and it is stamped as the row is built rather than after the money moves. Your Apify run detail is the authority on what you were actually billed.
A diagnostic row carries an errorCode:
| Code | What it means |
|---|---|
NO_RESULTS | The search ran and the library holds nothing for it. More than five empty searches collapse into one row so your dataset is not flooded. |
RATE_LIMITED | Too many requests too close together. Ask for fewer rows, or space the runs out. |
BLOCKED | The library answered with a challenge page instead of results. |
SERVER_ERROR, NETWORK | LinkedIn errored, or a page could not be read. Detail-page failures all report as NETWORK, whatever the cause. |
TIME_BUDGET | The run hit its own time limit with searches left. Everything collected before that is in your dataset. |
PROXY_INPUT_ADJUSTED | Something in your proxyUrls list could not be used and was dropped. |
CHARGE_ERROR, UNEXPECTED_ERROR | Something went wrong that the run could not classify. Worth sending in. |
▶️ How to run it
1. Open LinkedIn Ads Scraper and click Try for free. 2. Put a company name in Companies / advertisers, or words in Keywords in the ad copy. 3. Add a country code in Countries if you want the EU disclosure fields. 4. Set Maximum ads, then click Start. 5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost?
$0.25 per 1,000 ads. Flat on every Apify plan, no volume tiers.
One charge per ad row. An ad that two of your searches both find is written and charged once. Sample rows and diagnostic rows are never charged, and a search that finds nothing costs you nothing for results. Opening each ad's detail page does not change the price.
💡 What people use it for
- Reading a competitor's current campaigns: the copy, the hooks, the offers and where they point.
- Mapping an agency's client list by searching the agency as the payer.
- Checking which markets a company is actually buying in, and roughly how heavily, in the EU.
- Building a swipe file of headlines and calls to action for a category before writing new ads.
🚧 What it does not do
- No spend, no budget, no CPM. The library does not publish them, and neither does this.
- Impressions are bands, and EU only. So are run dates and targeting. Outside the EU those
fields are null on every row.
- About twelve months of history. Older campaigns are gone from the library itself.
- No audience data about who saw an ad, beyond the targeting facets LinkedIn discloses.
- A name search is a name match. Two companies sharing a name both come back. Use the company
URL with the numeric id when you need exactly one advertiser.
- Restricted ads arrive without their creative. You get the card and the flag, not the image.
- No ad performance ranking. Order is the library's, and it is not by impact.
🧭 Which ad library scraper do you need?
| If you want | Use |
|---|---|
| LinkedIn ads | This one |
| Facebook and Instagram ads | Meta Ads Library Scraper |
| Google and YouTube ads | Google Ads Transparency Scraper |
| TikTok ads | TikTok Ads Scraper |
| The company page behind an advertiser | LinkedIn Companies Scraper |
❓ Questions people ask
Do I need a LinkedIn account? No, and there is no cookie field. The Ad Library is public.
Why are the dates and impressions empty? Because the ad was not delivered into the EU, or your search was not scoped to an EU country. That disclosure only exists for EU delivery.
Can I get ads older than a year? No. The library holds about twelve months and there is no archive behind it.
Why did I get fewer rows than maxItems? Either the searches found fewer ads, or your budget was split across several searches. Check searchTerm on the rows to see which.
Is scraping the Ad Library legal? It is a public transparency database LinkedIn publishes on purpose. Apify's write-up on scraping and the law is a reasonable starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and the exact search you used. The errorCode on the diagnostic row is usually enough to explain it.