# TikTok Top Ads Scraper — Creative Center Ads & Metrics (`dottti/tiktok-ad-library`) Actor

Top-performing TikTok ads from TikTok Creative Center in 28 countries incl. Saudi Arabia and UAE: ad video, landing page, likes, comments, shares, CTR, industry and objective. New-ad alerts. EU Ad Library search experimental; blocked queries are free.

- **URL**: https://apify.com/dottti/tiktok-ad-library.md
- **Developed by:** [Dottti](https://apify.com/dottti) (community)
- **Security:** Limited permissions
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 ads

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 Top Ads Scraper — Creative Center Ads & Metrics

Get TikTok's top-performing ads as clean, flat rows. No TikTok login, no cookies, no API token.

- **TikTok Creative Center Top Ads** (default): TikTok's list of top-performing ads in 28 countries, including Saudi Arabia, the UAE, Turkey, the UK and the US. Each ad has CTR, likes, industry, campaign objective and video in five sizes, and on request the landing page, comments, shares and the countries it ran in.
- **TikTok Ad Library (experimental):** EU/UK ad search. On 28 October 2026 TikTok rejected these searches from Apify's servers. Blocked queries return a free status row and are never charged.

Field names match our Meta Ad Library actor (`adArchiveId`, `pageName`, `startDate`, `endDate`, `body`, `linkUrl`, `videoUrls`, `reachEstimate`, `searchCountry`, `sourceInput`), so you can put Facebook, Instagram and TikTok ads in one table.

### Who it is for

- Marketers and agencies who track what competitors run on TikTok.
- E-commerce and app teams who look for winning creatives, hooks and landing pages by country and industry.
- Researchers who study ads shown in Europe under the Digital Services Act.

### Input

- **Sources**: Ad Library, Creative Center, or both.
- **Search terms** (Ad Library): keywords or brand names. Put a term in double quotes for an exact phrase.
- **Advertisers** (Ad Library): a name (`Nike, Inc.`) or a TikTok business id (`6876449221579375362`). Names are matched with the Ad Library's own advertiser suggestions. The run summary shows the match and close alternatives.
- **Countries**: two-letter codes. Each term and advertiser runs once per country. A country a source does not cover gets a free status row.
- Ad Library filters: date range, active or inactive, media type (video, image, text).
- Creative Center filters: period (7, 30 or 180 days), industries, campaign objectives, ad language, Spark or non-Spark ads, and **Run every industry**.
- **Sort**: default, reach, last shown, newest (Ad Library), CTR, likes, 2s and 6s view rate, conversion rate (Creative Center).
- **Include ad details**: one extra request per ad for landing page, CTA and targeting. No extra charge.

Example: Nike ads in France and Germany, plus top beauty ads in Saudi Arabia and the UAE.

```json
{
    "sources": ["ad_library", "creative_center"],
    "advertisers": ["Nike, Inc."],
    "countries": ["FR", "DE", "SA", "AE"],
    "dateFrom": "90 days",
    "industries": ["Beauty & Personal Care"],
    "sortBy": "reach",
    "maxAds": 100
}
```

### Output example (real run, Creative Center, Saudi Arabia, objective traffic, with details)

```json
{
    "type": "ad",
    "platform": "tiktok",
    "source": "creative_center",
    "adArchiveId": "7687225898043850770",
    "adUrl": "https://ads.tiktok.com/business/creativecenter/topads/7687225898043850770/pc/en",
    "displayFormat": "VIDEO",
    "body": "ماعاد يحتاج احد ",
    "linkUrl": "https://pixconvey.store/?utm_source=tiktok&utm_medium=paid&utm_id=__CAMPAIGN_ID__&utm_campaign=__CAMPAIGN_NAME__",
    "videoUrls": ["https://v16m-default.tiktokcdn.com/ca131260a6b3cc37b1c3c7e1b0fc40cd/6a..."],
    "videoPreviewImageUrls": ["https://p16-common-sign.tiktokcdn.com/tos-alisg-p-0037/ogjujQzFVI4UIED..."],
    "videoDurationSec": 22.6,
    "targetedOrReachedCountries": ["SA"],
    "metrics": { "ctr": 0.8, "likes": 73, "comments": 2, "shares": 2, "costIndex": 0 },
    "industry": "Electric Scooters",
    "objective": "Traffic",
    "objectives": ["Traffic", "Reach"],
    "sourceType": "top_ads",
    "searchCountry": "SA",
    "detailFetched": true
}
```

Ad Library rows use the same fields and add `advertiserName`, `advertiserId` (business id), `startDate` and `endDate` (first and last shown), `reachEstimate` with `reachMin` and `reachMax` (unique users seen), `auditStatus`, and with details `ctaText`, `linkUrl`, `sponsor`, `advertiserLocation`, `targeting` and `targetingSummary`.

### Status rows and run summary

Every input ends with a clear result. Inputs that return nothing get a free status row (`type: "status"`) that says why: `no_results`, `no_new_ads`, `not_found` (advertiser name not found), `country_not_supported`, `not_supported`, `invalid_input`, `blocked` or `api_error`. Status rows are never charged. Each row has a link that opens the same search on TikTok.

The `RUN_SUMMARY` record in the key-value store lists every input and country with its status, the advertiser picked for each name, notes about filters, and the number of requests and bytes.

An ad found by two inputs for the same country is delivered and charged once.

### Only new ads (alerts)

Turn on **Only new ads** and schedule the actor. The first run delivers everything and saves a baseline. Later runs deliver only ads not seen before for each input, and the run summary counts new ads per advertiser. Use a different **Alert state name** for each watchlist. You pay only for new ads.

### How to schedule

In Apify Console, open the actor, save your input as a task, then add a schedule (for example every Monday at 08:00). Connect the task to email, Slack, Google Sheets or a webhook through Apify integrations.

### Pricing

$1.50 per 1,000 ads. Ad details are included at no extra charge. Platform usage is included in the price. Status rows are free. A run stops charging when it reaches your maximum cost per run.

### Limits

- The Ad Library covers only ads shown in the EU/EEA, Switzerland, the UK and Turkey. For Saudi Arabia, the UAE and other countries, use Creative Center.
- Creative Center shows logged-out visitors about 20 Top Ads per filter set (country, period, industry, objective, sort). Its keyword search and later pages need a TikTok login, so search terms and advertisers do not apply there. Use **Run every industry**, several objectives or several sorts to get more ads per country.
- Creative Center has no advertiser names for most ads and no first or last shown dates.
- TikTok serves Ad Library targeting details only for some requests. When TikTok refuses them, the ad is still delivered without targeting and the run summary says so.
- Video and image links are TikTok CDN links that expire after some hours or days. Download files you want to keep.

# Actor input Schema

## `sources` (type: `array`):

Creative Center Top Ads works without login in 28 countries. The EU Ad Library search is experimental: TikTok often rejects automated searches, and blocked queries are never charged.

## `searchTerms` (type: `array`):

Ad Library keywords or brand names, for example nike, skincare or "black friday" (double quotes = exact phrase). Creative Center keyword search needs a TikTok login, so terms do not apply there.

## `advertisers` (type: `array`):

Advertiser names (Nike, Inc.) or TikTok business ids (6876449221579375362). Names are matched with the Ad Library's own advertiser suggestions; the run summary shows the match and close alternatives. Creative Center has no advertiser filter.

## `countries` (type: `array`):

Two-letter codes. Each term and advertiser runs once per country. Ad 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 TR, or ALL. Creative Center: AR AU BR CA CO FR DE ID IT JP MY MX NL PK PH RO SA SG ZA KR ES SE TH TR AE GB US VN. A country a source does not cover gets a free status row.

## `dateFrom` (type: `string`):

Optional. Ads shown on or after this date: 2026-09-01 or a relative time such as 30 days. Default: one year ago.

## `dateTo` (type: `string`):

Optional. Ads shown on or before this date (2026-10-27). Default: today.

## `adStatus` (type: `string`):

Active, inactive or all ads.

## `mediaType` (type: `string`):

Only ads with this kind of creative.

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

Top Ads time window in days: 7, 30 or 180.

## `industries` (type: `array`):

Optional. Industry names or ids, for example Beauty & Personal Care, Financial Services, E-Commerce (Non-app), or 14000000000. Each industry runs as its own query.

## `expandIndustries` (type: `boolean`):

TikTok shows logged-out visitors 20 Top Ads per filter set. Turn this on to run all 21 main industries for each country (up to about 420 ads per country). Ignored when you list industries.

## `objectives` (type: `array`):

Optional. traffic, app_install, conversion, video_view, reach, lead_generation, product_sales or app_promotion. Each objective runs as its own query.

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

Optional. en, ar, es, fr, de, it, pt, nl, ro, vi, th, id, ms, ja, ko or zh-Hant.

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

Spark Ads are boosted organic posts; non-Spark ads are made in Ads Manager.

## `sortBy` (type: `string`):

Default = last shown date in the Ad Library and "For you" in Creative Center. Reach works in both. CTR, likes, 2s/6s view rate and CVR are Creative Center only; newest and last shown are Ad Library only. The other source then uses its default.

## `includeDetails` (type: `boolean`):

One extra request per ad. Creative Center: landing page, comments, shares, countries, keywords. Ad Library: CTA, landing page, advertiser details and targeting by country, age and gender, when TikTok serves the detail page. Slower; no extra charge.

## `maxAds` (type: `integer`):

Cap for each search term, advertiser or Top Ads query in each country. The Ad Library returns 12 ads per request, Creative Center 20.

## `onlyNew` (type: `boolean`):

Remembers the ads each input returned before and delivers only ads not seen yet. Schedule the actor to get new-ad alerts. The first run delivers everything and saves the baseline. You pay only for new ads.

## `stateName` (type: `string`):

Name of the saved state for Only new ads. Use a different name for each watchlist or schedule.

## `proxyConfiguration` (type: `object`):

Leave empty for the automatic ladder: no proxy first, then Apify datacenter, then residential only if TikTok refuses. Set a proxy here to force it.

## `autoProxyFallback` (type: `boolean`):

Move to a proxy when TikTok refuses direct requests.

## `allowResidentialFallback` (type: `boolean`):

Residential proxy uses more platform credit (included in the price). Turn off to stop at datacenter.

## `maxRetries` (type: `integer`):

Retries per request, each on a fresh session, when TikTok answers with an error or drops the connection.

## Actor input object example

```json
{
  "sources": [
    "creative_center"
  ],
  "countries": [
    "GB",
    "AE"
  ],
  "adStatus": "all",
  "mediaType": "all",
  "period": "30",
  "expandIndustries": false,
  "adFormat": "all",
  "sortBy": "default",
  "includeDetails": false,
  "maxAds": 20,
  "onlyNew": false,
  "stateName": "default",
  "autoProxyFallback": true,
  "allowResidentialFallback": true,
  "maxRetries": 4
}
```

# Actor output Schema

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

All rows. Filter by the type field.

## `runSummary` (type: `string`):

Status per input and country, matched advertisers, new ads per advertiser (alert mode), requests, bytes and proxy tier used.

# 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 = {
    "sources": [
        "creative_center"
    ],
    "countries": [
        "GB",
        "AE"
    ],
    "maxAds": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("dottti/tiktok-ad-library").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 = {
    "sources": ["creative_center"],
    "countries": [
        "GB",
        "AE",
    ],
    "maxAds": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("dottti/tiktok-ad-library").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 '{
  "sources": [
    "creative_center"
  ],
  "countries": [
    "GB",
    "AE"
  ],
  "maxAds": 20
}' |
apify call dottti/tiktok-ad-library --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dottti/tiktok-ad-library"
        }
    }
}
```

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/L5iQwwxlvfxs50ZRu/builds/EQxlkRbMZFD3raXmT/openapi.json
