TikTok Ads Library Scraper — EU Library & Creative Center avatar

TikTok Ads Library Scraper — EU Library & Creative Center

Pricing

from $15.00 / 1,000 results

Go to Apify Store
TikTok Ads Library Scraper — EU Library & Creative Center

TikTok Ads Library Scraper — EU Library & Creative Center

Scrape TikTok Ads Library (EU/EEA/UK) and Creative Center (global). Extract ad creatives, targeting data, reach estimates, CTR, video URLs, and industry insights. Dual-source coverage — no login required. Residential proxies built-in.

Pricing

from $15.00 / 1,000 results

Rating

0.0

(0)

Developer

Yuliia Kulakova

Yuliia Kulakova

Maintained by Community

Actor stats

1

Bookmarked

411

Total users

83

Monthly active users

3 days ago

Last modified

Share

TikTok Ads Library Scraper

Spy · Analyze · Outperform
The only TikTok ad scraper that covers both the EU Ads Library and the global Creative Center —
targeting data, reach estimates, CTR, video URLs, and industry insights. All in one run.

Why this one? · Data sources · Input · Output · Use cases · Pricing · What's new · Limitations


TikTok Ads Library Scraper pulls ad data from two complementary TikTok sources:

  • TikTok Ads Library — TikTok's official DSA transparency database for EU/EEA/UK. No login required. Returns targeting details, audience reach, and ad creatives for all ads shown in Europe.
  • TikTok Creative Center — TikTok's global top-performing ads showcase. Covers US, APAC, LATAM, and every other market. Returns CTR, engagement metrics, video URLs, and industry data.

Both sources are public and require no TikTok account.


🙏 Does this Actor save you time?

It is built and maintained by one developer. A rating on the Store page takes ten seconds and is the only signal new users have — it genuinely decides whether this Actor gets found at all.

Something missing, unclear, or not working the way you need? Please open an Issue. I read every one, reply within a day, and ship changes fast. Shipped just this week: deep pagination for large searches, full targeting breakdowns, ad copy and landing pages for EU Library ads, and precise Video / Image / Text filtering.

Missing a field or a country? Ask — most requests are a small change.


✨ What makes this different

FeatureThis actorMost others
Covers both Ads Library + Creative Center✅ dual-source❌ one source only
Global coverage via Creative Center (US, APAC, LATAM…)❌ EU-only
EU DSA reach estimates (uniqueUsersSeen, usersTargetedEstimate)
CTR and engagement metrics (Creative Center)
Video CDN URLs + thumbnailPartial
Industry + campaign objective (Creative Center)
Landing page URL + CTA button for EU Library ads
Impressions by country × age × gender✅ opt-in
Rejected ads flagged with TikTok's stated reason
Graceful handling of rate limits (429/403 logging)Silent failures
Warns when 3,600-result cap is reachedNo warning
Zero-result detection — no wasted compute
Residential proxies built-in (required for TikTok)

📡 Data sources explained

Source 1 — TikTok Ads Library (library)

PropertyDetail
URLhttps://library.tiktok.com/
Login required❌ No
CoverageEU-27 + EEA (IS, LI, NO) + Switzerland + UK
Why EU only?Mandated by EU Digital Services Act (DSA), Article 39
Result cap3,600 ads per query (TikTok platform limit — 300 pages × 12 ads)
Unique fieldstargetAgeGroups, targetGender, targetInterests, targetBehaviors, uniqueUsersSeen, uniqueUsersSeenByCountry, adPaidForBy, rejectedInCountries

Use this source when: you want DSA transparency data — who targeted whom, with what message, reaching how many people in Europe.


Source 2 — TikTok Creative Center (creative_center)

PropertyDetail
URLhttps://ads.tiktok.com/business/creativecenter/
Login required❌ No
CoverageGlobal — US, GB, AU, BR, JP, KR, IN, and 50+ more
Data typeTop-performing ads (sorted by CTR and engagement)
Unique fieldsctr, likes, industry, industryCode, campaignObjective, videoMetrics

Use this source when: you want global competitive intelligence — what's performing best in your category, market, or country right now.

TikTok serves a curated subset of Top Ads to logged-out visitors, so a Creative Center run may return fewer ads than maxResults. The Actor states this in the run log rather than leaving you guessing.


