# TikTok Ad Library Scraper - Ads, Creatives & Audience (`eiv/tiktok-ad-library-scraper`) Actor

Scrape the TikTok Ad Library by advertiser. Every ad a brand runs in a country, with the ad copy, the creative video and images, the dates it ran, and the estimated audience TikTok itself publishes. No login and no API key.

- **URL**: https://apify.com/eiv/tiktok-ad-library-scraper.md
- **Developed by:** [Eimantas V](https://apify.com/eiv) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 ad scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Ad Library Scraper

Every ad an advertiser has run on TikTok in a given country - not just the ones still
live - with the ad copy, the creative video and images, the dates it ran, and TikTok's
own estimated audience.

No login. No API key. No cookie of yours.

### What you get for every ad

| Field | Notes |
|---|---|
| `advertiserName` | The registered entity that paid for the ad, as TikTok spells it |
| `title` | The ad copy shown beneath the creative |
| `videoUrls` | Direct links to the creative video, **where TikTok publishes it** |
| `imageUrls` | The creative stills, or a video ad's cover frame |
| `creativeAvailable` | Whether TikTok published the creative at all. It withholds it for a large share of ads — measured at eight of twelve on one advertiser's first page — so this tells you an empty list is TikTok's choice rather than a failure |
| `firstShownAt`, `lastShownAt` | ISO 8601 |
| `estimatedAudience` | TikTok's own range, e.g. `0-1K`, `10K-100K` — it never publishes an exact number |
| `estimatedAudienceMin`, `estimatedAudienceMax` | The range parsed, so you can sort on it |
| `spend`, `impressions` | Where TikTok discloses them for that country and advertiser. Left **empty rather than zero** where it does not, because a spend of nothing and an audience of nobody would look like data and be false |
| `url` | The ad's own page in the library, so any row can be checked by hand |

Each advertiser also gets a summary row: `totalAdsReported` is TikTok's own count,
`adsFetched` is what this run collected, and `pagesFetched` is how many requests it took.
The first two together tell you your coverage.

### One name is often several advertisers

Searching `Nike` resolves against TikTok's own autocomplete and finds **five separately
registered entities** - `NIKE Retail B.V.`, `NIKE COM SRL`, `NIKELAB LTD` and others -
each advertising under its own business id. This Actor walks all of them and reports each
on its own row, rather than silently picking one and dropping the rest.

Four of those five turn out to run no ads in `GB` at all, and they come back as honest
zero rows rather than being quietly left out.

**Search by name, not by id.** The ad library matches on the advertiser's registered name
and offers no way to look one up from a business id, so a numeric entry is rejected with a
row explaining what to pass instead. Every ad this Actor returns is checked against the
name that was searched before it is written.

### Pick the right country

The ad library is a **per-country repository**. The same advertiser runs a different set
of ads in `GB` and `DE`, so the `region` you choose changes the answer rather than just
filtering it. Asking for a country an advertiser does not run in returns an honest zero.

### Example

```json
{
  "advertisers": ["Nike"],
  "region": "GB",
  "maxAdsPerAdvertiser": 50,
  "proxyConfig": { "useApifyProxy": true }
}
```

### How complete is it

TikTok serves 12 ads per request and this Actor follows the cursor to the end of the
advertiser's catalogue, carrying the cursor forward so no page is skipped or repeated.
Where an advertiser is served the same ad twice across pages, it is delivered once.

**By default you get every ad in your date range, not just the ones still running.** That
distinction is most of the library: measured on one advertiser in `GB` over a year,
**16,105 ads in total against 43 still running**. If you want only live ads, the *Which
ads* option does that - but it is a small fraction of what the advertiser has run.

Where a run stops early - your ad limit, your charge limit, or the run's time limit - the
summary row says which, rather than leaving you to infer it from a short dataset.

### Set an ad limit that matches the question

A large advertiser's full catalogue runs to tens of thousands of ads. *Max ads per
advertiser* is what keeps a run proportionate: leave it low to survey what a brand is
doing now, raise it when you need the archive. The summary row's `totalAdsReported` tells
you how much you did not take, so a capped run is never mistaken for a complete one.

# Actor input Schema

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

Advertiser names, one per line. Each is resolved against TikTok own autocomplete, so "nike" finds every separately-registered Nike entity that advertises and each one is walked and reported on its own row. Names only - the ad library cannot be searched by business id.

## `region` (type: `string`):

Two-letter country code. The ad library is a per-country repository, so the same advertiser has a different set of ads in GB and DE. Defaults to GB.

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

All ads the advertiser ran in your date range, or only the ones still running. Measured on one advertiser in GB over a year: all 16,105 ads, still running 43. Leave this on All unless you specifically want live ads only.

## `startDate` (type: `string`):

YYYY-MM-DD. The library keeps roughly a year, so earlier dates return nothing.

## `endDate` (type: `string`):

YYYY-MM-DD. Defaults to today.

## `maxAdsPerAdvertiser` (type: `integer`):

TikTok serves 12 ads per request and this Actor follows the cursor to the end. The default is kept modest so a first run finishes quickly, not because the Actor is limited to it.

## `maxTotalAds` (type: `integer`):

A ceiling across every advertiser in the run.

## `requestDelayMs` (type: `integer`):

Raise this if runs start being refused.

## `proxyConfig` (type: `object`):

Recommended. The ad library is served per country, so a proxy in the country you are asking about is the most reliable way to be served it.

## Actor input object example

```json
{
  "advertisers": [
    "Nike"
  ],
  "region": "GB",
  "adStatus": "all",
  "maxAdsPerAdvertiser": 50,
  "maxTotalAds": 2000,
  "requestDelayMs": 600,
  "proxyConfig": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `ads` (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 = {
    "advertisers": [
        "Nike"
    ],
    "proxyConfig": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("eiv/tiktok-ad-library-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 = {
    "advertisers": ["Nike"],
    "proxyConfig": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("eiv/tiktok-ad-library-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 '{
  "advertisers": [
    "Nike"
  ],
  "proxyConfig": {
    "useApifyProxy": true
  }
}' |
apify call eiv/tiktok-ad-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eiv/tiktok-ad-library-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/EXHzvKAtwBwNofoV5/builds/eHGcgtaeXJ4fjRL4z/openapi.json
