TikTok Ad Library Scraper — Resume & $0-on-Block avatar

TikTok Ad Library Scraper — Resume & $0-on-Block

Pricing

from $0.80 / 1,000 ad scraped (1 result)s

Go to Apify Store
TikTok Ad Library Scraper — Resume & $0-on-Block

TikTok Ad Library Scraper — Resume & $0-on-Block

Get TikTok ads from the EU Commercial Content Library (DSA archive, searchable by advertiser) or Creative Center Top Ads (global high-performers with CTR/like metrics). Resumable; never charges for blocked or rate-limited runs.

Pricing

from $0.80 / 1,000 ad scraped (1 result)s

Rating

0.0

(0)

Developer

Sumitsubo

Sumitsubo

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a month ago

Last modified

Categories

Share

TikTok Ad Library Scraper — EU Ad Library & Top Ads, Resume & $0-on-Block

Introduction

Get TikTok ads from both of TikTok's public transparency sources in one Actor:

  • EU Commercial Content Library (library.tiktok.com) — every ad delivered in the EU over roughly the last 12 months (the DSA archive), searchable by advertiser name or keyword, with the advertiser's legal name, first and last shown dates and TikTok's audience estimate (e.g. 10K-100K unique users).
  • Creative Center Top Ads (ads.tiktok.com/business/creativecenter) — a browse feed of high-performing ads worldwide with CTR, likes and video duration, plus direct video URLs.

It is built for large collections that never silently lose data: a killed run resumes where it stopped, failures are written to the dataset, and a blocked or rate-limited fetch is not billed.

This is an independent tool. It is not affiliated with, endorsed by, or sponsored by TikTok. TikTok is a trademark of its owner, used here only to say which public service this Actor reads.

The dataset Overview for a nike search in the EU library: advertiser, ad ID, first and last shown, days shown, audience estimate, title and detail link

A 20-ad search for nike in the EU library. The search is not an exact advertiser filter — here it returned ads from Alltricks and The Sole Supplier rather than from Nike itself — so every row says who the advertiser is.

What you get for every ad

EU library rows:

FieldExample
advertiser_nameAlltricks — the advertiser's legal name as TikTok publishes it
ad_id / detail_url1802755681539186 / a link to the ad's page in the library
titlethe ad's title as listed in the library
first_shown / last_shown / days_shown2024-07-25 / 2026-07-08 / 713
audience_estimate10K-100K — TikTok's own published range of unique users reached
countrythe country filter the ad was found under (all when you search all countries)
surfacecommercial_content_library or creative_center_top_ads
image_urls / video_urlsthe creative's image and video URLs. For reference only — never downloaded, never billed
mediathe creative files that are downloaded to key-value storage in snapshot_with_media mode; stored_key tells you where each one was saved
_metawhen and from which URL the row was collected, plus the Actor and schema version

Creative Center rows carry metrics: { ctr, like, video_duration } and industry / objective instead of dates. metrics also holds cost_tier, which TikTok fills for only about half of ads and whose scale it does not publish.

Export to JSON, CSV or Excel, or read it from the API.

One note on spreadsheets. Advertiser names and ad titles are written by the advertiser, not by us, and a value starting with =, +, - or @ is treated as a formula by Excel and Sheets. If you open exports directly, import them as text rather than double-clicking the file.