Source 3 — Both (both)

Runs both sources in a single actor run. Results are deduplicated automatically. Each result includes a source field so you always know where the data came from.


⚙️ Input

FieldTypeDefaultDescription
sourcestring"library"library · creative_center · both
searchTermsstring[]["Nike"]Keywords or brand names (library source only)
countriesstring[]["DE"]ISO 2-letter codes, case-insensitive. Library: EU/EEA/UK only — others are skipped with a warning. Creative Center: any country.
adTypestring"ALL"ALL · VIDEO · IMAGE · TEXT — applied by TikTok server-side
dateFromstringShow ads first seen on/after this date (YYYY-MM-DD). Library only.
dateTostringShow ads first seen on/before this date (YYYY-MM-DD). Library only.
maxResultsinteger10Max ads per search term + country pair. Hard cap: 3,600 (library).
resolveAdDetailsbooleanfalseLibrary only. Opens each ad's detail page to unlock: adPaidForBy, advertiserBusinessId, advertiserProfile, advertiserCountry, landingPageUrl, ctaType, campaignObjective, targetAgeGroups, targetGender, targetInterests, targetCountries, usersTargetedEstimate, rejectionReasons. Adds ~7 sec per ad.
includeAudienceBreakdownbooleanfalseLibrary only, needs resolveAdDetails. Adds audienceBreakdown — impressions split by country × age × gender. Rich in JSON; keep it off for CSV exports, where one ad can expand into hundreds of columns.

Note on countries: For source: "library", only European countries work (see supported list). For source: "creative_center", any country code works including US, GB, AU, BR, JP.


Example inputs

Quick test — Nike EU ads (library)

{
"source": "library",
"searchTerms": ["Nike"],
"countries": ["DE"],
"adType": "ALL",
"maxResults": 25
}

Multi-country competitor research — 3 brands × 3 EU markets

{
"source": "library",
"searchTerms": ["Adidas", "Nike", "Puma"],
"countries": ["DE", "FR", "NL"],
"adType": "ALL",
"maxResults": 100
}

Global top video ads — US market (Creative Center)

{
"source": "creative_center",
"countries": ["US"],
"adType": "VIDEO",
"maxResults": 50
}

Combined — EU library + global Creative Center

{
"source": "both",
"searchTerms": ["Samsung"],
"countries": ["DE", "US"],
"adType": "ALL",
"maxResults": 50
}

Date range — campaign window analysis

{
"source": "library",
"searchTerms": ["Zalando"],
"countries": ["DE"],
"dateFrom": "2025-01-01",
"dateTo": "2025-03-31",
"maxResults": 200
}

E-commerce swipe file — top image ads in UK

{
"source": "creative_center",
"countries": ["GB"],
"adType": "IMAGE",
"maxResults": 100
}

Supported library countries

The Ads Library source works only for EU/EEA/Switzerland/UK countries.

List a country outside that region together with supported ones — ["DE", "US"] — and the run continues: DE is scraped, US is named in the log as skipped. List only unsupported countries and the run finishes normally, with a status message naming what to change — nothing was attempted and nothing was charged, so there is no failure to report. Nothing is silently swapped to another source: Creative Center ignores searchTerms and returns different fields, so its rows would not be what you searched for, and this Actor charges per row.

EU-27: AT BE BG CY CZ DE DK EE ES FI FR GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK
EEA: IS LI NO
Other: CH (Switzerland) GB (United Kingdom)

For any other country (US, AU, BR, JP…) use source: "creative_center" — remember it is browsed by country, so searchTerms do not apply there.


📦 Output schema

Each item in the dataset represents one ad. The source field tells you whether it came from the Ads Library or Creative Center.

