TikTok Ad Library Scraper — Resume & $0-on-Block
Pricing
from $0.80 / 1,000 ad scraped (1 result)s
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
Maintained by CommunityActor 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-100Kunique 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.

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:
| Field | Example |
|---|---|
advertiser_name | Alltricks — the advertiser's legal name as TikTok publishes it |
ad_id / detail_url | 1802755681539186 / a link to the ad's page in the library |
title | the ad's title as listed in the library |
first_shown / last_shown / days_shown | 2024-07-25 / 2026-07-08 / 713 |
audience_estimate | 10K-100K — TikTok's own published range of unique users reached |
country | the country filter the ad was found under (all when you search all countries) |
surface | commercial_content_library or creative_center_top_ads |
image_urls / video_urls | the creative's image and video URLs. For reference only — never downloaded, never billed |
media | the creative files that are downloaded to key-value storage in snapshot_with_media mode; stored_key tells you where each one was saved |
_meta | when 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_caserow, 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.
maxItemsandmaxBudgetUsdare enforced across resumes.
Pricing
Pay per event — no subscription, no charge for data you didn't ask for.
| Event | Price |
|---|---|
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 doing | Typical cost |
|---|---|
| Trying it out — 200 ads from one query | about $0.21 |
| A full audit — 5,000 ads across several countries/queries | about $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
- Open the Input tab and enter an advertiser name or keyword in Advertiser names / keywords — or keep the prefilled
nike. - Choose Surfaces: the EU library (default), Creative Center Top Ads, or both.
- Set Countries: an ISO code, or
allfor the EU library. - Set Max ads to what you want to pay for at most. For a first try, 20–200 is plenty.
- 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
| Field | Meaning |
|---|---|
queries | Required. 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) |
countries | EU library: target country ISO code or all. Creative Center: ISO code (all falls back to US) |
lookbackDays | EU library last-shown window in days, max 365 |
mode | snapshot or snapshot_with_media (also downloads creatives) |
maxItems / maxBudgetUsd | Hard caps — you are never charged beyond them, across resumes included |
maxAdsPerUnit | Cap on ads per (surface × query × country) work unit (advanced, default 600) |
ccPeriodDays | Creative Center ranking window — 7, 30 or 180 days (default 30) |
useResidentialProxy | Off 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.