TikTok Ads Scraper - Ad Library by Keyword and Country
Pricing
from $0.44 / 1,000 ads
TikTok Ads Scraper - Ad Library by Keyword and Country
Scrape TikTok ads from TikTok's public ad library by keyword, advertiser, country or date. Each ad has the advertiser, caption, first and last shown dates, countries, a reach band, video, thumbnail, call to action and landing page. EEA and UK ads only, no US. $0.45 per 1,000 ads.
Pricing
from $0.44 / 1,000 ads
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
11
Total users
6
Monthly active users
4 days ago
Last modified
Categories
Share
Scrape TikTok ads from TikTok's public ad library, the Commercial Content Library: search by keyword, advertiser, country and date, and get one flat row per ad with who ran it, the caption, the first and last dates it was shown, the countries it ran in, the audience band TikTok publishes, the video and thumbnail, the button text and the landing page.
Read the coverage line before you plan anything around this. The archive exists because of EU and UK transparency rules, so it holds the EEA plus GB, CH, NO, IS and LI, and nothing before 2022-10-01. There is no United States edition of this library, and no spend or performance figures in it.
| Input | Search terms, advertiser names, or links from library.tiktok.com/ads |
| Output | One row per ad: advertiser, caption, first and last shown dates, countries, audience bands, video and thumbnail links, call to action and landing page |
| Ceiling | 20,000 ads per run, and 20 terms, 20 advertisers and 20 links |
| Account needed | None |
| Price | $0.45 per 1,000 ads on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 11,000 |
🔍 What TikTok Ads Scraper does
Four ways to say what you want, and they combine in one run.
A keyword matches advertiser names and ad copy, so running shoes returns ads whose text
mentions running shoes.
An advertiser name is looked up in the library's own register first, then that advertiser's ads
are pulled. Typing a brand word like Nike picks up registered entities whose name starts with
it, and the row keeps your wording in searchTerm.
A library link pasted straight from the site: the country, dates, advertiser, order and format already in the address are read back out and used as they are.
Countries on their own, with no search term, means the ads running in those countries.
📋 What data you get from each TikTok ad
| What you get | Field |
|---|---|
| The library's own id, and the link back to the ad's page | adId, adDetailUrl |
| Who ran it, and who paid when a sponsor is named | advertiserName, advertiserId, paidBy, advertiserRegistryCountry |
| The ad copy | caption |
| First and last day it was shown | firstShownDate, lastShownDate |
| Where it ran, and which countries your search covered | countriesTargeted, searchedRegions |
| Reach, audience size and impressions per country, as bands | uniqueUsersSeen, targetAudienceSize, impressionsByCountry |
| The creative: video, thumbnail and image links | videoUrl, thumbnailUrl, imageUrls |
| Landing page, button text and campaign objective | landingUrl, callToAction, advertisingObjective |
| Format and status | adFormat, adStatus |
| Age and gender targeting, where published | targetedAgeGroups, targetedGenders |
| Which of your terms, advertisers or links produced the row | searchTerm |
▶️ How to scrape TikTok ads
- Open TikTok Ads Scraper and click Try for free.
- Put your keywords into Search terms, or names into Advertiser names, or paste library links into Ad Library URLs.
- Set Ad target countries to the codes you care about, and a Shown from and Shown until date if the last 30 days is not the window you want.
- Set Maximum rows low, around 20, for the first run, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
Start it with the input empty and you get one labelled sample row and nothing else.
💰 How much does it cost to scrape TikTok ads?
$0.45 per 1,000 ads on the Free plan. Paid plans pay a little less: $0.445 on Starter, $0.44 on Scale and $0.435 on Business. On the free plan, the $5 Apify gives you each month covers about 11,000 ads.
You are charged per ad row delivered. Ads already seen earlier in the same run are dropped before that, so a creative matching two of your terms costs once. The sample row, every diagnostic row and a country code or date the library does not support are not charged.
📥 What you give it
{"searchTerms": ["running shoes", "protein powder"],"countries": ["DE", "FR", "IT"],"dateFrom": "2026-07-01","dateTo": "2026-08-15","maxItems": 100,"includeAdDetails": true}
| Field | Default | What it is |
|---|---|---|
searchTerms | none (the box holds running shoes) | Keywords. Up to 20, and the row budget is split evenly between every target. |
advertiserNames | none | Registered names like NIKE Retail B.V., or a brand word. |
adLibraryUrls | none | Addresses copied from the library site. Any other link gets an uncharged BAD_INPUT row. |
countries | none (the box holds DE) | Two-letter codes, or all. Only these exist in the library: 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. Empty searches all of them. |
dateFrom, dateTo | the last 30 days | YYYY-MM-DD. Anything earlier than 2022-10-01 is moved forward to it. |
maxItems | none (the box holds 20) | Total ads across every target, up to 20,000. |
includeAdDetails | on | Fetches the per-ad transparency record. It is the only source of landingUrl, callToAction, advertisingObjective, advertiserRegistryCountry, countriesTargeted, targetAudienceSize and impressionsByCountry. Off is faster and leaves those null. |
adFormat | none (the form starts at all) | all, video, image or text. |
adStatus | none (the form starts at all) | all, active for still running, inactive for stopped. |
sortBy | none (the form starts at create_time,desc) | Published date newest first is the order the library repeats and skips least. Last-shown and impression orders are there too. |
proxyUrls | none | Optional. Your own servers, as http://user:pass@host:port, used exactly as given. |
sessionCookies | none | Not needed, so leave it empty. The library is public and runs read it signed out. A session put here is only tried if the library refuses its public access, and it opens nothing a signed-out visitor cannot see. Anyone holding a session can act as that account, and you are responsible for using yours within the site's terms. The field is stored encrypted. |
📤 What you get back
One flat row per ad, with the fields above. These are the ones that need reading:
| Field | How to read it |
|---|---|
firstShownDate, lastShownDate | Day granularity, ISO format. |
uniqueUsersSeen, targetAudienceSize, impressionsByCountry | Bands, not numbers. TikTok publishes ranges. |
videoUrl, thumbnailUrl, imageUrls | Links only, signed and expiring. Download what you want to keep. |
adStatus | active, inactive or rejected. |
paidBy | Filled only when the library names a sponsor separately. |
targetedAgeGroups, targetedGenders | Only what the archive publishes, which is not every ad. |
searchedRegions | The countries your search actually covered. Check it before you read a country breakdown. |
detailsComplete | true when the ad's own transparency record was read. false when it was asked for and did not come back, because the run reached its time limit while reading it or that one lookup failed, so the fields only that record holds are null on this row. null when includeAdDetails is off. |
🧾 Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| An ad | ok: true and recordType: "ad" | yes |
| The sample row | _sample: true, written only when the input was empty | no |
| A diagnostic | ok: false, _diagnostic: true and an errorCode | no |
Filter on recordType == "ad" and you have your data. charged: true marks a real ad row and
false marks a sample or diagnostic one. Read it as the row type: it is stamped as the row is
built, so it is not a receipt. Your run's own event count in Apify is the billing record.
| Code | What it means |
|---|---|
BAD_INPUT | A country code that does not exist in this library, a date outside it, or a link the actor cannot read. |
NO_RESULTS | Nothing matched. On an advertiser name it usually means no registered match, so try it as a keyword. |
RATE_LIMITED | The library kept answering "system busy" for that search. Worth a re-run with a narrower window. |
NETWORK | The library was unreachable or answered badly. |
TIME_BUDGET | The run ran out of time before reaching that target. The run ends as failed only when the time limit stopped it before any ad came back. |
PROXY_INPUT_ADJUSTED | Something you put in proxyUrls was unusable, so the run carried on without it. |
CHARGE_ERROR | A charge could not be recorded. A couple in a row stops the run. |
💡 What people use it for
- Watching what a rival brand is running right now in a given market, by advertiser name.
- Pulling a category's creatives by keyword and reading the captions and calls to action together.
- Tracking how long an ad stays up, using
firstShownDateandlastShownDateacross repeated runs. - Collecting landing pages for a set of advertisers to see where the traffic is being sent.
From one brand's ads to what people say about it, in two runs:
- Run this with the brand in Advertiser names and your markets in Ad target countries.
- Sort on
firstShownDateand open theadDetailUrlof the newest ads to see the creative. - Put the brand name into the Search queries box of TikTok Scraper to see the organic videos about it.
🚧 What it does not do
- No United States ads. The archive covers the EEA plus GB, CH, NO, IS and LI, and nothing before 2022-10-01. This is the library's own scope.
- No spend and no performance data. Reach and impressions come back as bands, because bands are what TikTok publishes.
- A detail lookup that does not come back leaves fields null.
landingUrl,countriesTargeted,advertiserRegistryCountry,targetAudienceSize,impressionsByCountry,targetedAgeGroupsandtargetedGenderscan be null either because the archive has no value or because that one lookup did not come back, for instance when the run hit its time limit. Such an ad is still delivered and charged, markeddetailsComplete: false. - An unsupported country next to a search term widens the search. Ask for a country the library
does not have and the run searches every country it does have, with one uncharged
BAD_INPUTrow to tell you. ChecksearchedRegionson the rows before you read a country breakdown. - Media is linked, not downloaded. Those links are signed and expire.
- 12 rows a page. A large
maxItemsis many round trips, so give a big run room. - Ordering by last shown repeats and skips ads, which is why published-date order is the starting point.
- It is not an official TikTok tool. Dami's Studio is independent and is not affiliated with or endorsed by TikTok, or by any other company named on this page.
🧭 Which TikTok scraper do you need?
| If you want | Use |
|---|---|
| Ads from TikTok's public ad library | This one |
| Facebook and Instagram ads from Meta's ad library | Meta Ad Library Scraper |
| The ads a brand runs on Google, by domain or advertiser | Google Ads Transparency Scraper |
| Products, prices and units sold on TikTok Shop | TikTok Shop Scraper |
| The hashtags ranking in a country right now | TikTok Trending Hashtags |
| Videos posted under a hashtag | TikTok Hashtag Scraper |
| A profile plus its newest videos, or a keyword search | TikTok Scraper |
| Comments under a video | TikTok Comments Scraper |
❓ Questions people ask
Do I need a TikTok account or an ad account?
No. The library is a public transparency archive and the run reads it the way a signed-out visitor does.
Can I get US TikTok ads?
No. There is no US edition of this library, so nothing can pull US ads from it.
Why are some fields null on a row?
Either the archive has no value, or the per-ad record did not come back that time. detailsComplete
tells them apart: false means it did not come back, so re-run that ad if a null matters.
How far back does the TikTok ad library go?
2022-10-01. Earlier dates are moved forward to it and you get an uncharged row telling you.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made code
for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/tiktok-ads-scraper. Either way the
run happens on your Apify account at the same price.
Is scraping the TikTok ad library legal?
It is a public archive TikTok publishes to meet transparency rules, and a normal run reads it the way a signed-out visitor does: no account, nothing private. If the ads you collect name or show a person, that is personal data under GDPR and similar laws, so keep only what you need. TikTok's own terms still apply to what you do with it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the search, advertiser or link that misbehaved and
the run ID. The errorCode on the diagnostic row usually names the problem on its own.