{
"adId": "7318291038472910337",
"source": "library",
"advertiserName": "Zalando SE",
"advertiserBusinessId": null,
"adPaidForBy": null,
"adText": "Shoppe jetzt bei Zalando",
"landingPageUrl": null,
"ctaType": null,
"videoUrl": "https://v19-webapp.tiktok.com/video/tos/.../.mp4",
"thumbnailUrl": "https://p19-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/.../cover.jpg",
"imageUrls": [],
"firstShownDate": "2026-07-24",
"lastShownDate": "2026-08-14",
"adStatus": "ACTIVE",
"daysRunning": 22,
"uniqueUsersSeen": "10K-100K",
"uniqueUsersSeenByCountry": [],
"targetCountries": [],
"targetAgeGroups": [],
"targetGender": null,
"targetInterests": [],
"targetAudienceType": null,
"targetBehaviors": null,
"usersTargetedEstimate": null,
"rejectedInCountries": [],
"rejectionReasons": [],
"industry": null,
"campaignObjective": null,
"budgetRange": null,
"ctr": null,
"likes": null,
"videoMetrics": null,
"scrapedAt": "2025-04-04T14:23:11.000Z"
}

Library (default — resolveAdDetails: false): Returns advertiser name, ad copy, video/image creatives, ad dates, run status and the reach bucket. Targeting, landing page and CTA require resolveAdDetails: true.

Library example with resolveAdDetails: true (full targeting data unlocked):

{
"adId": "7318291038472910337",
"source": "library",
"advertiserName": "Zalando SE",
"advertiserBusinessId": "7123456789012345",
"adPaidForBy": "Zalando SE",
"adText": "Shoppe jetzt bei Zalando",
"landingPageUrl": "https://www.zalando.de/sale/?utm_source=tiktok",
"ctaType": "Shop now",
"videoUrl": "https://v19-webapp.tiktok.com/video/tos/.../.mp4",
"thumbnailUrl": "https://p19-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/.../cover.jpg",
"imageUrls": [],
"firstShownDate": "2025-02-10",
"lastShownDate": "2025-03-28",
"adStatus": "INACTIVE",
"daysRunning": 46,
"uniqueUsersSeen": "10M-20M",
"uniqueUsersSeenByCountry": [
{ "country": "DE", "impressions": "8.4M" },
{ "country": "AT", "impressions": "1.2M" }
],
"targetCountries": ["DE", "AT", "CH"],
"targetAgeGroups": ["18-24", "25-34", "35-44"],
"targetGender": "Female",
"targetInterests": ["Fashion & Accessories", "Shopping"],
"targetAudienceType": null,
"targetBehaviors": { "videoInteractions": true, "creatorInteractions": false },
"usersTargetedEstimate": "8.5M-10.4M",
"rejectedInCountries": [],
"rejectionReasons": [],
"advertiserCountry": "Germany",
"advertiserProfile": {
"username": "zalando",
"displayName": "Zalando",
"followerCount": "1.2M",
"accountType": "VERIFIED_BA",
"profileUrl": "https://www.tiktok.com/share/user/...",
"avatarUrl": "https://p16-common-sign.tiktokcdn-us.com/.../avatar.jpeg"
},
"industry": null,
"campaignObjective": "Sales",
"budgetRange": null,
"ctr": null,
"likes": null,
"videoMetrics": null,
"scrapedAt": "2025-04-04T14:23:11.000Z"
}

Note: add includeAudienceBreakdown: true to also receive audienceBreakdown — impressions split by country × age × gender.

Creative Center example:

{
"adId": "7401234567890123456",
"source": "creative_center",
"advertiserName": "GlowLab Skincare",
"advertiserBusinessId": null,
"adPaidForBy": null,
"adText": "We tested 100 skincare products. This one actually works.",
"landingPageUrl": null,
"ctaType": null,
"videoUrl": "https://v19-webapp.tiktok.com/video/tos/.../video.mp4",
"thumbnailUrl": "https://p16-sign-va.tiktokcdn.com/tos/.../cover.jpg",
"imageUrls": [],
"firstShownDate": null,
"lastShownDate": null,
"daysRunning": null,
"adStatus": "ACTIVE",
"uniqueUsersSeen": null,
"uniqueUsersSeenByCountry": [],
"targetCountries": ["US"],
"targetAgeGroups": [],
"targetGender": null,
"targetInterests": [],
"targetAudienceType": null,
"targetBehaviors": null,
"usersTargetedEstimate": null,
"rejectedInCountries": [],
"rejectionReasons": [],
"industry": "Skincare",
"industryCode": "label_14103000000",
"campaignObjective": "TRAFFIC",
"budgetRange": null,
"ctr": 3.24,
"likes": 18400,
"videoMetrics": {
"duration": 28.5,
"width": 1080,
"height": 1920
},
"scrapedAt": "2025-04-04T14:23:45.000Z"
}

