LinkedIn Ad Library Scraper - LinkedIn Ads Library Search avatar

LinkedIn Ad Library Scraper - LinkedIn Ads Library Search

Pricing

from $0.90 / 1,000 fast ad results

Go to Apify Store
LinkedIn Ad Library Scraper - LinkedIn Ads Library Search

LinkedIn Ad Library Scraper - LinkedIn Ads Library Search

Scrape the LinkedIn Ads Library by company, ad-text keyword, or payer name. Get ad copy, headlines, creatives and landing pages in fast mode; add impressions, targeting and transparency fields in full mode. Track competitor B2B campaigns across countries in a single run.

Pricing

from $0.90 / 1,000 fast ad results

Rating

0.0

(0)

Developer

jy-labs

jy-labs

Maintained by Community

Actor stats

0

Bookmarked

26

Total users

21

Monthly active users

4 days ago

Last modified

Share

LinkedIn Ad Library Multi-Search Scraper

This is an independent, unofficial tool. It is not affiliated with, endorsed by, or sponsored by LinkedIn. It only reads information exposed by the public LinkedIn Ad Library and does not accept LinkedIn credentials, cookies, or member data.

Search multiple company names, ad text keywords, and payer names in one run. Results from every search are merged by LinkedIn ad ID, while the matches field preserves exactly which searches found each ad.

Use Fast mode for affordable creative research or Full mode when you need the public transparency fields LinkedIn exposes on individual ad pages.

What it collects

  • Advertiser name, company ID and public company URL
  • Ad format, text, headline, CTA, creatives, and source URL
  • Every matching company, keyword, or payer search with its rank
  • full mode: public payer name, run period, landing URL, impression range, country breakdown, and targeting
  • Restricted ads as explicit rows without inventing hidden values

The Actor does not scrape LinkedIn profiles, emails, contacts, or logged-in content.

Input

Provide at least one value in companyNames, keywords, or payerNames. Across the three lists, you can submit up to 20 unique searches.

{
"companyNames": ["HubSpot", "Salesforce", "Monday.com"],
"keywords": ["CRM", "AI agent"],
"countries": ["US", "GB", "DE"],
"dateOption": "last-30-days",
"detailMode": "fast",
"maxResultsPerSearch": 25,
"maxTotalResults": 100
}

Date filters

Choose last-30-days, current-month, current-year, last-year, or custom-date-range. A custom range requires both dates, must stay within the most recent year, and must end no later than the previous UTC day because LinkedIn only exposes completed days.

{
"keywords": ["cybersecurity"],
"countries": ["FR", "DE"],
"dateOption": "custom-date-range",
"startDate": "2026-07-01",
"endDate": "2026-07-23",
"detailMode": "full"
}

ALL must be used by itself. Otherwise, use up to five ISO two-letter country codes.

Fast and Full modes

fast mode returns fields visible on search cards and is the best choice for creative discovery and competitor monitoring. It is billed per saved result at the Fast price on the Pricing tab.

full mode opens each public ad detail page and is billed per saved result at the Full price, twice the Fast price. LinkedIn only exposes some transparency fields for eligible ads and regions. Missing non-EU transparency data is returned as null and is not considered an error. If a detail page fails, the search-card result is retained with detailStatus: "failed".

Output

Each Dataset row represents one unique ad ID:

{
"adId": "1455310303",
"matches": [
{
"type": "company",
"value": "JetBrains",
"rank": 1,
"countries": ["FR", "DE"],
"searchUrl": "https://www.linkedin.com/ad-library/search?accountOwner=JetBrains"
}
],
"advertiser": {
"name": "JetBrains",
"companyId": "12515",
"companyUrl": "https://www.linkedin.com/company/12515",
"logoUrl": "https://media.licdn.com/..."
},
"payerName": "JetBrains s.r.o.",
"adFormat": "Single Image Ad",
"adText": "Build better software.",
"headline": "Try IntelliJ IDEA",
"ctaLabel": "Learn more",
"landingUrl": "https://www.jetbrains.com/idea/",
"creatives": [
{
"type": "image",
"url": "https://media.licdn.com/...",
"thumbnailUrl": null
}
],
"runPeriod": {
"startDate": "2026-07-22",
"endDate": "2026-07-23"
},
"restricted": false,
"impressions": {
"display": "30k-50k",
"min": 30000,
"max": 50000,
"byCountry": [{ "country": "France", "percentage": 60 }]
},
"targeting": [
{
"category": "Location",
"included": ["France", "Germany"],
"excluded": []
}
],
"detailStatus": "complete",
"retrievalMode": "http",
"sourceUrl": "https://www.linkedin.com/ad-library/detail/1455310303",
"scrapedAt": "2026-07-24T00:00:00.000Z"
}

The default Key-Value Store record SUMMARY contains search-level statuses, raw and deduplicated counts, confirmed empty searches, partial results, browser fallbacks, bounded error messages, final output count, and billing-limit state. Summary data is never mixed into the Dataset.

Empty results and blocking

An HTTP page is considered empty only when LinkedIn shows an explicit empty-result message. A 403, 429, error shell, meaningless 404, or page without both ads and empty-result evidence is treated as blocking or a parse failure.

A search page gets up to six attempts, with a 1–3 second pause before each retry (five when you set the proxy yourself); above a 60-second request timeout it gets four (three when you set the proxy yourself). Detail pages get three. Independent HTTP searches run with a maximum concurrency of five. If a search still fails, only that search is reprocessed in a browser, with at most two browser fallbacks at once. A run succeeds partially when at least one search succeeds. It fails only when every search is blocked or unparsable; an all-empty run succeeds normally.

Proxy

