TikTok Ads Library Scraper: EU Ads, Targeting and Reach avatar

TikTok Ads Library Scraper: EU Ads, Targeting and Reach

Pricing

from $1.09 / 1,000 ads

Go to Apify Store
TikTok Ads Library Scraper: EU Ads, Targeting and Reach

TikTok Ads Library Scraper: EU Ads, Targeting and Reach

Scrape TikTok's EU Ad Library (DSA) by keyword, advertiser name or id: advertiser, paid for by, first and last shown, unique users by country with age and gender split, targeting, ad text, landing page, video and image links. No login.

Pricing

from $1.09 / 1,000 ads

Rating

0.0

(0)

Developer

The Mine Works

The Mine Works

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a day ago

Last modified

Share

120 TikTok EU ads with targeting in 166 s

From The Mine Works, makers of Threads Scraper and B2B Leads Finder, with over 140,000 runs across 170+ public actors.

Why choose this actor?

  • The full disclosure record of every ad, not just the thumbnail. Each row carries what TikTok publishes under the EU Digital Services Act: advertiser, who paid for the ad, first and last day shown, unique users reached (the range, and by country with the age and gender split) and the targeting the advertiser chose. Our proof run returned 120 ads from 3 searches in 5 countries in 166 seconds, every one with its detail record. For 40 of them someone other than the advertiser paid, mostly agencies, and 11 reached between 16 and 25 countries.
  • Search the way you think about competitors. Keywords and advertiser names, exact phrases in quotes, or an advertiser's complete ad history by its exact name, which the actor looks up in the library for you. In our proof run NIKE Retail B.V. was found by name and the library reported 75,628 matching ads for it in the five countries; the actor read the first 40 with details. You never need an advertiser id, and you can run up to 100 searches of up to 5,000 ads each.
  • You pay only for ads you receive. One charge per ad row saved to your dataset, plus a flat start fee per run. Ads seen twice in a run, ads an earlier run already gave you (when you switch that on), ads whose details TikTok would not serve, advertiser names the library does not know and searches that match nothing are never charged. No TikTok account, no cookies, no proxy add-on.

Run it on Apify

Part of The Mine Works Social media and video family: Threads Scraper, Reddit Scraper, Threads Search Scraper, Instagram Profile Scraper, Instagram Followers & Following, Reddit Search Scraper.

Try it in one minute

Paste this input and press Start. It returns 20 adidas ads shown in Germany, each with its advertiser, paid for by, reach by country and targeting, in about 30 seconds:

{
"searchTerms": ["adidas"],
"countries": ["DE"],
"maxAdsPerSearch": 20
}

You can ask for ads in four ways, and mix them in one run:

  • Search terms: keywords or advertiser names, matched the way the Ad Library's own search box matches them, against advertiser names and ad text (nike, running shoes, zalando).
  • Exact phrases: a term in double quotes matches that phrase only ("black friday", "just do it").
  • Advertisers: every ad of one advertiser, by the exact name the library shows (NIKE Retail B.V., Zalando SE). The actor finds the advertiser with the library's own advertiser lookup. To pin one advertiser account, write name | id from the advertiser_name and advertiser_id of an earlier row, for example adidas AG | 6885261436319171329.
  • Browse: no term at all. Tick browseWithoutSearch to list every ad shown in your countries and dates, sorted by last shown, first shown or reach.

Apify's free plan includes $5 of credit every month, which covers about 2,400 results at this actor's price.

Copy to your AI assistant