Creative Center: Returns ad title, video creative, performance metrics (CTR, likes), industry, campaign objective, and budget tier. Dates, reach figures, and targeting details are not available from TikTok's Creative Center API.


Field reference

FieldSourceTypeNotes
adIdbothstringUnique TikTok ad ID
sourcebothstringlibrary or creative_center
advertiserNamebothstringBrand running the ad
advertiserBusinessIdlibrary*string|nullRequires resolveAdDetails: true. TikTok business platform ID
adPaidForBylibrary*string|nullRequires resolveAdDetails: true. DSA transparency: who paid for the ad
adTextbothstring|nullAd copy / creative title
videoUrlbothstring|nullDirect CDN video URL (.mp4)
thumbnailUrlbothstring|nullCover image URL
imageUrlsbothstring[]Static image creative URLs. Populated for IMAGE ads
firstShownDatelibrarystring|nullFirst impression date (YYYY-MM-DD). Null for CC
lastShownDatelibrarystring|nullMost recent impression date. Null for CC
daysRunninglibraryinteger|nullDays the ad ran, first shown → last shown inclusive. Null for CC
adStatusbothstringACTIVE, REJECTED (taken down — see rejectionReasons) or INACTIVE. CC always returns ACTIVE
uniqueUsersSeenlibrarystring|nullReach bucket TikTok labels "Unique users seen", e.g. "1K-10K". Null for CC
uniqueUsersSeenByCountrylibrary*object[]Per-country breakdown [{country, impressions}]. Requires resolveAdDetails: true. Empty array otherwise
targetCountrieslibrary* / CCstring[]Library: requires resolveAdDetails: true. CC: always populated
targetAgeGroupslibrary*string[]Requires resolveAdDetails: true. Age brackets: 18-24, 25-34, etc.
targetGenderlibrary*string|nullRequires resolveAdDetails: true. Male, Female, or All
targetInterestslibrary*string[]Requires resolveAdDetails: true. Interest categories
targetAudienceTypelibrary*string|nullRequires resolveAdDetails: true
targetBehaviorslibrary*object|nullRequires resolveAdDetails: true. {videoInteractions, creatorInteractions}
usersTargetedEstimatelibrary*string|nullSize of the targeted audience, e.g. "6.6M-8.0M". Requires resolveAdDetails: true. Null for CC
rejectedInCountrieslibrarystring[]Countries where the ad was rejected. Empty for CC
rejectionReasonslibrarystring[]TikTok's stated reason when an ad was taken down
landingPageUrllibrary*string|nullDestination URL of the ad. Requires resolveAdDetails: true
ctaTypelibrary*string|nullCall-to-action button label, e.g. Shop now. Requires resolveAdDetails: true
advertiserCountrylibrary*string|nullAdvertiser's registered country. Requires resolveAdDetails: true
advertiserProfilelibrary*object|nullPublic TikTok account behind the ad: {username, displayName, followerCount, accountType, profileUrl, avatarUrl}. Requires resolveAdDetails: true
audienceBreakdownlibrary*object[]Impressions by country × age × gender. Requires resolveAdDetails: true and includeAudienceBreakdown: true
industrycreative_centerstring|nullIndustry name, resolved against TikTok's live category dictionary. Null for library
industryCodecreative_centerstring|nullRaw TikTok category code, e.g. label_22110000000 — handy for grouping
campaignObjectiveboth*string|nulle.g. Sales, Reach, CONVERSION. For library requires resolveAdDetails: true
budgetRangenullTikTok publishes no spend or budget data for these ads, so this is always null
ctrcreative_centerfloat|nullClick-through rate. Null for library
likescreative_centerinteger|nullVideo like count. Null for library
videoMetricscreative_centerobject|null{duration, width, height}. Null for library
scrapedAtbothstringISO 8601 scrape timestamp

Field availability by source