Why this scraper

  • Two sources, one schema. The EU archive and the global Top Ads feed come out as the same flat snake_case row, so you don't have to stitch two tools together.
  • Resume. Kill or time out a large run and it continues exactly where it stopped — no re-fetching, no double charges. A multi-country, multi-advertiser audit can be one run instead of dozens of small ones.
  • Not billed when blocked. A blocked or rate-limited fetch is detected and not billed. TikTok's search sometimes answers a bad request with an empty but OK response; this Actor checks it against the total the page itself shows, so a soft failure is never sold to you as "no ads found".
  • No silent loss. Every work unit is checkpointed. A failure is written to the dataset as an {_error, _reason} record so you can see what is missing.
  • Real media files. Optionally download the creative videos and covers into key-value storage (TikTok's own media hosts only, capped per ad).
  • Hard cost ceilings. maxItems and maxBudgetUsd are enforced across resumes.

Pricing

Pay per event — no subscription, no charge for data you didn't ask for.

EventPrice
actor-start$0.005 per run
ad-scraped$0.001 per ad
media-downloaded$0.005 per file (only in snapshot_with_media)

actor-start is charged once per run, when the first search completes — whether or not it finds any ads. A run in which every fetch is blocked or rate-limited costs nothing, the start included. You are never charged per blocked fetch, or for ads beyond maxItems / maxBudgetUsd.

Apify Store discounts lower the per-ad price on higher plans: $0.0009 at the Silver discount tier, $0.0008 at Gold and above.

Typical cost

What you're doingTypical cost
Trying it out — 200 ads from one queryabout $0.21
A full audit — 5,000 ads across several countries/queriesabout $5.01
With media downloads (snapshot_with_media)add $0.005 per file archived

Use cases

  • Competitor research in the EU — every ad a competitor ran to EU users in the last year, with reach ranges and how long each ran.
  • Creative inspiration — the Top Ads feed shows what is performing now, with CTR and likes.
  • Brand monitoring — see which other advertisers' ads come up for your brand in the EU library.
  • Agency reporting — schedule a run and send the results to Sheets, Slack or a webhook with Apify integrations.
  • AI agents — connect through the Apify MCP server and let your agent look up live TikTok ads.

Tutorial

  1. Open the Input tab and enter an advertiser name or keyword in Advertiser names / keywords — or keep the prefilled nike.
  2. Choose Surfaces: the EU library (default), Creative Center Top Ads, or both.
  3. Set Countries: an ISO code, or all for the EU library.
  4. Set Max ads to what you want to pay for at most. For a first try, 20–200 is plenty.
  5. Click Start, then open the Output tab, or read the dataset from the API.

To keep an eye on a competitor, save the input as a task and put it on a schedule.

Input reference

FieldMeaning
queriesRequired. Advertiser names or keywords. Used by the EU library; Creative Center is a browse-only feed without keyword search
surfaces["ccl"] (EU library, default) and/or ["cc"] (Creative Center Top Ads, one work unit per country)
countriesEU library: target country ISO code or all. Creative Center: ISO code (all falls back to US)
lookbackDaysEU library last-shown window in days, max 365
modesnapshot or snapshot_with_media (also downloads creatives)
maxItems / maxBudgetUsdHard caps — you are never charged beyond them, across resumes included
maxAdsPerUnitCap on ads per (surface × query × country) work unit (advanced, default 600)
ccPeriodDaysCreative Center ranking window — 7, 30 or 180 days (default 30)
useResidentialProxyOff by default: TikTok's libraries are reachable without it. Turn it on only if your runs get blocked

Input and output examples

Input example

{
"queries": ["nike"],
"surfaces": ["ccl"],
"countries": ["all"],
"maxItems": 20
}

Output example

A real row from the run in the screenshot above (media URLs shortened):

{
"ad_id": "1802755681539186",
"country": "all",
"surface": "commercial_content_library",
"advertiser_name": "Alltricks",
"title": "Nike",
"first_shown": "2024-07-25",
"last_shown": "2026-07-08",
"days_shown": 713,
"audience_estimate": "10K-100K",
"metrics": { "impression": 0 },
"industry": null,
"objective": null,
"audit_status": "1",
"detail_url": "https://library.tiktok.com/ads/detail/?ad_id=1802755681539186",
"media": [
{ "kind": "image", "url": "https://p16-common-sign.tiktokcdn.com/…", "stored_key": null },
{ "kind": "video", "url": "https://library.tiktok.com/api/v1/cdn/…", "stored_key": null }
],
"image_urls": ["https://p16-common-sign.tiktokcdn.com/…"],
"video_urls": ["https://library.tiktok.com/api/v1/cdn/…"],
"_meta": {
"_scraped_at": "2026-09-25T00:00:00Z",
"_source_url": "https://library.tiktok.com/ads?region=all&adv_name=nike&…",
"_actor_version": "<actor build version>",
"_schema_version": "1.1.0"
}
}

stored_key is null in snapshot mode. In snapshot_with_media it is filled once the file is saved, so every file you are charged for can be found in the run's key-value store.

A blocked or failed unit appears as:

{ "_error": true, "_reason": "blocked", "_source_url": "…", "_work_unit": "…" }

FAQ and support

Why only EU ads in the library? The Commercial Content Library exists because of the EU Digital Services Act, so it only contains ads delivered in the EU. For ads outside the EU, use the Creative Center surface — but note that it is a curated sample of high-performing ads (roughly the top 20 per country and period on the login-free tier), not an exhaustive archive.

Can I get exact spend or impressions? No. TikTok does not publish exact spend or impressions for commercial ads. audience_estimate is TikTok's own published range; this Actor does not invent numbers.

Why does my search return other advertisers? The library search is not an exact advertiser filter. A brand search also returns other advertisers' ads — in the example above, Alltricks and The Sole Supplier. Filter on advertiser_name if you only want one advertiser.

My run was stopped or timed out. Do I lose what it collected? No. What was collected stays in the dataset, and progress is checkpointed. Resurrect the run from the Console — it restarts with the same storage and continues where it stopped, without charging again for the run start or for ads already delivered.

Does it log in to TikTok? No. It reads the public, logged-out pages only.

Something doesn't work. Open an issue on the Issues tab with the run ID, and I'll look at it.

Found this useful? A rating on this page helps other people evaluating it decide faster — it takes a few seconds and means a lot for a small, actively maintained Actor.