How to use it: 3 steps
- Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
- Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example:
Apifyin Company names. Each start is one run. - Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.
This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.
What it does
Scrape ads from the public LinkedIn Ad Library by company, keyword or payer, and get each ad's text, CTA, images or video, run dates, impressions by country and targeting.
- Who runs it: advertiser name, LinkedIn company ID and page, logo, and who paid for the ad.
- The ad itself: format (image, video, document, carousel, text, message and more), headline, full text, CTA button and link, landing domain, images, video, document pages, carousel cards.
- When and how much: first and last date shown, days running, impressions range, and the share of impressions by country.
- Targeting: what LinkedIn shows about the audience: language, location, job, company and other categories, with included and excluded values.
Good for
- Watch a competitor's LinkedIn ads: texts, offers, CTAs and landing pages.
- Find ads about a topic in chosen countries and a date range.
- Get only ads you have not seen before, on a schedule.
Who uses it
Marketers
Watch the texts, offers and CTAs of rival ads.
Agency teams
Find ads about a topic in chosen countries and dates.
Market researchers
Track new ads on a schedule.
Price
Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.
| What you pay for | Price | When |
|---|---|---|
| Ad | $0.0018 (from $0.00126 on paid Apify plans) | One ad written to the dataset (card data from search results). |
| Ad details | $0.0018 (from $0.00126 on paid Apify plans) | Full ad page loaded: full text, media, dates, impressions by country and targeting. Only when includeDetails is on and the page loaded. |
| Search | $0.001 | One search (company, keyword, payer, URL or ad ID list) started. |
| Ad checked | $0.0001 | An ad that was read but not written: already seen in onlyNew mode, removed by a format filter, or an ad ID that was not found. |
Examples
- One result: about $0.0018.
- 1,000 results: about $1.80.
- Every day 100 results, for 30 days: about $5.40 a month.
Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 2,700 results.
Prices checked on 8 November 2026. See the current price on Apify.
Questions
Do I need a LinkedIn account or cookies?
No. The Actor reads the public LinkedIn Ad Library without login.
Why are dates, impressions and targeting empty for some ads?
LinkedIn shows them only for ads shown in the EU. Impressions are a range, not an exact number.
Does it get every ad of a company?
It gets what the Ad Library shows for your search, up to maxAds. The library holds ads from about the last year.
How fresh is the data?
Each row is read at run time (fetchedAt). lastSeen is the last day LinkedIn says the ad ran.
Can I use the input from another LinkedIn Ad Library Actor?
Mostly yes: startUrls, resultsLimit, skipDetails and maxConcurrency are supported.
Details
Step by step on Apify
- Open the Input tab. Company names already has
Apify(box 1 in the picture). Replace it with your competitor's name. - Open Limits and details (box 2). Keep Max ads per search at
10for a first test. Keep Open each ad for full details on to get the full text, dates, impressions and targeting. - Click Start at the bottom of the page (below the form, not in the picture).
- Open the Output tab (box 1 below). The Ads view (box 2) shows the advertiser, format, text, CTA, landing URL, dates and impressions. Dates, impressions and targeting shows reach by country and targeting.
Use cases
| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| See all ads of a competitor | companyUrls or companyNames | ad | headline, body, ctaUrl, firstSeen, lastSeen | CSV or Excel export |
| Find ads about a topic in some countries | keywords + countries + dateRange | ad | advertiserName, body, format, impressionsText | Google Sheets via export |
| Check where and to whom an ad was shown | adIds or companyNames | ad | impressionsByCountry, targeting | your BI tool via API |
| Get only new competitor ads every week | companyUrls + onlyNew | ad | changeStatus, firstFoundAt, adLibraryUrl | Schedule + Slack or Notion |
Tips for better results
- Use companyUrls or exactCompanyMatch for one exact company. A name search can find similar names.
- Use countries with EU countries to get dates, impressions and targeting.
- Turn on onlyNew and run on a schedule to see ads you have not seen.
Limits and good to know
- Up to 5000 ads for each search and up to 100 searches in one run
- One run makes at most 3000 requests to LinkedIn and runs at most 1 hour. With details, each ad needs about 1.25 requests, so one run gives about 2000–2400 ads with details (our test: 2400 ads in 33 minutes). Without details, 5000 ads need about 220 requests. When a limit is reached, the run stops, keeps the saved ads and ends with
PARTIALand reasonTIME_LIMIT(the run still succeeds). The default run timeout is 1 hour; a shorter timeout gives fewer ads - If two searches in a row fail because LinkedIn does not answer, the Actor skips the remaining searches and says so in
RUN_SUMMARY.warnings. You pay nothing for skipped searches onlyNewremembers up to 20,000 ads for eachstateName; the oldest are forgotten first- Run dates, impressions and targeting exist only for ads shown in the EU. LinkedIn shows impressions as a range, not an exact number
- The library has ads from about the last year. LinkedIn decides what it shows; the Actor does not promise every ad an advertiser ever ran
- Search by company name can find companies with similar names. Use
companyUrlsorexactCompanyMatchfor one exact company - No personal profiles, no login, no private data. Image and video links come from LinkedIn and can expire
For developers
Sample result
One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.
{
"adId": "1612091784",
"adLibraryUrl": "https://www.linkedin.com/ad-library/detail/1612091784",
"advertiserName": "Apify",
"advertiserId": "10608457",
"paidBy": "Apify Technologies s.r.o.",
"format": "document",
"headline": null,
"body": "How would you explain your job to your grandparents? …",
"bodyIsPreview": false,
"ctaLabel": null,
"document": { "title": "How would you explain your job to your grandparents", "pageCount": 12 },
"firstSeen": "2026-10-26",
"lastSeen": "2026-11-01",
"daysRunning": 7,
"impressionsText": "150k-200k",
"impressionsByCountry": [
{ "country": "United Kingdom", "percent": 45, "lessThanOnePercent": false },
{ "country": "Canada", "percent": 23, "lessThanOnePercent": false }
],
"targeting": [
{ "category": "Language", "included": ["English"], "excluded": [] },
{ "category": "Location", "included": ["DACH", "United States", "Canada"], "excluded": ["India"] }
],
"hasTransparencyData": true,
"detailsStatus": "ok",
"searchSource": "Apify",
"fetchedAt": "2026-11-01T04:42:47.016Z"
}Use it from code
Actor ID: cliqtomedia/linkedin-ad-library. You need your Apify API token from Apify Console → Settings → API & Integrations.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/linkedin-ad-library").call(run_input={
"companyNames": [
"Apify"
],
"dateRange": "all-time"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~linkedin-ad-library/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"companyNames": ["Apify"], "dateRange": "all-time"}'# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("cliqtomedia/linkedin-ad-library")
result = tool.invoke({"run_input": {"companyNames": ["Apify"], "dateRange": "all-time"}})
print(result)The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.
Data fields (40)
| Field | Type | Meaning |
|---|---|---|
adId | string | LinkedIn Ad Library ID of the ad. |
adLibraryUrl | string | Public Ad Library link to this ad. |
advertiserName | string | Advertiser shown on the ad. |
advertiserUrl | string | Advertiser LinkedIn page link. |
advertiserId | string | Numeric LinkedIn company (or member) ID of the advertiser. |
advertiserType | string | company or member (Thought Leader ads run from a person's post). |
advertiserLogoUrl | string | Advertiser logo image. |
paidBy | string | "Paid for by" entity. |
format | string | Normalized format: image, video, carousel, document, message, article, text, spotlight, follower, event, job, other. |
formatLabel | string | Format as LinkedIn labels it, e.g. Single Image Ad. |
creativeType | string | LinkedIn creative type code, e.g. SPONSORED_VIDEO. |
headline | string | Headline under the image or video, when the ad has one. |
body | string | Ad text (introductory text or message body). |
bodyIsPreview | boolean | true when body is the shortened search-card text (details off or unavailable). |
description | string | Description line under the headline. |
ctaLabel | string | Call-to-action button text, e.g. Learn more, Join. |
ctaUrl | string | Where the ad sends people: the click URL of the headline or image, or, when the ad has none (often video ads), the first link in the ad text. LinkedIn's own tracking parameters are removed. |
landingDomain | string | Domain of ctaUrl. |
bodyLinks | array | External links in the ad text, in order (LinkedIn hashtag and profile links excluded). |
images | array | Image URLs of the creative (all carousel cards included). |
videoUrl | string | Video file URL. |
videoPosterUrl | string | Video thumbnail URL. |
document | object | Document ad: title, pageCount, coverImageUrls, manifestUrl. |
carousel | array | Carousel cards: imageUrl and title. |
messageButtons | array | Buttons of message / conversation ads. |
hashtags | array | Hashtags linked in the ad text. |
variantsCount | integer | How many creative versions LinkedIn shows for this ad. |
variants | array | Other versions: headline, body, ctaLabel, ctaUrl, images, videoUrl. |
firstSeen | string | First day the ad ran (YYYY-MM-DD); shown for EU ads. |
lastSeen | string | Last day the ad ran (YYYY-MM-DD); shown for EU ads. |
daysRunning | integer | Days between firstSeen and lastSeen, both included. |
availabilityText | string | LinkedIn note about dates when exact ones are not shown. |
impressionsText | string | Impressions range as LinkedIn shows it, e.g. 1k-5k. |
impressionsMin | integer | Lower bound of impressions. |
impressionsMax | integer | Upper bound of impressions. |
impressionsByCountry | array | Share of impressions by country: country, percent, lessThanOnePercent. |
targeting | array | Targeting by category: category, included, excluded. |
targetingParameters | array | Targeting parameters: parameter, targeted, excluded. |
hasTransparencyData | boolean | true when LinkedIn shows dates, impressions and targeting (ads shown in the EU). |
detailsStatus | string | ok, not_found, failed, not_requested or skipped. |
Input settings (25)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| Company names | companyNames | array | ["Apify"] |
| Company page URLs or IDs | companyUrls | array | |
| Keywords | keywords | array | |
| Paid by | payers | array | |
| Ad Library URLs | startUrls | array | |
| Ad IDs | adIds | array | |
| Countries | countries | array | |
| Date range | dateRange | string | "all-time" |
| From date | startDate | string | |
| To date | endDate | string | |
| Min impressions | impressionsMin | integer | |
| Max impressions | impressionsMax | integer | |
| Targeting includes | targetingIncluded | array | |
| Targeting excludes | targetingExcluded | array | |
| Ad formats | adFormats | array | |
| Exact company match | exactCompanyMatch | boolean | false |
| Order | sortOrder | string | "newest" |
| Max ads per search | maxAds | integer | 10 |
| Open each ad for full details | includeDetails | boolean | true |
| Track new ads | trackChanges | boolean | false |
| Only new ads | onlyNew | boolean | false |
| Tracking memory name | stateName | string | "linkedin-ad-library-state" |
| Advertiser comparison summary | includeAdvertiserSummary | boolean | false |
| Ad pages read at once | concurrency | integer | |
| Pause between requests (ms) | requestDelayMs | integer |
Use cases with this tool
Each guide shows all the steps and the other tools.