TikTok Ads Scraper - Ad Library & Top Ads
Pricing
from $1.50 / 1,000 results
TikTok Ads Scraper - Ad Library & Top Ads
Extract TikTok ads, targeting, brand-disclosed posts, Top Ads metrics, suggestions and country reports. Search the EU/EEA, UK and Swiss library or selected Top Ads markets. Pay per delivered row plus a start fee.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
7
Total users
4
Monthly active users
6 hours ago
Last modified
Categories
Share
TikTok Ads Scraper
Extract TikTok ad creatives, reach and targeting from the European Commercial Content Library, plus Top Ads rankings for selected markets, as exportable rows.
- Search ads by keyword, advertiser name or known ad IDs.
- Read brand-disclosed creator posts by exact username.
- Compare Top Ads metrics, search suggestions and country reports.
- Add available targeting and landing pages without creating extra billed rows.
- Pay $1.50 per 1,000 delivered rows on the Free plan, plus a small start fee.
What does TikTok Ads Scraper do?
The Actor collects public advertising data from TikTok's Commercial Content Library at library.tiktok.com and Creative Center Top Ads. Library searches cover the EU/EEA, the UK and Switzerland. Top Ads is a separate ranking with additional markets, not a worldwide ad archive.
- Ads: keyword or advertiser searches and direct ad IDs;
rowTypeisad. - Commercial posts: brand-disclosed posts;
rowTypeisother_commercial. - Combined search: ads and creator posts share one search allowance.
- Top Ads: ranked creatives;
rowTypeistop_ad. - Suggestions: advertiser names or keywords;
rowTypeissuggestion. - Reports: country-level metrics;
rowTypeisreport.
Each delivered row is billed. includeDetails is on by default and enriches existing ad rows rather than adding another charge.
What data can you extract from TikTok?
Available fields depend on the content type and whether details were returned. Examples below illustrate the format, not a promised result.
Ads: ad
| Field | Description | Example |
|---|---|---|
id, adId | Library ad identifier | 1877939373541554 |
country | Market searched | FR |
adTitle | Caption, not advertiser name | Discover our spring collection |
adType | Creative format | VIDEO |
adVideoUrl, adVideoCover | Video and cover URLs | https://example.com/ad.mp4 |
adImageUrls | Image or carousel URLs | [] |
adStartDate, adEndDate | First and last days shown | 2026-10-01 |
adImpressions | Published reach range | 100K-200K |
advertiserName | Advertiser label | Example Brand |
advertiserId | Business identifier, when available | 123456789 |
advertiserLocation, advertiserPaidForBy | Registration country and sponsor | France |
landingPageUrl, callToAction | Destination and button text | Shop now |
advertisingObjective | Published campaign objective | Conversions |
adEstimatedAudience | Target-audience range | 1M-2M |
targetingByLocation | Targeted regions | ["France"] |
targetingByAge, targetingByGender | Targeted ages and genders | ["18-24"] |
targetingLanguages | Targeted languages | ["French"] |
impressionsByRegion | Regional reach and demographic breakdowns | [] |
targetingDetails | Other disclosed targeting | null |
status, detailFetched | Availability and detail-read status | active, true |
Creator posts: other_commercial
Posts also carry id, country, adTitle and media fields.
| Field | Description | Example |
|---|---|---|
creatorUsername | Exact creator handle | creator.username |
brandNames | Disclosed brands | ["Example Brand"] |
contentLabel | Source's commercial-content label | Paid partnership |
postedAt | Publication time | 2026-10-01T12:00:00+00:00 |
videoViews, contentViews | Published view counts | 12500 |
Ranked creatives: top_ad
Top Ads also carry id, adTitle, country, media and landing-page fields when available.
| Field | Description | Example |
|---|---|---|
brandName | Published brand label | Example Brand |
industryKey, objectiveKey | Industry and objective codes | 21101000000 |
ctr | Source's click-through metric | 0.12 |
cost | Source's cost metric, not Actor pricing | 2 |
likes, comments, shares | Creative engagement metrics | 120 |
keywordList | Creative keywords | ["shoes"] |
videoDuration | Source's duration value | 15 |
Search suggestions: suggestion
| Field | Description | Example |
|---|---|---|
id | Suggestion identifier | suggestion:ad_keyword:shoes |
kind | adv_name or ad_keyword | ad_keyword |
value | Suggested text | shoes |
suggestionIds | Associated identifiers, if supplied | 123456789 |
Country reports: report
| Field | Description | Example |
|---|---|---|
id | Metric identifier | report:total_ads |
country | Market requested | FR |
metric | Metric name supplied by TikTok | total_ads |
value | Number, object or list supplied for that metric | 1234 |
Report metric names are source-defined, not a fixed catalog. Lists are capped at 50 entries. Large breakdowns can be trimmed, with rowTruncated marking affected rows.
How to scrape TikTok
- Open TikTok Ads Scraper in Apify Console.
- Choose
contentType, a supportedcountry, and the target described below. - Set
maxItemsto3for a small first run. - Click Start and wait for completion.
- Open the dataset and download rows, or read them through the API.
An empty input runs the form's example: shopify in France, with details enabled and at most 3 rows. Normal pricing applies. Filling query, advertiserName or adIds is enough for an ad search; a creator username alone does not switch to commercial posts.
Ads and direct IDs
Use query or advertiserName for ads. Advertiser name takes precedence over keyword. adIds reads specific Library ads and replaces text searches; IDs cannot be combined with other_commercial.
Commercial posts
Select other_commercial and enter creatorUsername. A username, @username or profile link is accepted. Clear the keyword and username to request the newest posts in the chosen country.
Combined ads and posts
Select both, enter an ad keyword or advertiser and a creator username. The two row types share maxItems; it is not a separate allowance for each type.
Top Ads
Select top_ads, a market such as US, and a 7- or 30-day period. A keyword is optional and filters the ranking; it is not a comprehensive keyword search across all TikTok ads.
Suggestions
Select suggestion and supply query or advertiserName. Results are suggested text, not ad details.
Country reports
Select reports and a Library country. Search terms are not used. Each returned metric is one row.
What to fill in
| Field | What to enter | Default |
|---|---|---|
query | Ad keyword or suggestion seed | Empty; example uses shopify |
advertiserName | Advertiser search text | Empty |
adIds | Numeric Library IDs or detail links | Empty |
creatorUsername | Exact creator handle or profile link | Empty |
country | Supported two-letter market code | FR |
contentType | ads, other_commercial, both, top_ads, suggestion, reports | ads |
period | Top Ads ranking window: "7" or "30" | "7" |
industryKey | Top Ads industry ID, such as 21101000000 or label_21101000000 | Empty |
objective | Top Ads objective ID or label, such as campaign_objective_conversion | Empty |
patternLabel | Top Ads pattern-label ID | Empty |
startDate | Library window start, YYYY-MM-DD | 30 days before the end |
endDate | Library window end, YYYY-MM-DD | Today |
includeDetails | Add available ad details | true |
maxItems | Row limit per input, from 1 to 500 | 70; example 3 |
cursor | Exact earlier RUN_SUMMARY.nextCursor object | Empty |
Ads:
{"query":"shopify","country":"FR","includeDetails":false,"maxItems":3}
Direct IDs:
{"adIds":["1877939373541554"],"country":"FR","maxItems":1}
Commercial posts — replace the placeholder handle:
{"contentType":"other_commercial","creatorUsername":"creator.username","country":"FR","maxItems":3}
Combined search:
{"contentType":"both","query":"shopify","creatorUsername":"creator.username","country":"FR","maxItems":4}
Top Ads:
{"contentType":"top_ads","country":"US","period":"7","maxItems":3}
Suggestions:
{"contentType":"suggestion","query":"shoes","country":"FR","maxItems":3}
Reports:
{"contentType":"reports","country":"FR","maxItems":3}
maxResults and limit are aliases for maxItems. Unknown fields are corrected when a close match is available and the intended field is empty; otherwise they are ignored with a note. Each run writes input-resolution information to INPUT_REPORT in its default key-value store. INPUT_ECHO records the interpreted search settings.
Unusable input stops before row charges. Input-resolution errors use INVALID_INPUT: <field> — <how to fix>; additional checks can instead name the field directly. Check the message rather than assuming every error has the prefix. Some invalid filters, such as an unsupported Top Ads period, are ignored with a note.
Output example
Illustrative Library ad row, shortened to the main fields:
{"rowType": "ad","id": "1877939373541554","adId": "1877939373541554","country": "FR","contentType": "ads","adTitle": "Discover our spring collection","adType": "VIDEO","advertiserName": "Example Brand","adStartDate": "2026-10-01","adEndDate": "2026-10-15","adImpressions": "100K-200K","adVideoUrl": "https://example.com/ad.mp4","landingPageUrl": null,"targetingByLocation": [],"detailFetched": false,"status": "active"}
Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. RUN_SUMMARY contains delivered counts, warnings and any continuation cursor; failures write ERROR_SUMMARY.
Why use this TikTok scraper?
- Pay per delivered row. Detail enrichment does not create another billed row.
- Keep partial answers. A returned partial answer can deliver usable rows with warnings. Rows already written remain available after a stop; rows not yet delivered are not guaranteed.
- Distinguish empty results from failures. A completed search with no matches can succeed with zero rows; an incomplete search with no rows fails with a reason.
- Keep missing values honest. Undisclosed fields stay empty rather than being inferred.
- Read multiple known ads. Submit several
adIdsin one run. - Avoid setup work. No TikTok login is required. You do not need to set up proxies.
How much does it cost to scrape TikTok?
Pricing is pay-per-event. At the default 512 MB memory, the run start costs $0.005: start events have a one-event minimum, with one event per GB. Platform usage is included in these prices.
| Apify plan | Start at 512 MB | Price per row | Price per 1,000 rows |
|---|---|---|---|
| Free | $0.005 | $0.0015 | $1.50 |
| Starter | $0.005 | $0.0015 | $1.50 |
| Scale | $0.005 | $0.0015 | $1.50 |
| Business | $0.005 | $0.0015 | $1.50 |
maxItems defaults to 70 per input. A keyword, advertiser, creator or combined search is one input; each direct ad ID is a separate input. Larger searches continue through available results, up to the requested limit. The allowance is a ceiling, not a guarantee of that many matches.
Free-plan access has a 10-run trial and a separate total-row allowance. Check RUN_SUMMARY.freeTierMaxResults for the allowance reported for the run. The whole run is also bounded by Maximum cost per run (maxTotalChargeUsd in the API).
Example: one search delivering 10 rows costs 10 × $0.0015 + $0.005 = $0.020 at 512 MB. Suggestions and reports use the same row charge. A run with no delivered rows has no row charge, but the start fee still applies.
What happens when the run timeout is too short
Some searches, such as both with a large maxItems or many adIds with includeDetails on, can take longer than the run timeout you chose. In that case the run does not fail. It ends early with the status message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." and shows as ABORTED for a while.
When the results are ready, the same run starts again by itself, reports "Resumed: delivering N rows.", writes the rows to the same dataset and finishes as SUCCEEDED. Rows that were already delivered are skipped, so no row is delivered or charged twice. You do not need to start another run.
- This can happen at most 3 times per run. To avoid it, keep the default timeout of 3600 seconds.
- The synchronous API endpoints (
run-sync,run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For larger jobs, start the run asynchronously and read the dataset after the run reaches SUCCEEDED, or use a webhook on the "succeeded" event.
Use with AI agents and the API
Apify MCP server
Add this remote server to Claude, ChatGPT, Cursor, VS Code or another compatible MCP client:
https://mcp.apify.com?tools=lentic_clockss/tiktok-ads-top-ads-actor
Sign in with Apify using OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool returns run and dataset IDs; read rows with get-dataset-items. Clients without remote support can use npx @apify/actors-mcp-server --tools lentic_clockss/tiktok-ads-top-ads-actor with APIFY_TOKEN set.
Example prompt: “Find 3 TikTok ads for shopify in France, without details, and show their captions and reach.”
Apify API
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/tiktok-ads-top-ads-actor").call(run_input={"query": "shopify", "country": "FR", "maxItems": 3})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/tiktok-ads-top-ads-actor').call({query: 'shopify', country: 'FR', maxItems: 3});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
For HTTP, send the input JSON to POST https://api.apify.com/v2/acts/lentic_clockss~tiktok-ads-top-ads-actor/runs with the bearer-token header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.
Integrations
Use the Actor's Integrations tab for Google Sheets, Make, Zapier, n8n, Slack, Airtable or webhooks. Use Apify Schedules for repeated searches.
FAQ
Is it legal to scrape TikTok?
The Actor reads public content. You are responsible for TikTok's terms and applicable data-protection law. Processing personal data requires a lawful basis; public visibility alone does not authorize every use.
Why did my run end as ABORTED?
The run was stopped. Check its status message and log for the reason; this is not evidence that the search had no matches. Rows already written remain available. Automatic continuation is not promised.
How many results can I get?
maxItems accepts 1–500 per input. Available matches, the run's spending limit and any free-plan allowance can reduce delivery. A direct ad ID identifies one ad, not hundreds of additional ads.
Why are some fields empty?
TikTok may omit them, details may be disabled, or the detail read may fail. detailFetched: false means those rows retain search-card data. Top Ads labels do not guarantee verified advertiser identity.
Which countries are covered?
Library modes cover the 27 EU countries, Iceland, Liechtenstein, Norway, Switzerland and the UK. Top Ads adds markets such as the US, Canada, Japan and Brazil. Select a country offered in the input form; availability varies.
Why does a keyword not find creator posts?
Commercial posts use exact creator usernames, not keyword search. Select other_commercial and fill creatorUsername, or clear both the username and ad search terms for newest posts.
How do I continue an earlier search?
When RUN_SUMMARY.nextCursor is non-null, paste it into cursor and keep the same search settings. A cursor is not guaranteed: completed searches have none, and a charge-limited delivery can withhold it to avoid skipping undelivered rows.
Does detail enrichment cost another row?
No. includeDetails enriches the existing ad row. Each distinct delivered ad, post, ranked creative, suggestion or report metric is one billed row.
Limitations
- Library coverage is regional; Top Ads is a selected ranking, not every campaign.
- Top Ads keyword filtering may stop before examining the entire ranking. Library searches offer no sorting input.
- Detail availability and targeting coverage are not guaranteed. Video URLs can expire.
- Phone numbers and emails remain empty. A landing page is not treated as a verified advertiser website.
- Nested lists are limited to 50 entries; long text and large breakdowns can be shortened.
- Date filters apply to Library searches; Top Ads uses
periodinstead.
Related scrapers
More ad library and ads intelligence scrapers from the same publisher:
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Report a problem or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.