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

Find the Highest-Reach TikTok Ads in Any EU Country

Rank the TikTok ads that reached the most people in an EU country over any date range, with per-country reach, using the TikTok Ads Library Scraper.

Try the scraper

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

View the scraper →

Which TikTok ads reached the most people in France last month, whoever ran them? Media planners ask it to size a market, creative teams ask it to see what wide-reach ads look like, and agencies ask it to find advertisers worth pitching. TikTok’s Ad Library can answer: its page lets you browse a country with no keyword and sort by unique users. What it does not do is export. You get a scrolling grid of thumbnails, and each reach figure sits behind a click.

Try it live: TikTok Ads Library Scraper: EU Ads, Targeting and Reach. Pay per result delivered. Failed and empty results are never charged.

The TikTok Ads Library Scraper runs the same browse and sort without a login and hands back the ranked list as rows, with the reach in each country when you want it.

What you get and who it is for

FieldWhat it tells you
unique_users_seenUnique users reached, as the band the library shows (1M-10M)
unique_users_min, unique_users_maxThe same band as two numbers you can sort and filter
unique_users_by_countryWith details on: a rounded count per country, split by age and gender
advertiser_name, paid_for_byWho ran the ad and who paid for it
ad_text, media_type, industryWhat the ad was and which category TikTok filed it under
first_shown_date, last_shown_date, days_shownHow long it ran
ad_urlThe ad’s page in the library, which does not expire

Use it to answer “who buys reach in this market”, to build a swipe file of the ads most people actually saw, or to check whether a category leader is still running at scale. Agencies treating the ranking as a pitch list can take the advertiser names from it and pull contact details off each advertiser’s own site.

The input

{
  "browseWithoutSearch": true,
  "countries": ["FR"],
  "dateFrom": "2026-09-01",
  "dateTo": "2026-09-30",
  "sortBy": "most_users",
  "uniqueUsers": ["over_100k"],
  "includeDetails": true,
  "maxAdsPerSearch": 100
}
  • browseWithoutSearch is only used when searchTerms and advertisers are both empty. It lists every ad shown in the chosen countries and dates.
  • sortBy set to most_users puts the widest-reaching ads first. It only applies when browsing. With a search term, TikTok ranks by match instead, and the difference is real: in our keyword search for adidas, the ad with the biggest German reach came 16th of 20.
  • uniqueUsers is the library’s own reach filter, with the bands under_10k, 10k_100k and over_100k. With most_users it trims the tail. Paired with sortBy set to first_shown_newest, it finds new ads that have already passed 100K people.
  • countries is one filter for the whole search, so two codes mean ads shown in either country. For a ranking per country, run one country at a time.
  • includeDetails adds unique_users_by_country and the advertiser fields, at about 1.4 seconds per ad. Turn it off for a list that comes back several times faster: in the actor’s own test, the 200 widest-reaching German ads took 75 seconds with details off, led by Samsung, Subway, L’Oréal and Rossmann, each in the 1M to 10M band.
  • dateFrom and dateTo set the window the ads were shown in.

What the output looks like

[
  {
    "ad_id": "1871321576463745",
    "ad_url": "https://library.tiktok.com/ads/detail/?ad_id=1871321576463745",
    "advertiser_name": "adidas AG",
    "paid_for_by": "PHD INTERNATIONAL LIMITED",
    "ad_text": "adidas Hyperboost Euphoria",
    "media_type": "video",
    "industry": "Apparel & Accessories",
    "first_shown_date": "2026-07-30",
    "last_shown_date": "2026-08-19",
    "days_shown": 21,
    "unique_users_seen": "1M-10M",
    "unique_users_min": 1000000,
    "unique_users_max": 10000000,
    "unique_users_by_country": [
      { "country": "DE", "unique_users": "2.4M", "unique_users_approx": 2400000 }
    ],
    "search": "adidas",
    "countries_filter": "DE",
    "position": 16
  },
  {
    "ad_id": "1871323061862529",
    "advertiser_name": "adidas AG",
    "unique_users_seen": "1M-10M",
    "unique_users_min": 1000000,
    "unique_users_max": 10000000,
    "unique_users_by_country": [
      { "country": "DE", "unique_users": "1.1M", "unique_users_approx": 1100000 }
    ],
    "position": 13
  }
]

These rows come from our keyword run for adidas in Germany on October 6, 2026, not from a browse run. A browse run returns the same fields, with search set to all ads. Both ads sit in the same 1M-10M band, so the band alone cannot order them. The per-country count can: 2.4M against 1.1M. Four of the 17 adidas AG ads in that run were in the top band, with German counts of 1.1M, 1.3M, 1.6M and 2.4M. Note the position values too. The biggest ad came 16th because a keyword search ranks by match, which is why this job uses browse mode.

Run it in Apify Console

  1. Open https://apify.com/themineworks/tiktok-ads-library-scraper and click Try for free.
  2. Clear the prefilled Search terms (keywords or advertiser names) field and leave Advertisers (exact names) empty.
  3. Tick Browse all ads (no search term).
  4. In Countries, replace the prefilled Germany with the one country you want.
  5. Set Shown from (YYYY-MM-DD) and Shown until (YYYY-MM-DD).
  6. Set Sort by to Most unique users first and Unique users reached to Over 100K, then set Max ads per search.
  7. Click Start, watch the Output tab, then click Export for CSV, JSON or Excel.

