LinkedIn Ad Library Keyword & Advertiser Scraper avatar

LinkedIn Ad Library Keyword & Advertiser Scraper

Pricing

from $0.49 / 1,000 results

Go to Apify Store
LinkedIn Ad Library Keyword & Advertiser Scraper

LinkedIn Ad Library Keyword & Advertiser Scraper

Search the public LinkedIn Ad Library by keyword, advertiser, country, or date range, and get headline, body copy, advertiser info, media URLs, and call-to-action for the ads each search returns.

Pricing

from $0.49 / 1,000 results

Rating

0.0

(0)

Developer

Nimbryxo-studio

Nimbryxo-studio

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Security

Limited permissions

Share

Search the public LinkedIn Ad Library without an account, cookies, or a login. Collect paginated ads by keyword, advertiser name, payer, exact company ID, or a pasted Ad Library URL — then enrich each ad with its full copy, CTA, landing URL, video, paying entity, and the EU transparency block (run dates, impression range, country shares, and targeting).

The actor is built for competitor research, creative monitoring, and B2B ad intelligence. It reads the same public pages a logged-out visitor sees, so it works with zero credentials.

Modes

ModeWhat it doesInputs it uses
search (default)Builds one search per keyword / advertiser / payer / company-ID group, paginates it, dedupes by ad ID, and optionally opens every detail page.searchTerms, advertisers, companyIds, companyUrls, payer, filters
adDetailsRe-scrapes specific ads from their IDs or detail URLs.adIds, directUrls (detail URLs)
directUrlsAccepts pasted Ad Library search URLs, company URLs, and ad detail URLs. Search filters are preserved.directUrls
countReturns the total number of matching ads per search, without pagination.The same search inputs

Every keyword, advertiser, payer, and company-ID group is an independent search (a union). Filters such as country, date, sort, impressions, and targeting apply to all of them.

Inputs

InputTypeDefaultDescription
modeSelectsearchsearch, adDetails, directUrls, or count.
searchTermsString list[]Keyword searches.
advertisersString list[]Advertiser names (fuzzy) or LinkedIn company URLs.
companyIdsString list[]Exact numeric LinkedIn company IDs; multiple IDs are OR-ed. URLs are accepted.
companyUrlsString list[]Company page URLs, resolved to their numeric organization ID.
payerString list[]Legal entity that paid for the ad.
advertiserMatchSelectstartsWithClient-side precision for advertiser-name searches: any, startsWith, exact.
countriesString list[]ISO-3166 alpha-2 codes (US, GB, DE) or ALL. Multiple codes are comma-joined.
dateOptionSelectlast-30-daysany-time, last-30-days, current-month, current-year, last-year, custom-date-range.
startDate / endDateString—Required for custom-date-range (YYYY-MM-DD, within the last 12 months).
sortOrderSelectnewestnewest or oldest.
impressionsMinValue / impressionsMaxValueInteger—EU impression range. LinkedIn requires both values.
impressionsMinUnit / impressionsMaxUnitSelectnonenone, thousand, or million.
targetingIncluded / targetingExcludedString list[]EU targeting facets: LANGUAGE, LOCATION, AUDIENCE, DEMOGRAPHIC, COMPANY, EDUCATION, JOB, INTERESTS_AND_TRAITS.
includeDetailsBooleantrueOpen each ad's detail page for full copy, CTA, landing URL, video, payer, and EU data.
decodeShortLinksBooleanfalseResolve lnkd.in and similar short links to the final landing URL.
adIdsString list[]Ad IDs or detail URLs, for adDetails.
directUrlsURL list[]Pasted Ad Library search/detail URLs or company URLs.
maxItemsInteger50Global cap per run (1–4,800).

Prefill

The default prefill is the smallest run with a reliable result: Microsoft's exact company ID, the last 30 days, three ads, and detail enrichment on.

{
"mode": "search",
"companyIds": ["1035"],
"dateOption": "last-30-days",
"includeDetails": true,
"maxItems": 3
}

Example — keyword search, card data only

{
"searchTerms": ["AI", "machine learning"],
"countries": ["US", "DE"],
"dateOption": "last-30-days",
"includeDetails": false,
"maxItems": 100
}

Example — exact advertiser with EU transparency

{
"companyIds": ["1035"],
"countries": ["DE"],
"dateOption": "last-year",
"includeDetails": true,
"maxItems": 200
}

Example — re-scrape specific ads

{
"mode": "adDetails",
"adIds": ["1611810664", "https://www.linkedin.com/ad-library/detail/1658527466"]
}

Example — count only

{
"mode": "count",
"searchTerms": ["AI"],
"countries": ["US"],
"dateOption": "last-30-days"
}

Output

Each ad is one dataset row with recordType: "ad". Count mode emits recordType: "count" rows. Empty values are removed at every depth — there are no null, empty-string, empty-array, or sentinel rows.

Ad fields