themineworks/tiktok-ads-library-scraper on Apify. Returns ads from TikTok's public EU Ad Library (the Digital Services Act repository for ads shown in the EU and EEA, Switzerland, the United Kingdom and Turkey), one row per ad with advertiser name and id, paid for by, first and last shown date, unique users reached (range, and by country with age and gender split), targeting (countries, age groups, genders, interests, audience size, custom audience), objective, call to action, landing page, ad text and video and image links. Call ApifyClient("TOKEN").actor("themineworks/tiktok-ads-library-scraper").call(run_input={"searchTerms": ["adidas"], "countries": ["DE"], "maxAdsPerSearch": 20}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: at least one of searchTerms (keywords or advertiser names; "quoted" for exact phrases), advertisers (exact advertiser names, or "name | id"), or browseWithoutSearch true. Optional: countries (default all covered countries, ISO codes such as DE, FR, GB), dateFrom and dateTo (YYYY-MM-DD, default the last 365 days), maxAdsPerSearch (default 20, 20 to 5000), includeDetails (default true), onlyNewAds (default false), sortBy, adStatus, mediaType, targetGender, targetAges, uniqueUsers. Skip rows that have "_type": "info". Full spec: GET https://api.apify.com/v2/acts/themineworks~tiktok-ads-library-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations?fpr=ymnoit&utm_source=apify-readme&utm_medium=referral

Key features

  • Over 50 fields per ad with details on: ad id and link, advertiser name, account id and country of registration, paid for by, the TikTok account the ad ran from (username, display name, followers, link, account type), ad text, media type, video, cover and image links, industry, objective, call to action, landing page, first and last shown date and days shown, unique users (range, minimum and maximum as numbers), unique users by country with the age and gender split, and the targeting: countries, age groups, genders, interests, video and creator interactions, audience size, custom audience and exclusion, high spending power, cities, provinces, languages, devices and operating systems.
  • 33 countries: every country the library covers, the 27 EU members, Iceland, Liechtenstein, Norway, Switzerland, the United Kingdom and Turkey. Pick some or leave the list empty for all.
  • Up to 5,000 ads per search and 100 searches per run, the most the library lists for one search. Each search line has its own status, match count and stop reason in the run summary.
  • The library's own filters: date range shown, active or inactive ads, video or image ads, targeted gender, targeted age groups and unique users reached (under 10K, 10K to 100K, over 100K), and the sort order for browsing.
  • Advertiser lookup built in: write an advertiser's name and the actor finds the matching advertiser accounts in the library, runs one search per account, and reports names it cannot find with the closest names it saw.
  • Only new ads on repeat runs: switch on onlyNewAds for a schedule and each run returns, and charges, only ads no earlier run in your account delivered. In our test the second run skipped the 20 ads of the first and delivered 20 others.

How to use it

Basic: one brand's ads in one country

{
"searchTerms": ["zalando"],
"countries": ["DE"],
"maxAdsPerSearch": 100
}

You get up to 100 rows, best matches first, each with the detail record. A search term also matches ads from other advertisers that mention it in their text, which is how the library's own search box works. For one advertiser only, use advertisers instead.

Several searches and countries at once

{
"searchTerms": ["zalando", "\"black friday\""],
"advertisers": ["NIKE Retail B.V."],
"countries": ["DE", "FR", "IT", "ES", "NL"],
"maxAdsPerSearch": 40
}

This is our proof run: three searches, 40 ads each, in five countries. In JSON the quotes of an exact phrase are written as \"; in the Console form you type them as normal quotes.

Weekly competitor creative report

{
"advertisers": ["Zalando SE", "NIKE Retail B.V.", "adidas AG"],
"dateFrom": "2026-09-28",
"dateTo": "2026-10-05",
"maxAdsPerSearch": 200,
"onlyNewAds": true
}

Every ad your competitors showed in the EU in the week, with the creative, the landing page, the objective and who it was aimed at. Schedule it weekly in Apify Console (Schedules, Add schedule) and move the dates along, or leave the dates out and let onlyNewAds keep each run to ads you have not seen. A name that matches two advertiser accounts (the library knows both Adidas AG and adidas AG) runs one search for each.

Who reaches the most people in a country

{
"browseWithoutSearch": true,
"countries": ["DE"],
"sortBy": "most_users",
"maxAdsPerSearch": 500,
"includeDetails": false
}

The ads with the most unique users in Germany over the last year, whoever ran them. With includeDetails off the actor reads the result list only, which is several times faster; turn it on when you need paid for by, reach by country and targeting. In our test the 200 widest reaching German ads came back in 75 seconds, led by Samsung, Subway, L'Oréal and Rossmann, each in the 1M to 10M band.

Targeting research for one audience

