# TikTok Top Ads Scraper 💰 $0.9/1K Creative Center Ads API (`memo23/tiktok-creative-center-scraper`) Actor

From $0.90/1K 💰 TikTok Creative Center Top Ads, hundreds per run: the actor reads every ranking, period, industry and objective you leave open until it hits your limit. CTR, likes, comments, shares, cost score, landing page, target countries, objective and video URLs up to 1080p. No login.

- **URL**: https://apify.com/memo23/tiktok-creative-center-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, E-commerce
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## TikTok Creative Center Scraper

Export the **Top Ads** board and the **trending hashtags** from the [TikTok Creative Center](https://ads.tiktok.com/business/creativecenter) as clean rows. Each top ad comes with its CTR, likes, comments, shares, spend score, campaign objective, industry, target countries, landing page and video URLs. No TikTok login, no browser, $0.90 per 1,000 results.

### Why use this scraper?

- **The numbers TikTok shows advertisers.** CTR with a benchmark tier, relative spend, likes, comments and shares for every ad on the board, in true ranking order.
- **Hundreds of ads per run.** TikTok shows 20 ads per board, so the actor reads board after board (other rankings, periods, industries and objectives you left open) and drops duplicates until it reaches your limit. A test run for the US saved 1,000 unique ads.
- **Seven rankings.** For You, CTR, 2-second play rate, 6-second play rate, conversion rate, likes and impressions.
- **Industry filters.** 21 top-level industries, each with its own Top Ads board, plus 267 sub-categories (for example Beauty & Personal Care > Skincare) to narrow a board down.
- **Video you can download.** Up to five renditions per ad (360p to 1080p), a cover image and the Creative Center link.
- **Two Creative Center tools in one run setup.** Switch `mode` to `trends` for the trending hashtags of any market.

### What it does

| Mode | Source | You get |
|---|---|---|
| `topAds` (default) | Creative Center Top Ads board | One row per ad: performance, objective, industry, targeting countries, landing page, video URLs |
| `trends` | Creative Center hashtag trends | One row per hashtag: rank, post count, views, popularity curve, top creators |

### How much data to expect

TikTok limits what the Creative Center shows without a login, and this actor does not log in:

- **Top Ads:** TikTok shows at most 20 ads per board, where a board is one ranking, period, top-level industry, objective and country. With `sweepBoards` on (the default), the actor keeps reading boards until it has `resultsLimit` unique ads. It starts with the board you picked, then the other rankings, then the industries and objectives you left open, then the other periods. Filters you set stay fixed, and each row says which board it came from. Measured for the US with full details: 300 ads from 80 boards in about 2 minutes, 1,000 ads from 129 boards in about 6.5 minutes. With `sweepBoards` off you get the one board you picked.
- **Sub-categories narrow, they do not add.** TikTok serves boards per top-level industry only. A sub-category keeps the matching ads from its parent industry's board, so it often returns a handful of ads, or none.
- **Trends:** the top 3 hashtags per country and period. Leave `country` empty to sweep all 27 supported markets in one run.

Keyword search on Top Ads is also login-only on TikTok. The `keyword` input filters the ads the actor fetched; it does not search TikTok's archive.

### Use cases

- **Creative research:** build a swipe file of the best-performing hooks in your industry and country.
- **CTR benchmarking:** compare your own ads against the board's click-through and play rates.
- **Competitor monitoring:** schedule a weekly run for your sub-category and watch which brands and formats enter the ranking.
- **Content planning:** pull trending hashtags per market before you brief creators.

### Input configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `topAds` | `topAds` or `trends` |
| `country` | string | `US` | Two-letter country code. Empty: no country filter (Top Ads) or a sweep of all 27 markets (Trends) |
| `industry` | string | `all` | Top-level industry filter, used by both modes |
| `period` | string | `30` | Top Ads ranking window in days: `7`, `30` or `180` |
| `orderBy` | string | `for_you` | Top Ads ranking: `for_you`, `ctr`, `play_2s_rate`, `play_6s_rate`, `cvr`, `like`, `impression` |
| `industryId` | string | empty | Top Ads industry including sub-categories; overrides `industry`. A sub-category filters its parent industry's board |
| `objective` | string | empty | Top Ads campaign objective (traffic, conversion, reach, app install, video views, lead generation, product sales, app promotion) |
| `adLanguage` | string | empty | Top Ads creative language, two letters (`en`, `es`, `de`) |
| `adFormat` | string | empty | `spark_ads` or `non_spark_ads` |
| `keyword` | string | empty | Keep only fetched ads whose title or brand contains this text |
| `minLikes` | integer | empty | Keep only fetched ads with at least this many likes |
| `extractDetails` | boolean | `true` | Fetch each ad's detail record (target countries, landing page, comments, shares, objectives) |
| `sweepBoards` | boolean | `true` | Top Ads: when one board holds fewer ads than `resultsLimit`, read more boards (other rankings, periods, industries and objectives you left open). Off: only the board you picked |
| `days` | string | `7` | Trends window in days: `7`, `30` or `120` |
| `isNewToTop100` | boolean | `false` | Trends: only hashtags that newly entered the Top 100 |
| `resultsLimit` | integer | `100` | Maximum rows saved per run, across all boards |
| `proxy` | object | empty | Leave empty; the actor uses its own residential proxy. Set it only to use your own proxies |

#### Example: top ads by CTR for one industry

```json
{
    "mode": "topAds",
    "country": "US",
    "period": "30",
    "orderBy": "ctr",
    "industryId": "14000000000",
    "extractDetails": true,
    "resultsLimit": 100
}
```

`14000000000` is Beauty & Personal Care. Use a sub-category id such as `14103000000` (Skincare) to keep only that part of the board. Leave `industryId` unset for all industries.

#### Example: trending hashtags in every market

```json
{
    "mode": "trends",
    "country": "",
    "days": "7",
    "resultsLimit": 100
}
```

### Output

#### Top Ads row (abridged)

```json
{
    "type": "top_ad",
    "adId": "7069234203623735297",
    "rank": 1,
    "adTitle": "Shop the viral serum everyone's talking about",
    "brandName": "medicube",
    "ctr": 1.84,
    "ctrTier": "high",
    "cost": 2,
    "likes": 40719,
    "comments": 212,
    "shares": 1183,
    "objectiveKey": "campaign_objective_conversion",
    "industryKey": "label_14103000000",
    "industryName": "Skincare",
    "countryCodes": ["US"],
    "landingPage": "https://…",
    "videoDuration": 27.5,
    "videoCover": "https://p16-….jpeg",
    "videoUrl720p": "https://v16m-….mp4",
    "videoUrl1080p": "https://v16m-….mp4",
    "videoUrlBest": "https://v16m-….mp4",
    "period": 30,
    "orderBy": "ctr",
    "countryCode": "US",
    "boardNumber": 1,
    "boardIndustry": "14000000000",
    "boardObjective": null,
    "creativeCenterUrl": "https://ads.tiktok.com/business/creativecenter/topads/7069234203623735297/pc/en",
    "detailFetched": true,
    "scrapedAt": "2026-10-10T06:00:00.000Z"
}
```

#### Trends row

```json
{
    "type": "hashtag_trend",
    "hashtagId": "7659867926865903649",
    "hashtagName": "marvelrivalss9",
    "rank": 1,
    "country": "US",
    "period": 7,
    "publishCount": 133653,
    "views": 37575559,
    "industryIds": ["25000000000"],
    "popularityCurve": [{ "timestamp": 1783382400, "value": 0 }, { "timestamp": 1783728000, "value": 100 }],
    "topCreators": [{ "creatorId": "0", "nickname": null, "avatarUrl": "https://p16-common-sign.tiktokcdn.com/..." }],
    "link": "https://ads.tiktok.com/business/creativecenter/hashtag/marvelrivalss9/pc/en?countryCode=US&period=7",
    "scrapedAt": "2026-10-10T06:00:00.000Z"
}
```

#### Key output fields

| Field | Description |
|---|---|
| `rank` | The ad's position on the board it came from, unaffected by the `keyword` and `minLikes` filters |
| `boardNumber`, `period`, `orderBy`, `boardIndustry`, `boardObjective` | The board the ad was read from. Board 1 is the one you picked; higher numbers come from the sweep |
| `ctr` / `ctrTier` | Click-through rate in percent, and a band (`low`, `average`, `high`, `exceptional`) the actor computes from fixed thresholds |
| `cost` | TikTok's relative spend score from 1 to 5. It is not a currency amount |
| `industryKey` / `industryName` | TikTok's industry code and its readable label, sub-categories included |
| `objectiveKey` | The campaign objective the advertiser chose |
| `countryCodes`, `landingPage`, `comments`, `shares`, `objectives` | Filled when `extractDetails` is on (one extra request per ad). Some ads have no landing page. When TikTok refuses a detail record, the row keeps its list-level fields and `detailFetched` is `false` |
| `keywordList` | Kept for compatibility. TikTok currently returns it empty on the public Creative Center |
| `videoUrl360p` to `videoUrl1080p`, `videoUrlBest` | Every rendition TikTok returns. The links are signed and expire within 24 to 48 hours, so download soon after the run |
| `publishCount` / `views` | Trends: posts using the hashtag and their total views |
| `popularityCurve` | Trends: popularity over time as `{ timestamp, value }`, where value is a 0 to 100 index |

### Pricing

Pay per event, no subscription:

| Event | Price |
|---|---|
| Actor start | $0.01 per GB of run memory, once per run |
| Result | $0.0009 per row ($0.90 per 1,000) |

100 top ads with full details cost about $0.10. Free Apify accounts can run it too, capped at 100 results per run.

### How it works

The actor calls the same data endpoints the Creative Center pages use, with the verification headers those pages compute, through a residential proxy. Nothing is rendered in a browser, so a run of 20 ads with details takes about 15 seconds. When TikTok asks it to slow down, the actor waits a few seconds and retries with fresh headers instead of dropping the ad.

### FAQ

**How many ads can one run return?**
As many as `resultsLimit`, up to what TikTok has for your filters. Each board holds at most 20 ads, and the actor reads more boards until it reaches the limit. A US run asking for 1,000 saved 1,000 unique ads. Narrow filters (one industry, one objective, a small country) leave fewer boards, so a run can end below the limit when every board has been read.

**Why do some rows have a different period or ranking than I asked for?**
They come from the sweep. Once the boards for your ranking and period are used up, the actor reads the other rankings and periods. Every row carries `period`, `orderBy` and `boardNumber`, so you can keep only board 1, or turn `sweepBoards` off.

**Can I search Top Ads by keyword or advertiser?**
Not on TikTok's side: that search needs a TikTok login. `keyword` and `minLikes` filter the ads the run fetched. If you need to look up what a specific brand is running, use the [TikTok Ads Library Scraper](https://apify.com/memo23/tiktok-ads-scraper-cheerio), which searches TikTok's Ad Library by advertiser.

**Which countries are covered?**
Top Ads covers the markets in the Creative Center's own country list (72 options in the input). Trends covers 27 markets.

**Do the video links last?**
No. TikTok signs them and they expire within 24 to 48 hours. Download the files you want to keep right after the run.

**Is `cost` the ad spend?**
No. It is TikTok's relative spend score from 1 to 5.

### Support

Found a bug or need a field added? Open an issue on the actor's [Issues tab](https://apify.com/memo23/tiktok-creative-center-scraper/issues) or write to <muhamed.didovic@gmail.com>.

### Additional services

Need a custom export, a scheduled feed for your industries, or this data through a private API? Email <muhamed.didovic@gmail.com>.

### Explore more scrapers

- [TikTok Ads Library Scraper](https://apify.com/memo23/tiktok-ads-scraper-cheerio): search TikTok's Ad Library by keyword or advertiser, with audience targeting
- [Facebook Ad Library Scraper](https://apify.com/memo23/facebook-ads-library-scraper-ppe): Meta ads with reach and transcripts
- [LinkedIn Ad Library Scraper](https://apify.com/memo23/linkedin-ads-scraper): LinkedIn ads with impressions and targeting
- [TikTok Hashtag Scraper](https://apify.com/memo23/tiktok-hashtag-scraper): every video under a hashtag, with stats

More at [memo23's Apify profile](https://apify.com/memo23).

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor through the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/tiktok-creative-center-scraper`).

**Purpose:** TikTok Creative Center data in two modes: `topAds` (best-performing ad creatives with performance metrics) and `trends` (trending hashtags per market).

**Minimal input:**

```json
{
  "mode": "topAds",
  "country": "US",
  "period": "30",
  "orderBy": "ctr",
  "resultsLimit": 20
}
```

**Output:** one row per item. Top Ads (`type: "top_ad"`): `adId`, `rank`, `adTitle`, `brandName`, `ctr`, `ctrTier`, `cost`, `likes`, `comments`, `shares`, `objectiveKey`, `industryKey`, `industryName`, `countryCodes`, `landingPage`, `videoDuration`, `videoCover`, `videoUrl360p` to `videoUrl1080p`, `videoUrlBest`, `period`, `orderBy`, `countryCode`, `boardNumber`, `boardIndustry`, `boardObjective`, `creativeCenterUrl`, `detailFetched`, `scrapedAt`. Trends (`type: "hashtag_trend"`): `hashtagId`, `hashtagName`, `rank`, `country`, `period`, `publishCount`, `views`, `industryIds`, `popularityCurve`, `topCreators`, `link`, `scrapedAt`.

**Behaviors an agent should know:**

- `mode` defaults to `topAds`. `adLibrary` is not supported here; use `memo23/tiktok-ads-scraper-cheerio` for the Ad Library.
- Top Ads reads boards of up to 20 ads each and, with `sweepBoards` on (default), keeps reading other rankings, periods, industries and objectives the caller left open until it has `resultsLimit` unique ads. Rows carry `boardNumber`, `period` and `orderBy`; board 1 is the requested one. A sub-category `industryId` only filters its parent industry's board and can return 0.
- `keyword` and `minLikes` filter fetched ads client-side; they do not search TikTok.
- Trends returns the top 3 hashtags per country and period; an empty `country` sweeps 27 markets.
- `cost` is a 1 to 5 score, not money, and not a ranking. Video URLs expire in 24 to 48 hours.
- Billed $0.0009 per result row plus a start fee of $0.01 per GB.

### ⚠️ Disclaimer

This actor reads only publicly available data from the TikTok Creative Center: no login, no authenticated endpoints and no private user data. You are responsible for using the output in line with TikTok's terms and the laws that apply to you. The actor is not affiliated with or endorsed by TikTok or ByteDance.

### SEO Keywords

tiktok creative center scraper, tiktok top ads scraper, tiktok creative center api, tiktok top ads api, tiktok ad spy tool, tiktok ads ctr benchmark, tiktok ad examples by industry, tiktok trending hashtags scraper, tiktok creative center export, tiktok ads swipe file, tiktok spark ads examples, tiktok ad inspiration data

# Actor input Schema

## `mode` (type: `string`):

<b>Top Ads</b> = the best-performing ad creatives from the TikTok Creative Center, ranked by CTR, likes, conversion rate or cost, with video URLs, landing pages, objectives and industries.<br><b>Trends</b> = trending hashtags from the Creative Center (rank, post counts, weekly trend).

## `country` (type: `string`):

Two-letter country code for the Creative Center ranking. With <i>All / unset</i>, Top Ads runs without a country filter and Trends sweeps every supported market. Example: US. Default: US.

## `industry` (type: `string`):

Restrict the ranking to one top-level industry, or pick <i>All</i>. Applies to both modes. For Top Ads you can go one level deeper with the sub-category filter below. Default: All.

## `period` (type: `string`):

Lookback window for the top-ads ranking: last 7, 30, or 180 days.

## `orderBy` (type: `string`):

How the top ads are ranked.

## `industryId` (type: `string`):

The Creative Center industry taxonomy: 21 top-level industries and their sub-categories (e.g. Beauty & Personal Care > Skincare). When set, it overrides the top-level Industry filter. TikTok serves a Top Ads board per top-level industry only, so a sub-category keeps the matching ads from its parent industry's board and can return few or none. Leave unset to use the top-level filter.

## `objective` (type: `string`):

Filter ads by their campaign objective. Leave empty for all.

## `adLanguage` (type: `string`):

Two-letter language code to filter creatives by language (e.g. en, es, de). Leave empty for all.

## `adFormat` (type: `string`):

Restrict to Spark Ads (ads promoted from an existing organic TikTok post) or Non-Spark Ads (standalone ad creatives). Leave empty for all.

## `keyword` (type: `string`):

Top Ads only. Keeps just the ads whose title or brand name contains this text. Applied by the actor to the fetched ranking — TikTok's public Creative Center API has no server-side keyword search, so this filters results rather than querying TikTok. Example: nike. Leave empty for no filter.

## `minLikes` (type: `integer`):

Top Ads only. Keeps just the ads with at least this many likes. Applied by the actor to the fetched ranking (TikTok's public API exposes no like-tier filter). Example: 1000. Leave empty for no filter.

## `extractDetails` (type: `boolean`):

Fetches each ad's detail endpoint for the complete field set (target country list, landing page, comments, shares, objectives). Off = faster, list-level fields only (CTR, cost, likes, video). Default: true.

## `sweepBoards` (type: `boolean`):

Top Ads only. TikTok shows at most 20 ads per board (one ranking, period, industry and objective). When Max results asks for more, the actor also reads the other rankings, periods, industries and objectives you left open, and skips ads it already saved. Filters you set stay fixed. Off = only the board you picked. Default: on.

## `days` (type: `string`):

Look-back period for trending hashtags.

## `isNewToTop100` (type: `boolean`):

If checked, only return hashtags that newly entered the Top 100 in the chosen window.

## `resultsLimit` (type: `integer`):

Most rows saved per run. Top Ads: one board holds up to 20 ads, so with "Read more boards" on the actor keeps reading other boards until it has this many unique ads. Trends: most hashtags saved. Free Apify accounts are capped at 100. Default: 100.

## `maxConcurrency` (type: `integer`):

Maximum number of parallel requests.

## `minConcurrency` (type: `integer`):

Minimum number of parallel requests.

## `maxRequestRetries` (type: `integer`):

How many times to retry a failed request before giving up.

## `proxy` (type: `object`):

Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies.

## Actor input object example

```json
{
  "mode": "topAds",
  "country": "US",
  "industry": "all",
  "period": "30",
  "orderBy": "for_you",
  "industryId": "",
  "objective": "",
  "adLanguage": "",
  "adFormat": "",
  "keyword": "",
  "extractDetails": true,
  "sweepBoards": true,
  "days": "7",
  "isNewToTop100": false,
  "resultsLimit": 100,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 8
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "topAds",
    "country": "US",
    "industry": "all",
    "days": "7"
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/tiktok-creative-center-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "topAds",
    "country": "US",
    "industry": "all",
    "days": "7",
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/tiktok-creative-center-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "topAds",
  "country": "US",
  "industry": "all",
  "days": "7"
}' |
apify call memo23/tiktok-creative-center-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/tiktok-creative-center-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/fk93i6Aufwv5YdENx/builds/m2Pvc6vhsagnTqP5E/openapi.json
