LinkedIn Ad Library Scraper — Competitor LinkedIn Ads Library avatar

LinkedIn Ad Library Scraper — Competitor LinkedIn Ads Library

Pricing

from $0.35 / 1,000 ads

Go to Apify Store
LinkedIn Ad Library Scraper — Competitor LinkedIn Ads Library

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

Hyperbach

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

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). includeRelatedAdvertisers asks 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. onlyNewAds skips every ad an earlier run delivered — not returned, not charged. Every row carries first_seen_at and last_seen_at, and includeEndedAds adds a free ended row for each ad a complete scan no longer lists (LinkedIn keeps stopped ads listed for up to a year; whether an ad still runs is is_active and last_shown on every EU row).
  • Who the advertiser is. includeCompanyInfo adds the company's public facts — industry, size, headquarters, founded, website, followers, specialties — to every ad row, and one advertiser row per company.
  • What the ad is doing, as columns. tagAds returns typed tags — angle, CTA intent, tone, offer type, funnel stage, the job function it speaks to, sentiment — each with its confidence. analyzeAds writes the hook, the concrete offer, the audience and the strategy. ocrImageAds reads the words in the artwork; transcribeVideos what the video says. No API key of yours needed.
  • Counts and presence. resultType: counts returns 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_url mean 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:

fieldmeaning
row_typead 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_idLinkedIn'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_urlThe ad's page in LinkedIn's Ad Library.
ad_formatimage, video, carousel, document, article, event, message, conversation, text, spotlight, follower, job or employer_brand.
creative_typeLinkedIn's own name for the format (SPONSORED_STATUS_UPDATE, SPONSORED_VIDEO, SPONSORED_UPDATE_CAROUSEL, …).
format_labelThe format as LinkedIn labels it on the page ("Single Image Ad").
advertiser_nameThe advertiser as LinkedIn shows it.
advertiser_idThe advertiser's LinkedIn company id. Join on this across runs and platforms; companies takes it.
advertiser_slugThe company's LinkedIn vanity name (hubspot), when the page shows it.
advertiser_typecompany, or member for an ad run from a person's profile.
advertiser_urlThe advertiser's LinkedIn page.
advertiser_logo_urlThe advertiser's logo.
member_nameThought-leader ads: the member whose post the company promoted.
member_headlineThought-leader ads: that member's headline.
member_urlThought-leader ads: that member's profile.
payerThe "Paid for by" entity, without the prefix — often the legal name.
headlineThe ad's headline (the bold line under the image, the event or document title, the text ad's title).
headline_descriptionThe line under the headline, when the ad has one.
body_textThe 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_previewThe copy as the list shows it — cut after about three lines, ending in "…" when cut.
body_text_truncatedWhether body_text_preview was cut by LinkedIn.
ctaThe call-to-action button, as the ad words it ("Register", "Demo erhalten").
cta_buttonsMessage ads: every button in the message ("Yes, I'm interested", "Maybe later").
cta_typeThe CTA as one value across languages: learn_more, register, sign_up, download, apply, request_demo, view_event, … other.
destination_urlWhere the ad sends the click, with the advertiser's UTM and tracking parameters kept (LinkedIn's own trk tag removed).
landing_domainThe destination's domain.
links_in_textLinks written into the copy (lnkd.in, hashtags, mentions).
image_urlThe creative's image; the first card's for a carousel, the cover for an article or Employer Brand card.
image_urlsEvery image of the creative.
video_urlThe video file, highest quality.
video_urlsEvery rendition of the video: url, bitrate, type, best first.
video_preview_urlThe video's poster frame.
document_titleDocument ads: the document's title.
document_urlDocument ads: the document's page manifest on LinkedIn's CDN.
document_cover_urlDocument ads: the cover page image.
document_pagesDocument ads: how many pages the document has.
cardsCarousel ads: every card — position, title, image_url, destination_url (when the card has its own link).
event_nameEvent ads: the event.
event_timeEvent ads: when it happens, as LinkedIn states it.
event_locationEvent ads: where ("Online", a city).
message_sender_nameMessage ads: the person the message comes from.
message_sender_image_urlMessage ads: the sender's photo.
employer_brand_lineEmployer Brand cards: the company line under the name (size · location).
variants_countHow many versions of the ad the page shows (LinkedIn allows several; one is the norm).
variantsThe other versions, when there are several, with the same fields as the row.
run_dates_textThe run dates as LinkedIn writes them ("Ran from Sep 23, 2026 to Sep 27, 2026").
first_shownThe ad's first day. EU ads only.
last_shownThe ad's last day so far. EU ads only.
days_shownDays from first to last, both counted.
is_activeWhether the ad's last day is today or yesterday — still running. Null without dates.
launched_last_7_daysWhether the ad started in the last 7 days.
launched_last_30_daysWhether the ad started in the last 30 days.
long_runningWhether the ad has run 30 days or more.
has_eu_transparencyWhether the page carries LinkedIn's EU transparency block (dates, impressions, targeting) — true for ads shown in the EU.
impressions_bucketTotal impressions as LinkedIn states the range ("5k-10k", "< 1k").
impressions_minLower end of that range, as a number.
impressions_maxUpper end of that range, as a number. Null for an open range ("1M+").
impressions_by_countryEvery 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_countryThe country with the largest share of impressions.
countries_countHow many countries the ad was shown in.
regionsISO-2 codes of the countries the ad was shown in (EU ads), the shape our Google and Meta actors use.
targeting_languageLanguages the advertiser targeted.
targeting_language_excludedLanguages the advertiser excluded.
targeting_locationsLocations targeted, the ones behind "and N others" included ("Dallas, TX" stays one value).
targeting_locations_excludedLocations excluded, all of them.
targeting_parametersThe targeting matrix: for audience, demographic, company, education, job, interests_and_traits, whether the advertiser targeted and whether it excluded by it.
targeting_otherAny other targeting line the page shows: category, kind (includes / excludes), values.
copy_lengthCharacters in the copy.
text_languageThe copy's language (ISO code), from its common words; null when too short to tell.
sentiment_scoreFree sentiment of English copy, -1..1 (AFINN word list); null for other languages and when no word is scored.
analysis_angletagAds: the persuasion angle — problem_solution, social_proof, scarcity, discount, feature, lifestyle, curiosity, education, comparison, brand, other.
analysis_cta_intenttagAds: what the ad asks the reader to do — purchase, signup, download, learn_more, contact, visit, watch, apply, book, other.
analysis_tonetagAds: the tone of the copy.
analysis_sentimenttagAds: emotional valence, -1..1.
analysis_offer_typetagAds: 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_stagetagAds: awareness, consideration or conversion.
analysis_target_functiontagAds: the job function the ad speaks to — marketing, sales, customer_success, it_security, hr_recruiting, finance, operations_logistics, executives_founders, engineering, general.
analysis_confidencetagAds: the confidence (0..1) of each tag, by tag name. Drop the unsure ones in your own pipeline.
analysis_hookanalyzeAds: the line meant to stop the scroll.
analysis_offeranalyzeAds: the concrete offer, or null when the ad makes none.
analysis_audienceanalyzeAds: who the ad is written for, in a few words.
analysis_strategyanalyzeAds: what the advertiser is trying to achieve with the ad, in one sentence.
ad_ocr_textocrImageAds: the words in an image ad's artwork (image ads only; a video's poster frame is not read).
transcripttranscribeVideos: what the video says.
transcript_languagetranscribeVideos: the language spoken.
hook_3stranscribeVideos: the first three seconds of speech.
speech_secondstranscribeVideos: seconds of speech in the video.
video_duration_stranscribeVideos: the video's length in seconds.
transcript_segmentstranscribeVideos: the transcript in timed segments — start, end (seconds), text.
advertiser_industryincludeCompanyInfo: the company's industry on LinkedIn.
advertiser_sizeincludeCompanyInfo: company size as LinkedIn states it ("5,001-10,000 employees").
advertiser_employees_minincludeCompanyInfo: lower end of the size range.
advertiser_employees_maxincludeCompanyInfo: upper end of the size range.
advertiser_employees_on_linkedinincludeCompanyInfo: how many members list the company as their employer on LinkedIn.
advertiser_taglineincludeCompanyInfo: the company's tagline on its LinkedIn page.
advertiser_similar_pagesincludeCompanyInfo: the companies LinkedIn shows as similar — name, slug, industry, location.
advertiser_headquartersincludeCompanyInfo: headquarters.
advertiser_foundedincludeCompanyInfo: year founded.
advertiser_company_typeincludeCompanyInfo: public, private, non-profit…
advertiser_websiteincludeCompanyInfo: the company's website.
advertiser_followersincludeCompanyInfo: LinkedIn followers.
advertiser_specialtiesincludeCompanyInfo: the specialties the company lists.
detail_statusok 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_queryThe search that found the ad, as you gave it.
matched_queriesThe 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_countLinkedIn's own total for the search ("N ads match") — check completeness against it.
first_seen_atMonitoring (onlyNewAds / includeEndedAds): the day a run of yours first saw the ad; null without monitoring.
last_seen_atMonitoring: the last day a run of yours saw it.
ended_atended 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_atWhen the row was read (UTC).
run_tagYour runTag, copied onto every row.
has_adscount rows: whether the search found any ad.
search_querycount rows: the Ad Library query that was counted.
advertiser_descriptionadvertiser rows: the company's About text.
summary_ad_countSummary rows: ads delivered for the advertiser or landing page.
summary_active_countSummary rows: of those, still running.
summary_longest_daysSummary rows: the longest run, in days.
summary_formatsSummary rows: ads per format.
summary_landing_domainsSummary rows: every landing domain.
summary_countriesSummary rows: countries by number of ads shown there.
summary_distinct_copiesSummary rows: distinct copies among the ads.
summary_ad_idsSummary rows: the ads counted.
display_urllanding_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,000FreeStarterScaleBusiness
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, tick onlyNewAds, save it as a task and schedule it. The first run delivers the current set; every later run only what appeared since, and is_active / last_shown tell 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: 30 keeps the ads an advertiser has paid to run for a month or more — the ones that work. Add tagAds to 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, or countries alone in searches for every ad shown there, plus includeCompanyInfo. 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