{
"searchTerms": ["skincare", "protein"],
"countries": ["FR", "DE"],
"mediaType": "video",
"targetAges": ["18-24"],
"targetGender": "female",
"adStatus": "active",
"maxAdsPerSearch": 100
}

Active video ads aimed at women aged 18 to 24, with the interests, audience sizes and custom audience flags their advertisers disclosed. Useful for agencies planning a launch and for researchers who study how ads are targeted.

Political and transparency research

Ads in the library carry who paid for them (paid_for_by), which often differs from the advertiser (an agency, a parent company or a reseller), where the advertiser is registered, whether the ad was removed and why. Browse a country and date window with details on, then group by paid_for_by or advertiser_registered_in. TikTok's ad policies do not allow political ads, so you will mostly find brands, shops and services.

Input parameters

ParameterTypeDefaultWhat it does
searchTermsarray of stringsnone (an input with no searches at all runs adidas)One search per line: keywords or advertiser names, matched like the library's search box. A term in double quotes is an exact phrase. Up to 100 searches per run.
advertisersarray of stringsnoneEvery ad of one advertiser per line: its exact name as the library shows it, or name | id from an earlier row.
browseWithoutSearchbooleanfalseWith no search terms and no advertisers, list every ad shown in the chosen countries and dates.
countriesarray of stringsall covered countriesCountry codes: AT, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MT, NL, NO, PL, PT, RO, SE, SI, SK, TR, or all.
dateFromstring (YYYY-MM-DD)365 days before dateToAds shown on or after this day. The library search does not accept days before 2023-08-01.
dateTostring (YYYY-MM-DD)todayAds shown on or before this day.
maxAdsPerSearchinteger20Ads to collect for each search line, 20 to 5,000.
includeDetailsbooleantrueRead each ad's detail record: advertiser id and country, paid for by, objective, landing page, call to action, reach by country and targeting. Off returns the list fields only, about three times faster.
onlyNewAdsbooleanfalseSkip ads an earlier run of this actor already delivered to you.
sortBystringlast_shown_newestOrder when browsing: last_shown_newest, last_shown_oldest, first_shown_newest, first_shown_oldest, most_users, fewest_users. With a search term TikTok ranks by match.
adStatusstringallall, active or inactive.
mediaTypestringallall, video or image.
targetGenderstringallall, female or male: only ads whose targeting includes it.
targetAgesarray of stringsall agesAny of 13-17, 18-24, 25-34, 35-44, 45-54, 55+.
uniqueUsersarray of stringsany reachAny of under_10k, 10k_100k, over_100k.

What data do you get?

One row per ad. Fields marked (details) need includeDetails, which is on by default.

The ad: ad_id, ad_url (its page in the library), ad_text, media_type (video or image), industry, video_urls, video_cover_urls, image_urls, first_shown_date, last_shown_date, days_shown, audit_status, removed, removal_reasons, objective (details), call_to_action (details), landing_page_url (details).

The advertiser: advertiser_name, and with details advertiser_id, advertiser_registered_in, paid_for_by, and the TikTok account the ad ran from when the library names one: tiktok_username, tiktok_display_name, tiktok_followers, tiktok_profile_url, tiktok_account_type.

Reach: unique_users_seen (the range the library shows, such as 1M-10M), unique_users_min and unique_users_max as numbers, and with details unique_users_total, countries_reached and unique_users_by_country: per country the unique users and the split by age group and gender. The library writes a dash where it hides a small number.

Targeting (details): target_countries, target_age_groups, target_genders, target_audience_size, target_interests, target_video_interactions, target_creator_interactions, custom_audience, audience_exclusion, high_spending_power, target_cities, target_provinces, target_languages, target_devices, target_operating_systems. Interests and interactions appear only when the advertiser used them: 17 of the 120 ads in our proof run named interests, such as Online Shopping and Sports & Fitness.

The run: has_details, position (rank in the search results), search (the search line, or for an advertiser its name and id), countries_filter, scraped_at.

Stable fields for automations

These fields were present in every row of our test runs, with details on and off:

