LinkedIn Ad Library Scraper — Competitor LinkedIn Ads Library
Pricing
from $0.35 / 1,000 ads
LinkedIn Ad Library Scraper — Competitor LinkedIn Ads Library
Scrape every ad a company runs in the LinkedIn Ads Library, with the full detail page: copy, landing URL with UTMs, payer, run dates, impressions by country and targeting. Pin a competitor by company URL, or search by keyword or country. Monitoring, company facts, AI tags. No login.
Pricing
from $0.35 / 1,000 ads
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Every ad a company runs on LinkedIn, with the whole detail page — the full copy, the destination URL with its UTMs, who paid, the run dates, the impressions by country and the targeting the advertiser chose. Pin the company by its LinkedIn URL, id or slug and get its own ads, not the partner agencies' that mention its name. Search by keyword, payer or country too, with LinkedIn's own filters. Every format: single image, video, carousel with every card, document, article, event, message, text, spotlight, thought-leader ads with the member who posted, and Employer Brand cards. Follow a competitor on a schedule and get only their new ads. Same column names as our Google Ads Transparency Scraper and Meta Ad Library Scraper. Proxies are handled for you.
Why this scraper, not the other LinkedIn ad actors
- It runs. LinkedIn started refusing Apify's datacenter IPs around 2026-09-06: of four actors in this category run in parallel on 2026-09-26, three came back blocked, and nine of the actors we ran ended a blocked or empty run as "0 rows, SUCCEEDED". This actor reads through residential exits, paces each under LinkedIn's limit (about 25 requests a minute per IP, measured), and moves to a fresh exit when one is refused. A run that could not read the source ends PARTIAL or FAILED and says why — never green and empty.
- The company, not everyone who mentions it. LinkedIn's advertiser search is a name match: "hubspot" finds 2,552 ads, and 8 of the first 25 are partner agencies. Give a company URL, id or slug and the run pins the company itself (1,412 ads, 1,410 delivered on a full walk).
includeRelatedAdvertisersasks for the agencies too, when you want them. - The whole detail page, not the list card. The list shows three lines of copy; most actors stop there or drop fields on the way. Each row here carries everything the page publishes: full copy, headline, CTA, destination URL with the advertiser's UTMs, links inside the copy, every carousel card, payer, run dates, total impressions, impressions for every country including the "< 1%" rows, languages and locations targeted and excluded (the hidden "and N others" expanded), and the six-category targeting matrix. Thought-leader ads name the member who posted and the company that paid.
- LinkedIn's own filters, all of them. Countries (several at once), date presets or your own dates, impressions range, targeting categories used or excluded, newest or oldest first, and any search you set up on linkedin.com/ad-library pasted as a URL. Several searches per run, each with its own filters and cap, deduplicated across searches.
- Monitoring.
onlyNewAdsskips every ad an earlier run delivered — not returned, not charged. Every row carriesfirst_seen_atandlast_seen_at, andincludeEndedAdsadds a freeendedrow for each ad a complete scan no longer lists (LinkedIn keeps stopped ads listed for up to a year; whether an ad still runs isis_activeandlast_shownon every EU row). - Who the advertiser is.
includeCompanyInfoadds the company's public facts — industry, size, headquarters, founded, website, followers, specialties — to every ad row, and oneadvertiserrow per company. - What the ad is doing, as columns.
tagAdsreturns typed tags — angle, CTA intent, tone, offer type, funnel stage, the job function it speaks to, sentiment — each with its confidence.analyzeAdswrites the hook, the concrete offer, the audience and the strategy.ocrImageAdsreads the words in the artwork;transcribeVideoswhat the video says. No API key of yours needed. - Counts and presence.
resultType: countsreturns LinkedIn's own total per search from one page load. A company with no ads is free — run a list of companies through it to see who advertises at all. Ready-made: Check which companies advertise on LinkedIn. - The same columns as our Google and Meta ads scrapers.
advertiser_name,advertiser_id,creative_id,ad_format,headline,body_text,destination_url,cta,first_shown,last_shown,days_shown,impressions_min,impressions_max,image_url,ad_urlmean the same thing in all three. One sheet holds a competitor's Google, Meta and LinkedIn advertising.
Who it's for
- B2B marketers & demand-gen teams — read a competitor's live LinkedIn ads — the offer, the landing page with its UTMs, the formats, and which job functions and companies they target.
- Agencies — a client's category on LinkedIn in one table: who advertises, how long each ad runs, where it is shown, and what the long runners say.
- Sales & RevOps — who is spending on LinkedIn right now in your market, with the company facts to qualify them — a list of accounts with budget, from a public source.
- Researchers & compliance teams — the EU transparency data LinkedIn publishes per ad — payer, impressions by country, targeting — in columns, over time.
Quick start
Every ad one company runs
{"companies": ["https://www.linkedin.com/company/hubspot"],"maxAds": 100}
Ads shown in Germany and France in the last 30 days
{"companies": ["hubspot"],"countries": ["DE","FR"],"dateRange": "last-30-days","maxAds": 50}
A keyword across every advertiser
{"keywords": ["cybersecurity"],"maxAds": 100}
Which of these companies advertise, and how much
{"companies": ["hubspot","salesforce","pipedrive"],"resultType": "counts"}
Monitoring — only what appeared since the last run
{"companies": ["hubspot"],"onlyNewAds": true}
Output
One record per ad:
| field | meaning |
|---|---|
row_type | ad for an ad; count for a resultType: counts row; advertiser for the company facts row (includeCompanyInfo); advertiser_profile and landing_page for the free summaryRows; ended for an ad a complete scan no longer lists (includeEndedAds). |
creative_id | LinkedIn's ad id — the number in the ad's detail URL. Unique per ad; the key for onlyNewAds. Employer Brand cards, which have none, carry eb-<companyId>-<channelId>. |
ad_url | The ad's page in LinkedIn's Ad Library. |
ad_format | image, video, carousel, document, article, event, message, conversation, text, spotlight, follower, job or employer_brand. |
creative_type | LinkedIn's own name for the format (SPONSORED_STATUS_UPDATE, SPONSORED_VIDEO, SPONSORED_UPDATE_CAROUSEL, …). |
format_label | The format as LinkedIn labels it on the page ("Single Image Ad"). |
advertiser_name | The advertiser as LinkedIn shows it. |
advertiser_id | The advertiser's LinkedIn company id. Join on this across runs and platforms; companies takes it. |
advertiser_slug | The company's LinkedIn vanity name (hubspot), when the page shows it. |
advertiser_type | company, or member for an ad run from a person's profile. |
advertiser_url | The advertiser's LinkedIn page. |
advertiser_logo_url | The advertiser's logo. |
member_name | Thought-leader ads: the member whose post the company promoted. |
member_headline | Thought-leader ads: that member's headline. |
member_url | Thought-leader ads: that member's profile. |
payer | The "Paid for by" entity, without the prefix — often the legal name. |
headline | The ad's headline (the bold line under the image, the event or document title, the text ad's title). |
headline_description | The line under the headline, when the ad has one. |
body_text | The ad's full copy from the detail page, line breaks kept. For a message ad, the message. Null when details are off and the list cut the copy. |
body_text_preview | The copy as the list shows it — cut after about three lines, ending in "…" when cut. |
body_text_truncated | Whether body_text_preview was cut by LinkedIn. |
cta | The call-to-action button, as the ad words it ("Register", "Demo erhalten"). |
cta_buttons | Message ads: every button in the message ("Yes, I'm interested", "Maybe later"). |
cta_type | The CTA as one value across languages: learn_more, register, sign_up, download, apply, request_demo, view_event, … other. |
destination_url | Where the ad sends the click, with the advertiser's UTM and tracking parameters kept (LinkedIn's own trk tag removed). |
landing_domain | The destination's domain. |
links_in_text | Links written into the copy (lnkd.in, hashtags, mentions). |
image_url | The creative's image; the first card's for a carousel, the cover for an article or Employer Brand card. |
image_urls | Every image of the creative. |
video_url | The video file, highest quality. |
video_urls | Every rendition of the video: url, bitrate, type, best first. |
video_preview_url | The video's poster frame. |
document_title | Document ads: the document's title. |
document_url | Document ads: the document's page manifest on LinkedIn's CDN. |
document_cover_url | Document ads: the cover page image. |
document_pages | Document ads: how many pages the document has. |
cards | Carousel ads: every card — position, title, image_url, destination_url (when the card has its own link). |
event_name | Event ads: the event. |
event_time | Event ads: when it happens, as LinkedIn states it. |
event_location | Event ads: where ("Online", a city). |
message_sender_name | Message ads: the person the message comes from. |
message_sender_image_url | Message ads: the sender's photo. |
employer_brand_line | Employer Brand cards: the company line under the name (size · location). |
variants_count | How many versions of the ad the page shows (LinkedIn allows several; one is the norm). |
variants | The other versions, when there are several, with the same fields as the row. |
run_dates_text | The run dates as LinkedIn writes them ("Ran from Sep 23, 2026 to Sep 27, 2026"). |
first_shown | The ad's first day. EU ads only. |
last_shown | The ad's last day so far. EU ads only. |
days_shown | Days from first to last, both counted. |
is_active | Whether the ad's last day is today or yesterday — still running. Null without dates. |
launched_last_7_days | Whether the ad started in the last 7 days. |
launched_last_30_days | Whether the ad started in the last 30 days. |
long_running | Whether the ad has run 30 days or more. |
has_eu_transparency | Whether the page carries LinkedIn's EU transparency block (dates, impressions, targeting) — true for ads shown in the EU. |
impressions_bucket | Total impressions as LinkedIn states the range ("5k-10k", "< 1k"). |
impressions_min | Lower end of that range, as a number. |
impressions_max | Upper end of that range, as a number. Null for an open range ("1M+"). |
impressions_by_country | Every country LinkedIn lists for the ad, in its order: country, country_code (ISO-2), share as written ("42%", "< 1%"), share_min, share_max as numbers. |
top_country | The country with the largest share of impressions. |
countries_count | How many countries the ad was shown in. |
regions | ISO-2 codes of the countries the ad was shown in (EU ads), the shape our Google and Meta actors use. |
targeting_language | Languages the advertiser targeted. |
targeting_language_excluded | Languages the advertiser excluded. |
targeting_locations | Locations targeted, the ones behind "and N others" included ("Dallas, TX" stays one value). |
targeting_locations_excluded | Locations excluded, all of them. |
targeting_parameters | The targeting matrix: for audience, demographic, company, education, job, interests_and_traits, whether the advertiser targeted and whether it excluded by it. |
targeting_other | Any other targeting line the page shows: category, kind (includes / excludes), values. |
copy_length | Characters in the copy. |
text_language | The copy's language (ISO code), from its common words; null when too short to tell. |
sentiment_score | Free sentiment of English copy, -1..1 (AFINN word list); null for other languages and when no word is scored. |
analysis_angle | tagAds: the persuasion angle — problem_solution, social_proof, scarcity, discount, feature, lifestyle, curiosity, education, comparison, brand, other. |
analysis_cta_intent | tagAds: what the ad asks the reader to do — purchase, signup, download, learn_more, contact, visit, watch, apply, book, other. |
analysis_tone | tagAds: the tone of the copy. |
analysis_sentiment | tagAds: emotional valence, -1..1. |
analysis_offer_type | tagAds: what is offered — event_or_webinar, demo_or_consultation, free_tool_or_trial, gated_content, product_announcement, customer_story, hiring, thought_leadership, discount, other. |
analysis_funnel_stage | tagAds: awareness, consideration or conversion. |
analysis_target_function | tagAds: the job function the ad speaks to — marketing, sales, customer_success, it_security, hr_recruiting, finance, operations_logistics, executives_founders, engineering, general. |
analysis_confidence | tagAds: the confidence (0..1) of each tag, by tag name. Drop the unsure ones in your own pipeline. |
analysis_hook | analyzeAds: the line meant to stop the scroll. |
analysis_offer | analyzeAds: the concrete offer, or null when the ad makes none. |
analysis_audience | analyzeAds: who the ad is written for, in a few words. |
analysis_strategy | analyzeAds: what the advertiser is trying to achieve with the ad, in one sentence. |
ad_ocr_text | ocrImageAds: the words in an image ad's artwork (image ads only; a video's poster frame is not read). |
transcript | transcribeVideos: what the video says. |
transcript_language | transcribeVideos: the language spoken. |
hook_3s | transcribeVideos: the first three seconds of speech. |
speech_seconds | transcribeVideos: seconds of speech in the video. |
video_duration_s | transcribeVideos: the video's length in seconds. |
transcript_segments | transcribeVideos: the transcript in timed segments — start, end (seconds), text. |
advertiser_industry | includeCompanyInfo: the company's industry on LinkedIn. |
advertiser_size | includeCompanyInfo: company size as LinkedIn states it ("5,001-10,000 employees"). |
advertiser_employees_min | includeCompanyInfo: lower end of the size range. |
advertiser_employees_max | includeCompanyInfo: upper end of the size range. |
advertiser_employees_on_linkedin | includeCompanyInfo: how many members list the company as their employer on LinkedIn. |
advertiser_tagline | includeCompanyInfo: the company's tagline on its LinkedIn page. |
advertiser_similar_pages | includeCompanyInfo: the companies LinkedIn shows as similar — name, slug, industry, location. |
advertiser_headquarters | includeCompanyInfo: headquarters. |
advertiser_founded | includeCompanyInfo: year founded. |
advertiser_company_type | includeCompanyInfo: public, private, non-profit… |
advertiser_website | includeCompanyInfo: the company's website. |
advertiser_followers | includeCompanyInfo: LinkedIn followers. |
advertiser_specialties | includeCompanyInfo: the specialties the company lists. |
detail_status | ok when the detail page was read; skipped with includeDetails off; failed: … when it could not be read (not billed for details); not_found when LinkedIn no longer has the ad. |
matched_query | The search that found the ad, as you gave it. |
matched_queries | The search that delivered the ad. An ad is delivered once per run; when several of your searches listed it, all of them are in the run's MATCHES record. |
claimed_count | LinkedIn's own total for the search ("N ads match") — check completeness against it. |
first_seen_at | Monitoring (onlyNewAds / includeEndedAds): the day a run of yours first saw the ad; null without monitoring. |
last_seen_at | Monitoring: the last day a run of yours saw it. |
ended_at | ended rows: the day a complete scan stopped LISTING the ad. LinkedIn keeps an ad listed for up to a year after it stops; whether an ad still runs is is_active / last_shown. |
scraped_at | When the row was read (UTC). |
run_tag | Your runTag, copied onto every row. |
has_ads | count rows: whether the search found any ad. |
search_query | count rows: the Ad Library query that was counted. |
advertiser_description | advertiser rows: the company's About text. |
summary_ad_count | Summary rows: ads delivered for the advertiser or landing page. |
summary_active_count | Summary rows: of those, still running. |
summary_longest_days | Summary rows: the longest run, in days. |
summary_formats | Summary rows: ads per format. |
summary_landing_domains | Summary rows: every landing domain. |
summary_countries | Summary rows: countries by number of ads shown there. |
summary_distinct_copies | Summary rows: distinct copies among the ads. |
summary_ad_ids | Summary rows: the ads counted. |
display_url | landing_page rows: the destination's domain. |
Example record:
{"row_type": "ad","creative_id": "1560106944","ad_url": "https://www.linkedin.com/ad-library/detail/1560106944","ad_format": "image","creative_type": "SPONSORED_STATUS_UPDATE","format_label": "Single Image Ad","advertiser_name": "HubSpot","advertiser_id": "68529","advertiser_slug": null,"advertiser_type": "company","advertiser_url": "https://www.linkedin.com/company/68529","advertiser_logo_url": "https://media.licdn.com/dms/image/v2/C4D0BAQF8H-SLmMDZlA/company-logo_100_100/company-logo_100_100/0/1646683330132/hubspot_logo?e=1792022400&v=beta&t=qdOzAJgZz5obWiFRXGHnfG_E3HiBfKVIzZV5WxPsM-U","member_name": null,"member_headline": null,"member_url": null,"payer": "HubSpot, Inc.","headline": "Sell from anywhere, close everywhere.","headline_description": null,"body_text": "Remote-first and built on trust.\nSell from wherever you're sharpest, on your own rhythm. The results are what matter here.","body_text_preview": "Remote-first and built on trust.\nSell from wherever you're sharpest, on your own rhythm. The results are what matter he…","body_text_truncated": false,"cta": "Learn more","cta_buttons": null,"cta_type": "learn_more","destination_url": "https://www.linkedin.com/organization/68529/campaign/b9cb9124-f8ce-4243-b345-6033313f7d9d","landing_domain": "linkedin.com","links_in_text": null,"image_url": "https://media.licdn.com/dms/image/v2/D4E10AQGeVkCkkr6L1w/image-shrink_1280/B4EaBr72KLHkAc-/0/1788517245905/VariantCpng?e=2147483647&v=beta&t=ZMyfSupMWzPFERk9TiTQFkDvJFs3P-lIxdjLGxYIaTA","image_urls": ["https://media.licdn.com/dms/image/v2/D4E10AQGeVkCkkr6L1w/image-shrink_1280/B4EaBr72KLHkAc-/0/1788517245905/VariantCpng?e=2147483647&v=beta&t=ZMyfSupMWzPFERk9TiTQFkDvJFs3P-lIxdjLGxYIaTA"],"video_url": null,"video_urls": null,"video_preview_url": null,"document_title": null,"document_url": null,"document_cover_url": null,"document_pages": null,"cards": null,"event_name": null,"event_time": null,"event_location": null,"message_sender_name": null,"message_sender_image_url": null,"employer_brand_line": null,"variants_count": 1,"variants": null,"run_dates_text": "Ran from Sep 14, 2026 to Sep 27, 2026","first_shown": "2026-09-14","last_shown": "2026-09-27","days_shown": 14,"is_active": true,"launched_last_7_days": false,"launched_last_30_days": true,"long_running": false,"has_eu_transparency": true,"impressions_bucket": "30k-50k","impressions_min": 30000,"impressions_max": 50000,"impressions_by_country": [{"country": "United Kingdom","share": "42%","share_min": 42.0,"share_max": 42.0},{"country": "Ireland","share": "18%","share_min": 18.0,"share_max": 18.0},{"country": "Germany","share": "18%","share_min": 18.0,"share_max": 18.0},{"country": "Australia","share": "14%","share_min": 14.0,"share_max": 14.0},{"country": "Canada","share": "5%","share_min": 5.0,"share_max": 5.0},{"country": "United States","share": "2%","share_min": 2.0,"share_max": 2.0},{"country": "New Zealand","share": "< 1%","share_min": 0.0,"share_max": 1.0},{"country": "Spain","share": "< 1%","share_min": 0.0,"share_max": 1.0},{"country": "United Arab Emirates","share": "< 1%","share_min": 0.0,"share_max": 1.0},{"country": "Netherlands","share": "< 1%","share_min": 0.0,"share_max": 1.0}],"top_country": "United Kingdom","countries_count": 10,"regions": null,"targeting_language": ["English"],"targeting_language_excluded": null,"targeting_locations": ["Dallas","TX","Germany","Chicago","IL","Toronto","ON","Australia","Ireland","United Kingdom"],"targeting_locations_excluded": ["India","New Zealand","United Arab Emirates"],"targeting_parameters": {"audience": {"targeted": false,"excluded": false},"demographic": {"targeted": false,"excluded": false},"company": {"targeted": true,"excluded": true},"education": {"targeted": false,"excluded": false},"job": {"targeted": true,"excluded": false},"interests_and_traits": {"targeted": false,"excluded": false}},"targeting_other": null,"copy_length": 122,"text_language": "en","sentiment_score": 0.2,"analysis_angle": "lifestyle","analysis_cta_intent": "learn_more","analysis_tone": "professional","analysis_sentiment": 0.51,"analysis_offer_type": "hiring","analysis_funnel_stage": "consideration","analysis_target_function": "sales","analysis_confidence": {"angle": 0.97,"cta_intent": 1.0,"tone": 0.55,"offer_type": 0.56,"funnel_stage": 0.86,"target_function": 1.0,"sentiment": 0.97},"analysis_hook": null,"analysis_offer": null,"analysis_audience": null,"analysis_strategy": null,"ad_ocr_text": null,"transcript": null,"transcript_language": null,"hook_3s": null,"speech_seconds": null,"video_duration_s": null,"transcript_segments": null,"advertiser_industry": null,"advertiser_size": null,"advertiser_employees_min": null,"advertiser_employees_max": null,"advertiser_employees_on_linkedin": null,"advertiser_tagline": null,"advertiser_similar_pages": null,"advertiser_headquarters": null,"advertiser_founded": null,"advertiser_company_type": null,"advertiser_website": null,"advertiser_followers": null,"advertiser_specialties": null,"detail_status": "ok","matched_query": "hubspot","matched_queries": ["hubspot"],"claimed_count": 187,"first_seen_at": null,"last_seen_at": null,"ended_at": null,"scraped_at": "2026-09-27T09:59:51Z","run_tag": null,"has_ads": null,"search_query": null,"advertiser_description": null,"summary_ad_count": null,"summary_active_count": null,"summary_longest_days": null,"summary_formats": null,"summary_landing_domains": null,"summary_countries": null,"summary_distinct_copies": null,"summary_ad_ids": null,"display_url": null}
Pricing
Pay only for what a run actually returns, with no start fee. Prices are per 1,000 and fall with your Apify plan:
| per 1,000 | Free | Starter | Scale | Business |
|---|---|---|---|---|
| Ad — id, format, advertiser, headline, first lines of the copy, image | $0.70 | $0.595 | $0.49 | $0.35 |
| Detail page on that ad — full copy, destination with UTMs, payer, dates, impressions by country, targeting | +$1.10 | +$0.935 | +$0.77 | +$0.55 |
Count row (resultType: counts), only when the search found ads | $10.00 | $8.50 | $7.00 | $5.00 |
Advertiser company facts (includeCompanyInfo), once per company | $4.00 | $3.40 | $2.80 | $2.00 |
Typed tags — angle, offer, funnel stage, audience function… (tagAds) | +$1.00 | +$0.85 | +$0.70 | +$0.50 |
Written analysis — hook, offer, audience, strategy (analyzeAds), model usage included | +$6.00 | +$5.10 | +$4.20 | +$3.00 |
Video transcript, when the video has speech (transcribeVideos) | +$20.00 | +$17.00 | +$14.00 | +$10.00 |
Image text read by a vision model, when words were found (ocrImageAds) | +$2.00 | +$1.70 | +$1.40 | +$1.00 |
Each fee is charged per row that actually carries the thing. A detail page that could
not be read is delivered marked (detail_status) and not billed for details; maxAds is
exact and never overshot; an ad two of your searches both find is returned and billed once.
Enterprise plans have their own rates — the Actor's Pricing tab shows the price for your plan.
Usage patterns
- Follow a competitor weekly — Put their company URL in
companies, tickonlyNewAds, save it as a task and schedule it. The first run delivers the current set; every later run only what appeared since, andis_active/last_showntell you which ads still run. Connect the task to Slack or email through Apify's integrations. Ready-made: Monitor a competitor's new LinkedIn ads weekly. - Find the ads worth copying —
minDaysRunning: 30keeps the ads an advertiser has paid to run for a month or more — the ones that work. AddtagAdsto see which angle and offer they use. Ready-made: a competitor's long-running LinkedIn ads, tagged by AI. - Map a market — A keyword with
countries, orcountriesalone insearchesfor every ad shown there, plusincludeCompanyInfo. The result is who advertises in your market, with their industry and size. - Compare against their Google and Meta ads — Run the same competitor through our Google Ads Transparency Scraper and Meta Ad Library Scraper. The three outputs share the column names, so one sheet shows all three platforms.
- Use a search you already set up — Set the filters on linkedin.com/ad-library, copy the URL from the address bar into
startUrls. Every filter in it is kept. A published Google Sheet or a text file with one URL per line works as well.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
companies | array | [] | Each entry is one advertiser: a LinkedIn company URL (linkedin.com/company/hubspot), a company id (68529), a slug (hubspot) or a name. An id, URL or slug pins the exact company — only ads that company runs, not the agencies that mention it. A name with spaces is matched as LinkedIn's advertiser-name search and kept to advertisers of exactly that name (switch on includeRelatedAdvertisers to keep the agencies too). |
keywords | array | [] | Words in the ad. One search per line, across every advertiser. |
payers | array | [] | The entity LinkedIn shows as "Paid for by" — often the legal name, e.g. HubSpot, Inc.. |
startUrls | array | [] | LinkedIn URLs: an Ad Library search you set up on linkedin.com/ad-library (every filter in it is kept), an ad's detail page, an Employer Brand page, or a company page. A text file, CSV or published Google Sheet with one URL per line works too (Link remote text file). |
adIds | array | [] | Single ads by id or detail URL (linkedin.com/ad-library/detail/1558773703): re-read an ad you already know, e.g. to watch its impressions move. |
searches | array | [] | Several searches in one run, each with its own filters and cap. Each entry names one of company, keyword, payer or url, plus any of countries, dateRange, startDate, endDate, impressionsMin, impressionsMax, targetingIncludes, targetingExcludes, sortOrder, includeRelatedAdvertisers, maxAds. An entry with only countries is every ad shown there. Example: [{"company": "hubspot", "countries": ["DE", "FR"]}, {"keyword": "webinar", "dateRange": "last-30-days", "maxAds": 200}]. |
resultType | ads / counts | "ads" | counts returns one row per search with LinkedIn's own total, from one page load and no ads scraped. A search that finds nothing is free: use it to check which of a list of companies advertise at all. |
countries | array | [] | Ads shown in these countries. Empty = everywhere. Several are combined (shown in any of them). LinkedIn ignores this filter when a targeting or impressions filter is set. |
dateRange | any / last-30-days / current-month / current-year / last-year / custom | "any" | When the ad ran, as LinkedIn's own date filter. For your own dates set startDate / endDate. |
startDate | string | YYYY-MM-DD. With an end date or alone. | |
endDate | string | YYYY-MM-DD. | |
impressionsMin | integer | LinkedIn's impressions filter. It applies to ads shown in the EU (the only ads LinkedIn publishes impressions for), and LinkedIn then ignores the country filter (measured 2026-09-28). | |
impressionsMax | integer | Upper bound for the impressions filter; EU ads only. | |
targetingIncludes | array | [] | Only ads whose advertiser targeted by these categories (EU ads). LinkedIn ignores the country filter when this is set. |
targetingExcludes | array | [] | Only ads whose advertiser excluded audiences by these categories (EU ads). |
sortOrder | newest / oldest | "newest" | The order LinkedIn lists the ads in. |
includeRelatedAdvertisers | boolean | false | For companies: also return ads by other advertisers whose name contains the company's (partner agencies, resellers, subsidiaries) — LinkedIn's own advertiser-name search. Off, only the company itself. |
adFormats | array | [] | Keep only these formats. Filtered on the list before any detail page is opened, so a skipped ad costs nothing. Conversation ads are labelled Message Ad by LinkedIn and come as message. |
minDaysRunning | integer | 0 | Only ads that ran this many days or more — the long runners, the ones worth copying. Needs run dates, which LinkedIn publishes for ads shown in the EU. |
onlyActive | boolean | false | Only ads whose last day is today or yesterday (EU ads carry dates). |
includeDetails | boolean | true | On: the full copy, destination URL with UTMs, payer, run dates, impressions by country and the targeting. Off: the list view only (the first lines of the copy, headline, format, image) — cheaper and faster. |
includeCompanyInfo | boolean | false | Industry, company size, headquarters, founded, type, website, followers and specialties from the company's public LinkedIn page — on every ad row, plus one advertiser row per company. |
tagAds | boolean | false | Typed tags per ad from a classification model: angle, CTA intent, tone, offer type, funnel stage, target job function and sentiment, each with a confidence. |
analyzeAds | boolean | false | A language model reads the ad and writes its hook, the concrete offer, who it is written for and the advertiser's apparent strategy. Model usage included. |
ocrImageAds | boolean | false | The words baked into the artwork, read by a vision model (ad_ocr_text). Model usage included. |
transcribeVideos | boolean | false | What the video says, as text, with its language and first three seconds. A silent video is checked and not billed. |
openaiApiKey | string | Your own key for analyzeAds, ocrImageAds and transcribeVideos, if you want the model usage on your account. Not needed: the Actor has its own. | |
summaryRows | boolean | false | Free rows after the ads: one advertiser_profile per advertiser (ads, still running, longest run, formats, countries, landing domains) and one landing_page per destination URL. |
outputFormat | full / compact | "full" | compact keeps the columns most people use and drops the nested ones. |
maxAds | integer | 0 | Ads delivered in the whole run, exactly (0 = no limit). Never exceeded, and you are never billed for more. |
maxAdsPerSearch | integer | 0 | Ads per company, keyword, payer or URL (0 = no limit). |
onlyNewAds | boolean | false | Skip every ad an earlier run with the same searches already delivered — not returned, not charged. Schedule the run and each one brings only what is new. |
includeEndedAds | boolean | false | Add an ended row for every ad an earlier run saw that a complete scan of the same search no longer lists. Free. |
stateStoreName | string | Name for the memory onlyNewAds and includeEndedAds use. Empty: named after your searches, so the same input on a schedule finds its own memory. | |
runTag | string | Your label, copied onto every row (run_tag), to tell runs apart in one sheet. | |
resumeFromRunId | string | The id of a run that stopped early (timeout, abort) with the same input: this run carries on from where it stopped, with no ad delivered or billed twice. |
FAQ
Why are the destination, dates, impressions and targeting empty on some ads?
LinkedIn publishes them only for ads shown in the EU (the Digital Services Act): on an ad shown only outside the EU the page carries no destination link, no run dates, no impressions and no targeting. That ad has the copy, the headline, the CTA label, the payer, the format and the media, and has_eu_transparency: false. Add EU countries to countries to get the ads that carry them. minDaysRunning and onlyActive read those dates, so they keep EU ads only.
I searched for a company by name and got ads from other advertisers.
A name with spaces is LinkedIn's advertiser-name search, which matches any advertiser whose name contains it. Without includeRelatedAdvertisers the run keeps only advertisers of exactly that name. For the company itself and nothing else, give its LinkedIn company URL, id or slug: that pins it.
How complete is a company's list?
A company's walk runs to the end of LinkedIn's list: 1,410 of HubSpot's 1,412 ads on the full walk we measured (2026-09-27). Every row carries claimed_count, LinkedIn's own total, so you can check it on your run.
What does a row cost me, and what if a page fails?
Per ad, and per detail page read. A detail page that could not be read is still delivered, marked detail_status: failed…, and not billed for details. maxAds is exact. Nothing is billed for a run that failed.
What are Employer Brand ads?
LinkedIn's "Company Discovery Reminder" ads: a company card inviting candidates to follow it. They carry no ad id; the row's creative_id is eb-<companyId>-<channelId>, stable across runs.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/linkedin-ad-library-scraper').call({"companies": ["https://www.linkedin.com/company/hubspot"], "maxAds": 100});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/linkedin-ad-library-scraper').call(run_input={'companies': ['https://www.linkedin.com/company/hubspot'], 'maxAds': 100})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/linkedin-ad-library-scraper --input '{"companies": ["https://www.linkedin.com/company/hubspot"], "maxAds": 100}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~linkedin-ad-library-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"companies": ["https://www.linkedin.com/company/hubspot"], "maxAds": 100}'
Support
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.