Run it from Python

pip install apify-client
import csv
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
COUNTRIES = ["DE", "FR", "ES", "IT"]

rows = []
for country in COUNTRIES:
    run = client.actor("themineworks/tiktok-ads-library-scraper").call(run_input={
        "browseWithoutSearch": True,
        "countries": [country],
        "dateFrom": "2026-09-01",
        "dateTo": "2026-09-30",
        "sortBy": "most_users",
        "uniqueUsers": ["over_100k"],
        "includeDetails": True,
        "maxAdsPerSearch": 100,
    })
    for item in client.dataset(run["defaultDatasetId"]).iterate_items():
        if item.get("_type") == "info":
            continue  # the run summary row, never billed
        if item.get("removed"):
            continue  # removed ads hide the advertiser and media
        here = next((c for c in item.get("unique_users_by_country") or []
                     if c.get("country") == country), {})
        rows.append({
            "country": country,
            "users_in_country": here.get("unique_users_approx"),
            "unique_users_seen": item.get("unique_users_seen"),
            "advertiser_name": item.get("advertiser_name"),
            "paid_for_by": item.get("paid_for_by"),
            "ad_text": (item.get("ad_text") or "")[:80],
            "first_shown_date": item.get("first_shown_date"),
            "last_shown_date": item.get("last_shown_date"),
            "ad_url": item.get("ad_url"),
        })

# biggest per-country count first, then group by country (the sort is stable)
rows.sort(key=lambda r: r["users_in_country"] or 0, reverse=True)
rows.sort(key=lambda r: r["country"])
if not rows:
    raise SystemExit("no ads matched these filters")

with open("tiktok_top_reach_by_country.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
    writer.writeheader()
    writer.writerows(rows)

for country in COUNTRIES:
    print(country)
    for r in [r for r in rows if r["country"] == country][:5]:
        print(f"  {r['users_in_country'] or 0:>10,}  {r['advertiser_name']}")

Each country gets its own run, its own ranking and its own start fee. Sorting on the country’s own count, rather than the total band, matters for ads shown in many countries: an ad can sit in the 1M-10M band overall and still be small in the one country you care about.

Run it every month

Save the input as a task, open Schedules, and create a schedule with a cron expression such as 0 7 1 * * (07:00 on the first of each month). A task keeps fixed dates, so either update dateFrom and dateTo before each run or leave them empty for a rolling 365 days. If you want fixed calendar months without editing the task, run the Python script from your own scheduler and compute last month’s dates there.

For an alert instead of a ranking, set sortBy to first_shown_newest, keep uniqueUsers at over_100k, tick Only new ads (for schedules) and run it weekly with 0 7 * * 1. Each run then returns only big ads it has not sent you before. Send results to a Google Sheet with Apify’s Google Sheets integration, to Slack through Make, Zapier or n8n, or to your own endpoint with a webhook.

What it costs

You pay per ad delivered, the same with details on or off: $1.69 per 1,000 ads on the Bronze plan, $1.39 on Silver, and $1.09 on Gold, Platinum and Diamond, plus a flat $0.005 start fee per run.

Four countries, 100 ads each, once a month is 400 ads: about $0.68 on Bronze plus $0.02 in start fees for the four runs. Ads seen twice in a run and ads whose details TikTok will not serve are never charged, and a run that finds nothing costs only the start fee.

Limits worth knowing

  • Up to 5,000 ads per search. That is the most the library lists for one search. For a deeper list, split by country or use narrower date windows.
  • Reach is a band plus a rounded count. The library never gives an exact number. Per-country counts are rounded (2.4M), and small numbers are hidden.
  • Removed ads can rank high. The library keeps removed ads with their reach but hides the advertiser and the media. In the actor’s own browse of Germany, a removed ad came sixth. The script above skips them; keep them if you study enforcement.
  • 33 countries only. The library covers the EU and EEA, Switzerland, the United Kingdom and Turkey. Ads shown only elsewhere are not in it.
  • Media links expire. Video and cover links stop working after some hours, so save creative soon after the run. Keep ad_url for anything long term.
Related Actor

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

Frequently asked questions

Why does Sort by have no effect on my search? +

Sort by only applies when you browse without a search term. With a keyword or an advertiser name, TikTok ranks the ads by how well they match, the same way the library page does.

How exact is the reach figure? +

The library gives a band, such as 1M-10M, which the actor also returns as unique_users_min and unique_users_max. With details on, each country gets a rounded count such as 2.4M, which is enough to order ads inside one band.

Can I rank several countries in one run? +

The Countries list is one filter for the whole search, so a run with DE and FR returns ads shown in either. For one ranking per country, run each country on its own, as the Python script in this guide does.

How far back can I look? +

About a year. Leave Shown from empty and the run covers the 365 days before the end date. The library search does not accept a start date before August 1, 2023.

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.