TikTok Ads Scraper
Scrape the TikTok Ad Library by keyword, advertiser, country or date. Get captions, run dates, countries, video and landing URLs. EEA and UK only.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
searchTerms,advertiserNames,adLibraryUrls(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.00045 per ad = $0.45 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Ad scraped | One ad row delivered from the TikTok Commercial Content Library. Sample and diagnostic rows are never charged. | $0.00045 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-16, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
searchTerms | Keywords to search for. Matches both advertiser names and ad captions, so "running shoes" returns every ad whose copy mentions running shoes. Up to 20 per run; the row budget is shared evenly between them. | array |
advertiserNames | Registered advertiser names, for example "NIKE Retail B.V.". Each is resolved against the library's own advertiser register first, then that advertiser's complete ad set is pulled. Typing a brand word like "Nike" picks up every registered entity whose name starts with it. | array |
adLibraryUrls | Paste addresses straight from library.tiktok.com/ads. The country, date range, advertiser, sort order and format filters already in the URL are read back out and used as they are. | array |
countries | Two-letter codes for the countries an ad was shown in, or "all". Only these exist in this 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. Leave empty to search all of them. On its own, with no search terms, it means "every ad running in these countries". | array |
dateFrom | The start of the window an ad must have run in, as YYYY-MM-DD. Defaults to 30 days ago. The library holds nothing before 2022-10-01 and an earlier date is moved forward to it. | string |
dateTo | The end of the window, as YYYY-MM-DD. Defaults to today. | string |
maxItems | Total number of ads to return across every search term, advertiser and URL. The budget is shared evenly between them. Keep it low while you are testing - you pay per row. | integer |
includeAdDetails | On by default. This is the only source of the landing page URL, the call to action, the campaign objective, the advertiser's registry country, the full list of targeted countries, the audience size and the per-country impression bands. Turn it off for a faster, lighter run with those fields left null. | boolean |
adFormat | Return every format, or only video, image or text ads. | string |
adStatus | Return every ad, only ads still running, or only ads that have stopped. | string |
sortBy | How the library should order the results before they are paged. Published-date descending is the default because it is the ordering the library itself repeats and skips least. | string |
proxyUrls | Leave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port. | array |
sessionCookies | Optional, and almost never needed. The Commercial Content Library is a public transparency archive and this Actor reads it without any account. Supply your own TikTok account cookie only as a safety net for the day the library stops serving anonymous callers. In Chrome: F12 -> Application -> Cookies -> tiktok.com, and copy the value of sessionid. Anyone with this value can act as your account, so treat it like a password. | array |
What you get
A structured dataset — each result includes fields like:
searchTermadIdadvertiserNamecaptionfirstShownDatelastShownDatecountriesTargeteduniqueUsersSeenvideoUrlthumbnailUrllandingUrlcallToActionadFormatadDetailUrlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Developer & Research Tools
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
GitHub Scraper
Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.
Stack Overflow / Stack Exchange Scraper
Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.
Package Registry Scraper (npm + PyPI)
Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.
arXiv Scraper
Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.
OpenAlex Scholarly Works Scraper
Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.
Crossref Scholarly Works Scraper
Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.
Where this tool sits
- Categories
- Developer & Research Tools
TikTok Ads Scraper: ads from TikTok's public Commercial Content Library
Search TikTok's own ad archive by keyword, advertiser, country and date, and get one flat row per ad: 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 |
| Ceiling | 20,000 ads per run, and 20 terms, 20 advertisers and 20 links |
| Account needed | None |
| Price | $0.45 per 1,000 ads, flat on every plan |
📣 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 every ad whose text mentions running shoes.
An advertiser name is resolved against the library's own register first, then that advertiser's ads are pulled. Typing a brand word like Nike picks up every registered entity 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 every ad running in those countries.
📥 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 | Starts at | What it is |
|---|---|---|
searchTerms | box holds running shoes | Keywords. Up to 20, and the row budget is split evenly between every target. |
advertiserNames | empty | Registered names like NIKE Retail B.V., or a brand word. |
adLibraryUrls | empty | Addresses copied from the library site. |
countries | 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. |
dateFrom, dateTo | empty | YYYY-MM-DD. Left empty it covers the last 30 days. Anything earlier than 2022-10-01 is moved forward to it. |
maxItems | 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. |
adFormat | all | all, video, image or text. |
adStatus | all | all, active for still running, inactive for stopped. |
sortBy | create_time,desc | Published date newest first is the order the library repeats and skips least. Last-shown and unique-users orders are there too. |
proxyUrls | empty | Optional. Your own servers, as http://user:pass@host:port, used exactly as given. |
sessionCookies | empty | Optional and almost never needed. Your own TikTok sessionid, as a safety net if the archive stops serving signed-out readers. Anyone holding that value can act as your account, so treat it like a password. |
Run it with the input empty and you get one labelled sample row and nothing else.
📤 What you get back
One flat row per ad. These are the fields, read off the deployed output schema.
| Field | What it is |
|---|---|
adId, adDetailUrl | The library's own id, and the link back to that ad's page. |
advertiserName, advertiserId | Who ran it. paidBy is filled when a sponsor is named separately. |
caption | The ad copy as the archive holds it. |
firstShownDate, lastShownDate | Day granularity, ISO format. |
countriesTargeted, searchedRegions | Where the ad ran, and which countries your search covered. |
uniqueUsersSeen, targetAudienceSize, impressionsByCountry | Bands, not numbers. TikTok publishes ranges. |
videoUrl, thumbnailUrl, imageUrls | Links only, and they are signed and expire. Download what you want to keep. |
landingUrl, callToAction, advertisingObjective | Where the ad clicks through to, the button text, and the campaign objective. |
adFormat, adStatus | video, image or text, and active, inactive or rejected. |
targetedAgeGroups, targetedGenders | Only what the archive publishes, which is not every ad. |
searchTerm | Which of your terms, advertisers or links produced the row. |
🧾 Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it |
|---|---|
| An ad | ok: true and recordType: "ad" |
| The sample row | _sample: true, written only when the input was empty |
| A diagnostic | ok: false, _diagnostic: true and an errorCode |
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. |
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. |
▶️ How to run it
1. Open TikTok Ads Scraper and click Try for free. 2. Put your keywords into Search terms, or names into Advertiser names, or paste library links into Ad Library URLs. 3. 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. 4. Set Maximum rows low, around 20, for the first run, then click Start. 5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost?
$0.45 per 1,000 ads. Flat on every Apify plan, no volume tiers.
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 people use it for
- Watching what a competitor 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 scheduled runs. - Collecting landing pages for a set of advertisers to see where the traffic is being sent.
- Building a picture of which countries an advertiser targets, from
countriesTargeted.
🚧 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 failed detail lookup leaves fields null, and the row does not say so.
landingUrl,
countriesTargeted, advertiserRegistryCountry, targetAudienceSize, impressionsByCountry, targetedAgeGroups and targetedGenders can be null either because the archive has no value or because that one lookup did not come back. Treat a null as "unknown", not "none".
- 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_INPUT row to tell you. Check searchedRegions on 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.
🧭 Which TikTok scraper do you need?
| If you want | Use |
|---|---|
| Ads from the public Commercial Content Library | This one |
| Videos under a hashtag | TikTok Hashtag Scraper |
| Comments under a video | TikTok Comments Scraper |
| Follower counts and profile stats | TikTok Profile Scraper |
| Products and units sold on TikTok Shop | TikTok Shop 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 ads? No. There is no US edition of this library, so nothing in the world can pull them 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. The row does not distinguish them, so re-run the ad if a null matters.
How far back does it go? 2022-10-01. Earlier dates are moved forward to it and you get an uncharged row telling you.
Can I run it on a schedule? Yes. adId is stable, so a daily run diffs cleanly against the last one.
Is scraping the ad library legal? It is a public archive that TikTok publishes to meet transparency rules. Apify's write-up on scraping and the law 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.