FieldMeaning
ad_idThe library's ad id; use it to dedupe
ad_urlLink to the ad's page in the library
media_typevideo or image
first_shown_dateFirst day shown, YYYY-MM-DD
last_shown_dateLast day shown, YYYY-MM-DD
days_shownDays from first to last shown, both counted
unique_users_seenUnique users reached, as the range the library shows
unique_users_minLower end of that range as a number
audit_status1 shown normally, 2 shown as removed
removedtrue when the library shows the ad as removed
has_detailstrue when the detail record was read
positionRank in the search results
searchThe search line the ad came from
countries_filterCountries the search covered
scraped_atWhen the row was read

These names will not change. New fields may be added; existing ones keep their name and meaning.

Output examples

Real rows from our test runs on 6 October 2026, trimmed: long media links are cut, and lists of countries and age and gender splits are shortened.

A brand ad with details and interest targeting (search zalando):

{
"ad_id": "1850682199250961",
"ad_url": "https://library.tiktok.com/ads/detail/?ad_id=1850682199250961",
"advertiser_name": "Zalando SE",
"ad_text": "Zalando",
"media_type": "video",
"first_shown_date": "2025-12-09",
"last_shown_date": "2025-12-31",
"days_shown": 23,
"unique_users_seen": "1M-10M",
"unique_users_min": 1000000,
"unique_users_max": 10000000,
"industry": "Apparel & Accessories",
"video_urls": ["https://library.tiktok.com/api/v1/cdn/1791234952/video/aHR0cHM6Ly92MTZ..."],
"audit_status": "1",
"removed": false,
"has_details": true,
"advertiser_id": "6876456332912755458",
"advertiser_registered_in": "Germany",
"paid_for_by": "Zalando SE",
"tiktok_username": "zalando",
"tiktok_display_name": "Zalando",
"tiktok_followers": "2.2M",
"tiktok_account_type": "BLUEV_BA",
"landing_page_url": "https://www.zalando.es/live/show/01kbq22xg50262vk9e3sv27n5g/?wmc=smp330__.52522860___..&opc=2211",
"call_to_action": "Watch now",
"objective": "Traffic",
"unique_users_total": "1M-10M",
"countries_reached": 1,
"unique_users_by_country": [
{ "country": "ES", "unique_users": "1.8M", "unique_users_approx": 1800000, "by_age_gender": [ { "age": "25-34", "gender": "female", "unique_users": "-" } ] }
],
"target_countries": ["ES"],
"target_age_groups": ["25-34", "35-44", "45-54"],
"target_genders": ["female", "male", "unknown"],
"target_audience_size": "6.3M-7.6M",
"target_interests": ["Online Shopping"],
"target_creator_interactions": ["Fashion & Beauty"],
"custom_audience": false,
"audience_exclusion": false,
"high_spending_power": false,
"target_operating_systems": ["ALL"],
"search": "zalando",
"countries_filter": "DE,FR,IT,ES,NL",
"position": 6
}

An ad paid for by an agency, shown in 16 countries (exact phrase "black friday"):

{
"ad_id": "1878076455406610",
"advertiser_name": "南京同诺仓储设备制造有限公司",
"advertiser_id": "7454123072484950032",
"advertiser_registered_in": "China",
"paid_for_by": "BLUEVISION INTERACTIVE LIMITED",
"ad_text": "BLACK FRIDAY 50% OFF FOR A LIMITED TIME",
"media_type": "video",
"first_shown_date": "2026-10-04",
"last_shown_date": "2026-10-04",
"unique_users_seen": "0-1K",
"objective": "Sales",
"landing_page_url": "https://newblood66.com/products/eye-2-eye-polo?utm_source=tiktok&utm_c...",
"countries_reached": 16,
"unique_users_by_country": [
{ "country": "ES", "unique_users": "0-1K", "by_age_gender": [ { "age": "18-24", "gender": "male", "unique_users": "0-1K" } ] },
{ "country": "FR", "unique_users": "0-1K", "by_age_gender": [ { "age": "18-24", "gender": "male", "unique_users": "0-1K" } ] }
],
"target_countries": ["ES", "FR", "GB", "NO", "NL", "PT", "CH", "BE", "DE", "FI", "IE", "PL", "DK", "IT", "SE", "AT"],
"target_age_groups": ["18-24", "25-34", "35-44", "45-54", "55+"],
"target_audience_size": "151.1M-184.6M",
"custom_audience": false,
"search": "\"black friday\""
}

