TikTok Ads Scraper - Ad Library & Top Ads avatar

TikTok Ads Scraper - Ad Library & Top Ads

Pricing

from $1.50 / 1,000 results

Go to Apify Store
TikTok Ads Scraper - Ad Library & Top Ads

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

kane liu

Maintained by Community

Actor stats

1

Bookmarked

7

Total users

4

Monthly active users

6 hours ago

Last modified

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; rowType is ad.
  • Commercial posts: brand-disclosed posts; rowType is other_commercial.
  • Combined search: ads and creator posts share one search allowance.
  • Top Ads: ranked creatives; rowType is top_ad.
  • Suggestions: advertiser names or keywords; rowType is suggestion.
  • Reports: country-level metrics; rowType is report.

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

FieldDescriptionExample
id, adIdLibrary ad identifier1877939373541554
countryMarket searchedFR
adTitleCaption, not advertiser nameDiscover our spring collection
adTypeCreative formatVIDEO
adVideoUrl, adVideoCoverVideo and cover URLshttps://example.com/ad.mp4
adImageUrlsImage or carousel URLs[]
adStartDate, adEndDateFirst and last days shown2026-10-01
adImpressionsPublished reach range100K-200K
advertiserNameAdvertiser labelExample Brand
advertiserIdBusiness identifier, when available123456789
advertiserLocation, advertiserPaidForByRegistration country and sponsorFrance
landingPageUrl, callToActionDestination and button textShop now
advertisingObjectivePublished campaign objectiveConversions
adEstimatedAudienceTarget-audience range1M-2M
targetingByLocationTargeted regions["France"]
targetingByAge, targetingByGenderTargeted ages and genders["18-24"]
targetingLanguagesTargeted languages["French"]
impressionsByRegionRegional reach and demographic breakdowns[]
targetingDetailsOther disclosed targetingnull
status, detailFetchedAvailability and detail-read statusactive, true

Creator posts: other_commercial

Posts also carry id, country, adTitle and media fields.

FieldDescriptionExample
creatorUsernameExact creator handlecreator.username
brandNamesDisclosed brands["Example Brand"]
contentLabelSource's commercial-content labelPaid partnership
postedAtPublication time2026-10-01T12:00:00+00:00
videoViews, contentViewsPublished view counts12500

Ranked creatives: top_ad

Top Ads also carry id, adTitle, country, media and landing-page fields when available.

FieldDescriptionExample
brandNamePublished brand labelExample Brand
industryKey, objectiveKeyIndustry and objective codes21101000000
ctrSource's click-through metric0.12
costSource's cost metric, not Actor pricing2
likes, comments, sharesCreative engagement metrics120
keywordListCreative keywords["shoes"]
videoDurationSource's duration value15

Search suggestions: suggestion

FieldDescriptionExample
idSuggestion identifiersuggestion:ad_keyword:shoes
kindadv_name or ad_keywordad_keyword
valueSuggested textshoes
suggestionIdsAssociated identifiers, if supplied123456789

Country reports: report

FieldDescriptionExample
idMetric identifierreport:total_ads
countryMarket requestedFR
metricMetric name supplied by TikToktotal_ads
valueNumber, object or list supplied for that metric1234

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

  1. Open TikTok Ads Scraper in Apify Console.
  2. Choose contentType, a supported country, and the target described below.
  3. Set maxItems to 3 for a small first run.
  4. Click Start and wait for completion.
  5. 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

FieldWhat to enterDefault
queryAd keyword or suggestion seedEmpty; example uses shopify
advertiserNameAdvertiser search textEmpty
adIdsNumeric Library IDs or detail linksEmpty
creatorUsernameExact creator handle or profile linkEmpty
countrySupported two-letter market codeFR
contentTypeads, other_commercial, both, top_ads, suggestion, reportsads
periodTop Ads ranking window: "7" or "30""7"
industryKeyTop Ads industry ID, such as 21101000000 or label_21101000000Empty
objectiveTop Ads objective ID or label, such as campaign_objective_conversionEmpty
patternLabelTop Ads pattern-label IDEmpty
startDateLibrary window start, YYYY-MM-DD30 days before the end
endDateLibrary window end, YYYY-MM-DDToday
includeDetailsAdd available ad detailstrue
maxItemsRow limit per input, from 1 to 50070; example 3
cursorExact earlier RUN_SUMMARY.nextCursor objectEmpty

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 adIds in 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 planStart at 512 MBPrice per rowPrice 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 ApifyClient
client = 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

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.

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 period instead.

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.