fieldtypedefaultwhat it does
companiesarray[]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).
keywordsarray[]Words in the ad. One search per line, across every advertiser.
payersarray[]The entity LinkedIn shows as "Paid for by" — often the legal name, e.g. HubSpot, Inc..
startUrlsarray[]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).
adIdsarray[]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.
searchesarray[]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}].
resultTypeads / 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.
countriesarray[]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.
dateRangeany / 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.
startDatestringYYYY-MM-DD. With an end date or alone.
endDatestringYYYY-MM-DD.
impressionsMinintegerLinkedIn'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).
impressionsMaxintegerUpper bound for the impressions filter; EU ads only.
targetingIncludesarray[]Only ads whose advertiser targeted by these categories (EU ads). LinkedIn ignores the country filter when this is set.
targetingExcludesarray[]Only ads whose advertiser excluded audiences by these categories (EU ads).
sortOrdernewest / oldest"newest"The order LinkedIn lists the ads in.
includeRelatedAdvertisersbooleanfalseFor 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.
adFormatsarray[]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.
minDaysRunninginteger0Only 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.
onlyActivebooleanfalseOnly ads whose last day is today or yesterday (EU ads carry dates).
includeDetailsbooleantrueOn: 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.
includeCompanyInfobooleanfalseIndustry, 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.
tagAdsbooleanfalseTyped tags per ad from a classification model: angle, CTA intent, tone, offer type, funnel stage, target job function and sentiment, each with a confidence.
analyzeAdsbooleanfalseA 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.
ocrImageAdsbooleanfalseThe words baked into the artwork, read by a vision model (ad_ocr_text). Model usage included.
transcribeVideosbooleanfalseWhat the video says, as text, with its language and first three seconds. A silent video is checked and not billed.
openaiApiKeystringYour own key for analyzeAds, ocrImageAds and transcribeVideos, if you want the model usage on your account. Not needed: the Actor has its own.
summaryRowsbooleanfalseFree 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.
outputFormatfull / compact"full"compact keeps the columns most people use and drops the nested ones.
maxAdsinteger0Ads delivered in the whole run, exactly (0 = no limit). Never exceeded, and you are never billed for more.
maxAdsPerSearchinteger0Ads per company, keyword, payer or URL (0 = no limit).
onlyNewAdsbooleanfalseSkip 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.
includeEndedAdsbooleanfalseAdd an ended row for every ad an earlier run saw that a complete scan of the same search no longer lists. Free.
stateStoreNamestringName for the memory onlyNewAds and includeEndedAds use. Empty: named after your searches, so the same input on a schedule finds its own memory.
runTagstringYour label, copied onto every row (run_tag), to tell runs apart in one sheet.
resumeFromRunIdstringThe 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 ApifyClient
client = 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

apify@hyperbach.com

This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.