Fieldlibrarycreative_centerNotes
advertiserName
adTextAd copy / creative title
videoUrl / thumbnailUrl
imageUrlsPopulated for IMAGE ads
firstShownDate / lastShownDateLibrary only
daysRunningComputed from dates
adStatus✅ (always ACTIVE)
uniqueUsersSeenReach bucket, e.g. "10K-100K"
uniqueUsersSeenByCountry✅*Requires resolveAdDetails: true. Per-country impressions
usersTargetedEstimate✅*Requires resolveAdDetails: true. Targeted audience size range
targetAgeGroups / targetGender✅*Library: enable resolveAdDetails: true
targetInterests / targetBehaviors✅*Library: enable resolveAdDetails: true
targetCountries✅*Library: enable resolveAdDetails: true
advertiserBusinessId / adPaidForBy✅*Library: enable resolveAdDetails: true
rejectedInCountriesDSA compliance data
industry / campaignObjectiveCC-only metrics
budgetRangeTikTok publishes no spend data — always null
ctr / likesPerformance metrics from CC
videoMetricsDuration, dimensions

Why are some fields null? TikTok's public APIs only expose a subset of ad data. Fields marked ❌ are not returned by TikTok — this is a platform limitation, not a scraper bug. No TikTok scraper can retrieve data that TikTok doesn't expose publicly.


🎯 Use cases

Competitor creative intelligence Pull all active ads from your competitor's brand in their key markets. Analyze which video hooks, CTAs, and creative formats they're investing in — and how large an audience they're reaching.

Building a TikTok ad swipe file Use Creative Center source to extract top-performing video ads by country, industry, and objective. Filter by budgetRange: HIGH and ctr > 2.0 to collect only proven performers for your creative research.

EU DSA compliance monitoring Track political, social, or issue-based advertisers in Europe using the Ads Library source. The adPaidForBy, targetAgeGroups, targetGender, and targetInterests fields reveal who is being targeted and by whom — exactly what DSA Article 39 requires to be transparent.

Agency multi-brand reporting Run weekly scrapes for a portfolio of brands across multiple EU markets. Export to CSV, push to Google Sheets, or integrate via Apify API into your reporting dashboard.

E-commerce market intelligence Monitor competitor ads in specific countries before entering a new market. See what formats (video vs image), what hooks, and which brands are getting the highest CTR in your niche.

Ad spend estimation (EU only) While TikTok doesn't expose exact spend, uniqueUsersSeen + targetCountries gives you a strong signal of which campaigns are getting real budget. A campaign reaching 500K+ users across 5 EU countries is clearly a priority for that advertiser.

Creative trend analysis Track how creative formats are shifting over time. Run the same query monthly and compare: are competitors shifting from video to image? Are they testing new CTA types? Which hooks are disappearing and which are growing?

Influencer & creator strategy The targetBehaviors.creatorInteractions field reveals which advertisers are targeting users who engage with specific creator profiles — a strong signal about which creator niches are commercially attractive.


💰 Pricing

From $15.00 / 1,000 ads — no monthly fees, pay only for what you scrape.

ModeCoverage~Cost per 1,000 ads
source: "library"EU/EEA/UK DSA data~$15
source: "creative_center"Global top ads~$15
source: "both"Combined — max data~$16–17

The both mode runs two browser sessions (one per source), and resolveAdDetails opens one extra page per ad (~7 sec each) — both add a little Apify platform compute on top of the base event fee. No monthly fees — pay only for what you scrape.


🆕 What's new

2026-08-25 — runs that explain themselves

  • An unsupported country no longer fails the run. List ["DE", "US"] with source: "library" and Germany is scraped while the US is named as skipped, in the log and again in the final summary. List only unsupported countries and the run finishes normally with a status message telling you exactly what to change — nothing was attempted, nothing was charged, so nothing failed.
  • A refused connection is retried on a second one. If TikTok does not answer through the primary connection, the task is retried through Apify Residential rather than the run being written off. The proxy check no longer trusts an open port as proof that TikTok accepts it.
  • An empty result is no longer mistaken for a block. A run is reported as blocked only when TikTok never answered at all — previously a single stray error, including a 403 on a telemetry request, was enough to call an ordinary empty search a block.
  • Pagination no longer stops early on overlapping countries. Scraping several countries for the same term used to cut the later ones short whenever they shared ads with the first.
  • Country codes are case-insensitive and de-duplicated. ["de"] works, ["US", "US"] is scraped once, and anything that is not an ISO 2-letter code is reported instead of being sent to TikTok.
  • Every reason at once. If more than one input needs fixing, the error lists all of them rather than revealing them one failed run at a time.
  • maxResults now defaults to 10, as the documentation always said. Runs started through the API without this field previously collected 50. Set it explicitly if you relied on the old value.
  • Every outcome says which stage it came fromINPUT: on a run that had nothing to do, BLOCKED: on one TikTok refused — so the two are never confused for each other.