A list-only row (browseWithoutSearch, Germany, most_users, details off):

{
"ad_id": "1859234897655858",
"ad_url": "https://library.tiktok.com/ads/detail/?ad_id=1859234897655858",
"advertiser_name": "Shopify (USA) Inc.",
"ad_text": "Wachse mit Shopify",
"media_type": "video",
"first_shown_date": "2026-03-17",
"last_shown_date": "2026-06-08",
"days_shown": 84,
"unique_users_seen": "1M-10M",
"unique_users_min": 1000000,
"unique_users_max": 10000000,
"video_urls": ["https://library.tiktok.com/api/v1/cdn/1791235147/video/aHR0cHM6Ly92MTZ..."],
"audit_status": "1",
"removed": false,
"has_details": false,
"search": "all ads",
"countries_filter": "DE",
"position": 1
}

A removed ad (same run): the library hides the media and the advertiser, and says why.

{
"ad_id": "1835161482072097",
"ad_text": "Conoce una profesión de alta demanda. Fórmate en 6 meses y mejora tu carrera. Clase gratis.",
"media_type": "video",
"first_shown_date": "2025-06-17",
"last_shown_date": "2025-11-25",
"days_shown": 162,
"unique_users_seen": "1M-10M",
"video_urls": [],
"audit_status": "2",
"removed": true,
"removal_reasons": ["Our review shows that your advertising content may violate TikTok's advertising policies by promoting misleading employment or money-making opportunities. ..."],
"has_details": false,
"search": "all ads",
"countries_filter": "DE",
"position": 6
}

Pricing

Pay per event: you pay for each ad delivered to your dataset, plus a flat $0.005 per run, whatever memory you choose. The price is the same with details on or off. Nothing else is billed: no proxy add-on, no charge per search or per page.

EventFree planBronze (Starter)Silver (Scale)Gold (Business) and above
Ad delivered, per 1,000 ads$1.99$1.69$1.39$1.09
Run start, once per run$0.005$0.005$0.005$0.005

Never charged: the same ad found by two searches in one run, ads an earlier run already delivered when onlyNewAds is on, ads whose details TikTok would not serve after six tries when includeDetails is on (they are left out of the dataset and listed in the run summary), advertiser names the library does not know, searches that match nothing, refused requests, and the information row at the end of a run. A run that delivers nothing costs only the start fee.

To cap a run's cost, set Maximum cost per run in the run options; the actor stops delivering, and charging, when that budget is used.

FAQ

What is TikTok's Ad Library?

A public website, library.tiktok.com/ads, where TikTok lists the ads it showed in the European Union and the EEA, Switzerland, the United Kingdom and Turkey, as the EU Digital Services Act requires of very large platforms. For each ad it publishes the advertiser, who paid, when it ran, how many unique users saw it and how it was targeted. This actor reads exactly what that site shows any visitor.

Which countries are covered?

The 33 the library covers: Austria, Belgium, Bulgaria, Croatia, Cyprus, the Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Iceland, Ireland, Italy, Latvia, Liechtenstein, Lithuania, Luxembourg, Malta, the Netherlands, Norway, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden, Switzerland, Turkey and the United Kingdom. Ads shown only outside these countries, in the United States for example, are not in the library.

How many ads can I get?

Up to 5,000 per search, which is the most the library lists for one search, and up to 100 searches per run. For a bigger set, split it: one search per country, or narrower date windows.

How far back does it go?

The library lists ads shown in about the last year, and its search does not accept a start date before 1 August 2023. An ad that started earlier but was still shown inside your window is included: in our tests we found ads first shown in October 2022 that were still running in July 2026.

How fresh is the data?

Each run reads the library live, so you get what it shows at that moment. In our runs on 5 and 6 October 2026 the newest ads had last been shown on 4 and 5 October.

Do I need a TikTok account, cookies or an API key?