FieldDescription
ad_idLinkedIn ad / creative ID.
ad_urlPublic Ad Library detail URL.
recordTypead.
sourceUrlThe search URL or detail URL that produced the row.
scrapedAt / scraped_atISO 8601 UTC scrape timestamp (scraped_at is the legacy alias).
advertiser_name, advertiser_id, advertiser_url, advertiser_logo, advertiser_taglineAdvertiser identity. advertiser_id is a numeric company ID when available, otherwise a member/showcase slug.
paid_for_byPaying legal entity from the detail page.
ad_format, creative_type, format_labelNormalized format (image, video, carousel, document, message, spotlight, job, event, article, follow_company, dynamic, text) plus the raw creative type and LinkedIn's label.
headlineAd headline when present.
body_textCopy preview from the search card (or the full preview when scraping a detail URL directly).
body_text_fullFull detail-page copy (up to roughly 2,700 characters).
cta_textCTA button text (Learn more, Register, ...).
landing_url, landing_url_raw, landing_domain, is_shortlinkCleaned landing URL (only the trk parameter is removed), original URL, hostname, and short-link flag.
mediaList of {type, url, expiresAt} entries (image, poster, video).
media_urls, image_urls, video_urls, video_poster_urlFlat media lists for compatibility and convenience.
start_date, end_date, duration_days, is_activeRun dates and duration from the EU transparency block. is_active is only present when an end date exists.
total_impressions, impressions_min, impressions_maxImpression range label and parsed bounds.
impressions_by_country{country, shareRaw, sharePct, isUpperBound?, isLowerBound?, estimatedMin?, estimatedMax?} rows.
targeting_language, targeting_location_included, targeting_location_excluded, targeting_parametersEU targeting data. Parameters are {category, targeted, excluded} rows.
has_dsa_dataAlways a boolean. false means LinkedIn did not publish the EU transparency block for that ad.
country, top_countryThe single delivery-country filter when one is set; the largest impression-share country from the DSA block.
variants_countNumber of creative variants on the detail page.

Count fields

FieldDescription
recordTypecount.
sourceUrlThe search URL used.
scrapedAt / scraped_atISO timestamp.
query, queryType, queryValueThe search label, e.g. keyword, advertiser, payer, companyIds, filters.
totalCountLinkedIn's reported number of matching ads.

Pagination, dedupe, and limits

  • The Ad Library returns 24 ads per page and exposes a pagination token.
  • The actor follows up to 200 pages (4,800 ads) per search, then stops. This is the practical ceiling the Ad Library accepts.
  • Results are deduplicated by ad_id across pages and searches.
  • maxItems is a global cap across all searches (1–4,800). It trims the final page exactly.
  • Broad searches can match hundreds of thousands of ads. Slice them by country, date window, keyword, or exact company IDs to reach more than 4,800 rows.
  • maxItems limits rows, not requests: with includeDetails: true, one detail request is made per collected ad (up to the cap).

Reliability and errors

  • The actor uses curl_cffi with a Chrome 131 TLS fingerprint and a fresh Apify Proxy AUTO session/IP for every request (sticky sessions fail when they land on a blocked IP). Each request is retried up to five times with backoff.
  • If AUTO stays blocked, the actor tries a headless browser on AUTO, then the Apify UNBLOCKER group for that request. Proxy setup is automatic; there is no proxy input.
  • Partial runs are reported honestly in the status message. If some searches are blocked and others return data, the dataset keeps the good rows and the status says how many queries were blocked.
  • If every request is blocked, or a search that should return data comes back empty, the run fails with a clear message. It never pushes a fake "blocked" row.
  • Detail-page failures (404/410 or a transient block) keep the card record and log the failure.
  • A legitimate 0 results search also fails the run with an explicit "0 results" message rather than silently succeeding with an empty dataset.
  • A run summary (pages, details, query statuses) is saved to the key-value store as run_summary.

FAQ

Do I need a LinkedIn account or cookies? No. The Ad Library is public guest content. The actor makes the same anonymous requests the public site does.

Do I need to configure a proxy? No. The actor selects and rotates its proxy automatically.

Why do some ads lack impressions, dates, or targeting? LinkedIn only publishes that transparency block for ads served in the EU. Non-EU ads have no run dates, impression range, country shares, or targeting data. The has_dsa_data flag tells you which is which. This is a source limitation, not a scraper bug.

Why are media URLs signed? LinkedIn CDN URLs carry an e= expiry parameter. The actor exposes the URL and its expiresAt date in media[].expiresAt. Download or archive media before it expires if you need a permanent copy.

What is the difference between advertisers and companyIds? advertisers is a fuzzy name search and can include partners or resellers. companyIds is exact and is the best way to collect only a specific company's ads.

Why is body_text shorter than body_text_full? The search card shows a truncated preview. body_text_full comes from the detail page and is only present when includeDetails is on (or when the mode is adDetails).

How do I get more than 4,800 ads? Split the request by country, date range, keyword, or company ID and run each slice separately. Deduplicate downstream by ad_id if slices overlap.

Can I see spend, budget, CTR, or conversions? No. LinkedIn does not publish those values in the Ad Library. Impressions are ranges, not exact counts.

Is this affiliated with LinkedIn? No. This is an independent third-party actor that reads LinkedIn's public Ad Library. It is not affiliated with or endorsed by LinkedIn Corporation.

Limitations

  • Only public Ad Library ads are available; Campaign Manager data is not accessible.
  • EU transparency data (dates, impressions, country shares, targeting) is published only for EU-served ads.
  • LinkedIn reports impression ranges rather than exact impressions.
  • Each search is capped at 4,800 ads (200 pages × 24).
  • Media URLs are signed and expire; expiresAt is provided for archival planning.
  • Per-ad delivery country is not published. country reflects a single-country search filter; top_country is the largest DSA share.
  • Carousel/document slide text and non-EU active status are not published by the source.
  • LinkedIn may rate-limit aggressive runs; the actor retries and reports partial results rather than fabricating rows.