2026-08-23 — deeper data, sharper filters

  • Deep pagination. Pull thousands of ads per search — the Actor walks the full result set, so maxResults is the only thing that limits you.
  • Full targeting breakdown. With resolveAdDetails, every ad comes back with age groups, gender, interests, target countries and per-country reach.
  • Ad copy for the EU Ads Library. We found a way to pull adText for Library ads, not just Creative Center.
  • New fields: landingPageUrl (where the ad sends people), ctaType (button label), rejectionReasons, advertiserProfile (handle, followers and verification of the TikTok account behind the ad), advertiserCountry, industryCode, plus an optional audienceBreakdown — impressions by country × age × gender.
  • Server-side format filtering. VIDEO, IMAGE and the new TEXT are applied by TikTok itself, so you get exactly the creative type you asked for.
  • Live industry taxonomy. Categories are resolved against TikTok's own dictionary — 258 up-to-date names.
  • Precise daysRunning. Measures the real flight window, first shown to last shown.
  • Moderation transparency. Ads TikTok pulled are labelled REJECTED with the stated reason — a fast way to spot brand impersonation and policy-breaking competitors.
  • Unambiguous runs. Every run reports what it retrieved, what it skipped and why it stopped. An empty result means there were no matching ads in the countries that actually ran — and the final summary lists which those were, so it is never a guess.

⚠️ Limitations

TikTok Ads Library is EU/EEA/UK only This is a hard platform constraint — TikTok built the Ads Library specifically for EU Digital Services Act compliance. US, APAC, LATAM, and Middle East markets are not available through this source. Use source: "creative_center" for global coverage.

3,600-result hard cap per query (library) TikTok caps the Ads Library at 300 pages × 12 ads = 3,600 results per search. The scraper detects this and logs a clear warning. To get more comprehensive data, run multiple narrower searches (e.g., different date ranges, different keywords).

No spend data TikTok does not expose actual ad spend figures — not even ranges. This is unlike Meta, which provides {min, max} spend for political ads. All TikTok spend intelligence tools (AdSpyder, PiPiAds, etc.) are using estimates, not real figures.

Some Library ads carry no creative When TikTok takes an ad down, the video and images are removed from the archive. The record still arrives with its copy, landing page, targeting and the stated rejection reason — only the creative itself is gone.

Creative Center shows only top-performing ads The Creative Center does not return all ads — only ads that TikTok's algorithm has identified as top performers in a given period, country, and category. This is by design: it's a creative inspiration tool, not a complete ad archive. TikTok also serves a curated subset to logged-out visitors, so a run may return fewer ads than requested.

TikTok page structure may change TikTok periodically updates their frontend. If results become empty after an update, open an issue and we'll push a fix within 24–48 hours.


🌍 Supported countries — quick reference

Ads Library (EU only)

CodeCountry
ATAustria
BEBelgium
BGBulgaria
CYCyprus
CZCzech Republic
DEGermany
DKDenmark
EEEstonia
ESSpain
FIFinland
FRFrance
GRGreece
HRCroatia
HUHungary
IEIreland
ITItaly
LTLithuania
LULuxembourg
LVLatvia
MTMalta
NLNetherlands
PLPoland
PTPortugal
RORomania
SESweden
SISlovenia
SKSlovakia
ISIceland
LILiechtenstein
NONorway
CHSwitzerland
GBUnited Kingdom

Creative Center (global — examples)

US GB AU CA DE FR BR MX JP KR IN ID TH PH VN SG MY ZA AE SA — and many more.