No. The actor reads the library as a logged-out visitor. You do not need TikTok's research API either.

Why are runs with details slower, and how slow?

The detail record of each ad is a separate request, and TikTok answers only one or two of them per visitor before asking that visitor to wait several minutes. The actor therefore opens a fresh visitor session for each ad: a headless Chrome page receives the library's visitor token, and the requests themselves go out as plain web requests. Our proof run read 120 ads with details in 166 seconds, about 1.4 seconds per ad. With includeDetails off the actor reads only the result lists, 12 ads a request, and 200 ads took 75 seconds.

What happens with ads whose details TikTok will not serve?

Each is tried on up to six fresh visitor sessions. If none answers, the ad is left out and not charged, and its id is listed in the run summary (details_failed_ad_ids). If five ads in a row fail like this the run stops, so you never pay for a run TikTok is blocking. In our proof run every one of the 120 ads came back with its details.

No, not for long. The video and image links are signed by TikTok and stop working after some hours, so download the media soon after the run if you need it. The ad_url link to the ad's library page does not expire.

Can I monitor competitors for new ads?

Yes. Put their names in advertisers, switch on onlyNewAds and add a schedule (Apify Console, this actor, Schedules, Add schedule). Each run then returns, and charges, only ads you have not received before. In our test a second run of the same search skipped the 20 ads the first had delivered and returned 20 others.

Why did my advertiser name return nothing?

The name must match the library's spelling of the advertiser, which is often the legal entity, such as NIKE Retail B.V. rather than Nike. The run summary lists the closest names the library knows, so copy one of those. Or search the brand as a search term first, then use the advertiser_name and advertiser_id of a row as name | id.

In what formats can I export the data?

JSON, CSV, Excel, XML, RSS or an HTML table from the run's dataset, in Apify Console or through the API. Nested fields such as unique_users_by_country stay nested in JSON and are flattened into columns in CSV and Excel.

Can I use it from Claude, ChatGPT or another AI assistant?

Yes, through Apify's MCP server.

  • Connector URL: https://mcp.apify.com/?tools=themineworks/tiktok-ads-library-scraper
  • Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
  • ChatGPT: turn on developer mode, add an MCP connector with the URL, sign in with Apify.
  • Cursor or VS Code: add it as an HTTP MCP server with that URL.
  • Claude Code: claude mcp add -t http tiktok-ads-library-scraper "https://mcp.apify.com/?tools=themineworks/tiktok-ads-library-scraper"

The library exists so that the public can inspect these ads, and the actor collects only what it shows to anyone, without logging in. You are responsible for how you use the data: check TikTok's terms for your use case and the data protection laws that apply to you, such as GDPR and CCPA. Most advertisers are companies, but some are individual creators, so treat their names with care.

Integrations

  • Google Sheets: send each run's dataset to a sheet with Apify's Google Sheets integration, one row per ad.
  • Make, Zapier and n8n: start a run and read its dataset with the Apify apps and nodes, for example to post a competitor's new ads to Slack every Monday.
  • Webhooks: have Apify call your URL when a run finishes, then fetch the dataset.
  • API: start runs and read results from any language with the Apify API or the Python and JavaScript clients (see "Copy to your AI assistant" above).
  • MCP clients: Claude, ChatGPT, Cursor, VS Code and Claude Code, through the connector URL in the FAQ.

Related actors from us: Facebook Ad Library Scraper for Meta's ads, Google Ads Transparency Scraper for an advertiser's Google ads, and TikTok Creator Scraper for the accounts behind the ads.

More from The Mine Works

Social media and video

Leads and business directories

Marketing, SEO and reviews

LinkedIn

Real estate

Science, health and government data

Jobs and hiring

Company and business data

E-commerce and marketplaces

Food and local services

Developer and AI tools

More tools

Support

Found an ad or a search that does not come back right, or a field you need? Open an issue in the Issues tab and include the run link. For new sources or a custom build, email dmineworks@gmail.com.

Every ad in TikTok's EU Ad Library that matches your keywords, phrases or advertisers, with who paid for it, when it ran, how many people it reached in each country and how it was targeted, read without a login and charged only for ads you receive.