Leave Proxy configuration at its default and the Actor goes direct first. It switches to Apify Proxy only when LinkedIn rate-limits or keeps blocking:

  • Every search starts without a proxy. LinkedIn's occasional 403 is often random per request, so a page is first retried on the same route. A search that keeps getting blocked climbs on its own: two direct attempts, then one through Apify Proxy (datacenter), then up to three through residential proxy (US), each proxy attempt on a new exit IP: six attempts in all. Above a 60-second request timeout the steps are one, one and two: four in all. Residential is used only by a search that needs it; if your account cannot use residential proxy, that step is skipped. A search still blocked after these is named in the run's status message.
  • The first 429 or 999 answer switches the rest of the run to Apify Proxy (datacenter). The search that got it retries through the proxy, and every search that starts later begins on the proxy. If the proxy cannot be set up, the run stays direct.
  • A proxied search keeps its proxy and one proxy session (the same exit IP and cookies) for all its pages. It moves to a new exit IP only after one of its requests is blocked.
  • Detail pages start the same way: direct unless the run has switched to the proxy. A blocked detail page climbs on its own: two attempts on its starting route, then one through Apify Proxy (datacenter), then one through residential proxy (US), each proxy attempt on a new exit IP: four attempts at most. Other failures (a missing page, unusable content) end it after three attempts on its route.
  • A search's browser fallback goes through residential when the search reached it, else the proxy its search got through on; otherwise it follows the run's route. At most five searches per run use residential this way; later ones go through datacenter. A proxied browser fallback skips images, video, fonts and stylesheets. Detail page browser fallbacks follow the run's route.

The run log shows each search's route (Search route: direct, datacenter or residential), every switch, and each search page's size, and each detail page fetched through a proxy with its size. The proxyTiers field of the SUMMARY record counts search page attempts, pages and bytes per route, the same for detail pages under proxyTiers.details, search browser fallbacks and their approximate bytes under proxyTiers.browserFallback, and moves onto each proxy under proxyTiers.climbs.

If you set the proxy yourself (proxy groups such as residential, a country, your own proxy URLs, or turning the proxy off), the Actor uses exactly that setting for every request and never switches routes.

Pricing

ChargePrice
Fast saved resultper result, see Pricing tab
Full saved resultper result, see Pricing tab
Actor start event$0.00005 per charged start unit

The current per-result prices, including the discount for your Apify plan, are on the Actor's Pricing tab. A Full result costs twice a Fast result. Apify automatically scales the synthetic start-event count with allocated memory; at the default 1 GB, a run charges one start unit for a total of $0.00005. The start event also makes the first five seconds of compute eligible for Apify's PPE startup coverage.

The Pricing tab also shows the minimum maximum charge a run accepts. Set a higher maximum charge when requesting more results.

Before Full detail work, the Actor checks how many full-ad-result events still fit within the user's limit. Fast mode checks fast-ad-result instead. Each row is validated, saved, and charged together. When another result cannot be charged, the Actor stops and records chargeLimitReached: true in SUMMARY.

Ads with no extractable content (no advertiser name, or no text, headline, or creative) are delivered free, marked contentStatus: "empty".

In Full mode, an ad whose detail page could not be fetched is delivered with its Fast data, marked detailStatus: "failed", and charged fast-ad-result instead of full-ad-result. SUMMARY.fastChargedDetailFailures counts them.

Result estimate:

Fast = unique saved results × Fast result price
Full = unique saved results × Full result price
Default-memory start = $0.00005

SUMMARY.pricing records the observed Fast, Full, and start prices and the highest price this build accepts for each. Production runs refuse to start when a deployed price is above that ceiling, preventing accidental overbilling.

Run through the API

Run and wait for Dataset output with an Apify API token in the authorization header:

curl --request POST \
"https://api.apify.com/v2/acts/jy-labs~linkedin-ad-library-multi-search-scraper/run-sync-get-dataset-items?format=json&clean=true" \
--header "Authorization: Bearer $APIFY_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"companyNames": ["HubSpot", "Salesforce"],
"countries": ["US", "DE"],
"detailMode": "fast",
"maxResultsPerSearch": 10,
"maxTotalResults": 20
}'

For larger runs, start the Actor asynchronously with /runs, then read the default Dataset and the SUMMARY record using the storage IDs returned by the run.

Common use cases

  • Compare LinkedIn ads from multiple competitors
  • Search B2B categories such as CRM, cybersecurity, or AI agents
  • Find ads by the disclosed payer entity
  • Inspect public EU impression and targeting transparency
  • Compare creative strategies across countries

FAQ and troubleshooting

Why did a successful search return zero rows?

confirmed_no_results means LinkedIn explicitly showed that no ads matched the filters. Broaden the date range, use ALL, or try the advertiser's exact public name. A blocked or ambiguous page is never reported as an empty result.

Why are impressions or targeting null?

LinkedIn exposes these fields only for eligible ads and regions. Use Full mode and include relevant European countries. Missing public transparency data is represented as null; the Actor does not infer it.

What does completed_partial mean?

At least one search succeeded, but another search, pagination page, or detail page was unavailable. Review SUMMARY.searches, detailErrors, and browserFallbackSearches. Successfully collected card rows remain in the Dataset.

Why did output stop before maxTotalResults?

The run's maximum charge may not allow another result. Increase the maximum charge and rerun. SUMMARY.chargeLimitReached distinguishes this from search limits or deduplication.

Does the Actor require a LinkedIn account?

No. It accepts no LinkedIn login, cookie, or member data and reads only the public Ad Library.

Responsible use

You are responsible for using the output in accordance with applicable laws, LinkedIn's current terms, robots policies, and Apify's platform rules. Public web content can change without notice. Before Store publication, the latest relevant policies must be reviewed; if publication is not permitted, keep the Actor private.