The Mine Works
← All posts
tutorial October 8, 2026 · 7 min read Updated October 8, 2026

Monitor New LinkedIn Ads for a Keyword Every Week

Get a weekly list of new LinkedIn ads that mention your keywords, from any advertiser, with the LinkedIn Ad Library Scraper and only-new mode.

Try the scraper

The actor referenced in this article. Pay only for results delivered.

View the scraper →

Competitor lists go stale. The companies you already track are rarely the ones that surprise you; the surprise is the new vendor, agency or adjacent player that starts buying LinkedIn ads on your topic. Searching the Ad Library for a keyword by hand every Monday and trying to remember which ads you saw last week does not scale past one keyword.

Try it live: LinkedIn Ad Library Scraper: Ads, Impressions, Targeting. Pay per result delivered. Failed and empty results are never charged.

The LinkedIn Ad Library Scraper searches LinkedIn’s public Ad Library by keyword without a login. With only-new mode on a weekly schedule, each run returns just the ads you have not seen yet, from any advertiser.

What you get and who it is for

FieldWhy it matters for a weekly watch
search_query, search_typeWhich keyword found the ad, so one run can cover several topics
advertiser_name, advertiser_id, paid_byWho is advertising, and the legal entity that paid
headline, body, ctaThe message and the offer
destination_urlThe landing page, when LinkedIn shows it
first_shown, last_shownLaunch and latest run date, where LinkedIn publishes them
impressions_rangeTotal impressions as a range such as 1k-5k, where published
ad_url, ad_idA link to the ad’s public page, and a stable id

Product marketers use a keyword watch to spot new entrants in their category. Agencies use it to collect fresh creative examples for a client’s topic. Founders use it to see who else is paying to reach the buyers they want, before those companies show up in deals. When a name you do not know turns up, its funding rounds and investors tell you how long it can keep buying.

The input

{
  "keywords": ["AEO", "answer engine optimization"],
  "dateRange": "last-30-days",
  "sortOrder": "newest",
  "maxAdsPerSearch": 100,
  "includeAdDetails": true,
  "onlyNewAds": true
}
  • keywords takes one word or phrase per line, matched against the ad text. Each line is its own search.
  • onlyNewAds skips ads an earlier run of yours already delivered, so a scheduled run returns and charges only new ones.
  • sortOrder stays on newest. It is LinkedIn’s default and what only-new mode expects: a search stops as soon as it reaches ads you already have.
  • dateRange set to last-30-days keeps the first run to ads that ran in the last month, instead of the whole archive.
  • maxAdsPerSearch (20 to 1,000) caps each keyword per run. 100 leaves room for a busy week.
  • includeAdDetails adds the full text, landing page, payer, run dates and impressions. It is charged as one extra event per ad.

What the output looks like

[
  {
    "ad_id": "1632997416",
    "ad_url": "https://www.linkedin.com/ad-library/detail/1632997416",
    "advertiser_name": "HubSpot",
    "advertiser_id": "68529",
    "paid_by": "HubSpot, Inc.",
    "ad_format": "single_image",
    "headline": "The LinkedIn AEO playbook: Research-backed tactics that work",
    "body": "Level up your LinkedIn AEO with research-backed tactics that actually work. Get the free playbook.",
    "cta": "Learn more",
    "has_details": true,
    "search_type": "advertiser",
    "search_query": "HubSpot",
    "position": 12
  },
  {
    "ad_id": "1558385343",
    "advertiser_name": "HubSpot",
    "paid_by": "HubSpot, Inc.",
    "ad_format": "single_image",
    "headline": "Raw notes in. Post-ready drafts out.",
    "cta": "Learn more",
    "destination_url": "https://www.hubspot.com/startups/resources/gtm/founder-led-brand-toolkit?utm_campaign=HSFS...",
    "first_shown": "2026-09-24",
    "last_shown": "2026-10-05",
    "impressions_range": "< 1k",
    "search_type": "advertiser",
    "search_query": "HubSpot",
    "position": 50
  }
]

To be clear about the source: these rows come from our advertiser searches for HubSpot on October 6 and 7, 2026, not from a keyword run. In a keyword run, search_type reads keyword, search_query holds your phrase, and every other field is the same.

They still show what a weekly diff looks like. Comparing our two 50-ad runs 24 hours apart, 6 ads were new in the newest 50: 4 headline variants of one LinkedIn AEO playbook offer (the first row is one of them), a thought leader ad and a video from the HubSpot for Developers page. Those AEO ads are the kind of thing a watch on that keyword exists to catch. 4 of the 6 new ads carried no run dates, because LinkedIn published no transparency block for them. The second row, from the October 6 run, has one: first shown September 24, last shown October 5, under 1,000 impressions.

Run it in Apify Console

  1. Open https://apify.com/themineworks/linkedin-ad-library-scraper and click Try for free (or Start if you already use it).
  2. In Keywords, enter each word or phrase on its own line. Leave Advertisers empty.
  3. Set Date range to Last 30 days, Order to Newest first and Max ads per search to 100.
  4. Leave Include ad details ticked, and tick Only new ads (for schedules).
  5. Click Start and watch the Output tab.
  6. Use the Export button to download the new ads as CSV, JSON or Excel.

Run it from Python

pip install apify-client
import csv
from collections import Counter, defaultdict
from datetime import date, timedelta

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("themineworks/linkedin-ad-library-scraper").call(run_input={
    "keywords": ["AEO", "answer engine optimization"],
    "dateRange": "last-30-days",
    "sortOrder": "newest",
    "maxAdsPerSearch": 100,
    "includeAdDetails": True,
    "onlyNewAds": True,
})

new_ads = []
for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    if ad.get("_type") == "info":
        continue  # the run summary row, never billed
    new_ads.append(ad)

# Who is new on each keyword this week
by_keyword = defaultdict(Counter)
for ad in new_ads:
    by_keyword[ad["search_query"]][ad["advertiser_name"]] += 1
for keyword, advertisers in by_keyword.items():
    print(f"{keyword}: {sum(advertisers.values())} new ads from {len(advertisers)} advertisers")
    for name, n in advertisers.most_common(5):
        print(f"    {n:>3}  {name}")

# New to you is not the same as launched this week: first_shown tells them apart
week_start = (date.today() + timedelta(days=-7)).isoformat()
launched = [a for a in new_ads if (a.get("first_shown") or "") >= week_start]
print(f"{len(launched)} of {len(new_ads)} new ads first ran in the last 7 days")

fields = ["search_query", "advertiser_name", "paid_by", "ad_format", "headline", "body",
          "cta", "destination_url", "first_shown", "last_shown", "impressions_range", "ad_url"]
with open(f"new_linkedin_ads_{date.today()}.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
    writer.writeheader()
    writer.writerows(new_ads)

The actor keeps track of what it already delivered to your account, so the script needs no list of seen ids. Each week’s CSV is just that week’s new ads, and the launch check only counts ads that carry a first_shown date.

Run it every week

Save the input as a task, open Schedules, create a schedule with the cron expression 0 7 * * 1 (Mondays at 7:00), and pick the task. The first run returns up to 100 ads per keyword from the last 30 days. Every run after that returns only ads you have not received, and in our own test of only-new mode a repeat run delivered 0 ads and stopped after one request.

To get the list in front of people, connect Apify’s Google Sheets integration to the task, forward the dataset to Slack or email through the Make, Zapier or n8n apps, or have a webhook call your own script when the run finishes.

What it costs

You pay per ad delivered: $1.29 per 1,000 ads on the Bronze plan, plus $1.29 per 1,000 for ad details when Include ad details is on, so $2.58 per 1,000 ads with details. On Silver it is $0.99 plus $0.99, and on Gold, Platinum and Diamond $0.79 plus $0.79. Each run also has a flat $0.005 start fee. Ads an earlier run delivered and keywords with no results are never charged.

A worked example: the first run can return up to 200 ads for two keywords, about $0.52 on Bronze with details. After that, if 50 new ads turn up each week, four weekly runs deliver 200 ads a month: about $0.52 with details or $0.26 without, plus $0.02 in start fees. A quiet week costs only the $0.005 start fee.

Limits worth knowing

  • Short, generic keywords match a lot of ads. A keyword search for CRM in our tests reported 75,308 matching ads, and one search returns at most 1,000, so prefer specific phrases.
  • New to you is not the same as newly launched. The first weeks of a watch include older ads that are still running.
  • Run dates, impressions and targeting appear only where LinkedIn publishes them, mainly for ads served in the European Union.
  • With details off, text is cut at about 120 characters and there is no landing page, payer or run date.
  • LinkedIn’s date filter covers the last 365 days.
Related Actor

Explore the scraper referenced in this article: inputs, outputs, and pricing, then run it on Apify.

Frequently asked questions

What does a keyword search match? +

The ad text. Each keyword line is its own search, and every row records the keyword that found it in search_query, so one run can watch several topics.

Is a new ad the same as a newly launched ad? +

Not always. Only-new mode returns ads your account has not received before. An ad that started months ago can show up the first week your keyword finds it, so check first_shown for the launch date where LinkedIn publishes it.

Should I keep ad details on for a weekly watch? +

Keep them on if you want the full text, landing page, payer and run dates, at $2.58 per 1,000 ads on Bronze. Turn them off for a list at half the price, with text cut at about 120 characters.

Can I limit the watch to certain countries? +

Yes. The countries field takes two letter codes and applies to every keyword search in the run. EU codes also bring impressions and targeting onto more rows.

Apify Store

Find a ready-made scraper for your job

Apify has over 80,000 scrapers and automations, ours included. Start free with $5 of platform credit every month.