# TikTok Ads Library Scraper - Ad Spy (`elliotpadfield/tiktok-ads-library-scraper`) Actor

Scrape TikTok Commercial Content Library ads by keyword, advertiser, business ID, country, date range, or ad URL. Extract creatives, video URLs, targeting, reach buckets, sponsors, and advertiser metadata.

- **URL**: https://apify.com/elliotpadfield/tiktok-ads-library-scraper.md
- **Developed by:** [Elliot Padfield](https://apify.com/elliotpadfield) (community)
- **Categories:** E-commerce, Lead generation, Social media
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.25 / 1,000 saved 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## TikTok Ads Library Scraper

Scrape TikTok Commercial Content Library ads by keyword, advertiser, advertiser business ID, country, date range, or direct ad URL. This Actor extracts structured TikTok ad data including advertiser names, business IDs, sponsors, registry locations, first and last shown dates, estimated audience buckets, creative image URLs, video URLs, and targeting metadata.

Use it to monitor competitor TikTok ads, collect winning ad creatives, research paid social hooks, audit advertising activity, track sponsor relationships, and export TikTok ad intelligence to CSV, JSON, Excel, Google Sheets, Make, Zapier, or your own API workflow.

### What can this TikTok Ads scraper do?

- Search TikTok ads by keyword or phrase
- Search by advertiser name
- Search exact advertisers by TikTok advertiser business ID
- Enrich direct TikTok Ad Library URLs or numeric ad IDs
- Filter by one or more country codes
- Pass TikTok date-range filters
- Sort by last shown date, first shown date, or audience size
- Post-filter by creative format, target region, and estimated audience bucket
- Use quick search mode when you only need search-card fields
- Fetch paginated search results from TikTok's public ad library API
- Fetch detail pages for sponsor, registry, targeting, and richer media fields
- Export structured ad data to Apify datasets
- Run on schedules for competitor ad monitoring
- Use Apify residential proxies on every run for production reliability

### What data can you extract from TikTok Commercial Content Library?

| Field | Description |
|---|---|
| `adId` | TikTok Commercial Content Library ad ID |
| `adUrl` | Direct TikTok Ad Library detail URL |
| `advertiserName` | Advertiser shown by TikTok |
| `advertiserBusinessId` | TikTok advertiser business ID from detail pages |
| `advertiserRegistryLocation` | Advertiser registry location when available |
| `sponsorName` | Sponsor or agency shown on the ad detail page |
| `firstShownAt` | First shown timestamp |
| `lastShownAt` | Last shown timestamp |
| `estimatedAudience` | TikTok estimated audience bucket |
| `estimatedAudienceLower` | Parsed lower bound of the audience bucket |
| `estimatedAudienceUpper` | Parsed upper bound of the audience bucket |
| `adFormat` | Video, Image, or Live Room when detectable |
| `imageUrls` | Creative image URLs |
| `videos` | Video URL and cover image URL pairs |
| `targetLocations` | Targeted countries and impression buckets |
| `targetAges` | Age targeting flags by region |
| `targetGenders` | Gender targeting flags by region |
| `targetAudienceSize` | Estimated targetable audience size |
| `daysActive` | Derived number of days between first and last shown dates |
| `resultPosition` | Position in search results |
| `countries` | Country filters used for the run |
| `scrapedAt` | Timestamp when the row was saved |

### How to scrape TikTok ads

1. Choose your search method: keywords, advertiser names, advertiser business IDs, or direct ad URLs.
2. Add one or more country codes such as `GB`, `DE`, `FR`, `NL`, `ES`, `IT`, or `CH`.
3. Set `dateFrom` and `dateTo` if you want a specific last-shown window.
4. Set `maxAds` and `maxPages` to control result size.
5. Keep `includeDetails` enabled if you want sponsor, registry, advertiser business ID, and targeting metadata.
6. Run the Actor and export the dataset in JSON, CSV, Excel, XML, RSS, or HTML from Apify.

### Input examples

#### Search competitor ads by keyword

```json
{
  "keywords": ["nike", "running shoes"],
  "countries": ["GB"],
  "maxAds": 100,
  "maxPages": 5,
  "adFormats": ["Video"],
  "includeDetails": true
}
````

#### Search by advertiser

```json
{
  "advertiserNames": ["NIKE Retail B.V.", "JD SPORTS FASHION PLC"],
  "countries": ["GB"],
  "dateFrom": "2026-04-27",
  "dateTo": "2026-05-27",
  "regionFilter": ["GB"],
  "minAudienceLower": 100000,
  "maxAds": 250,
  "includeDetails": true
}
```

#### Enrich specific TikTok ad URLs

```json
{
  "adUrls": [
    "https://library.tiktok.com/ads/detail/1850594343314561",
    "1850594317256754"
  ],
  "includeDetails": true
}
```

### Output example

```json
{
  "sourceType": "search",
  "query": "nike",
  "countries": ["GB"],
  "resultPosition": 4,
  "adId": "1850594343314561",
  "adUrl": "https://library.tiktok.com/ads/detail/1850594343314561",
  "advertiserName": "NIKE Retail B.V.",
  "advertiserBusinessId": "6876453864464188162",
  "advertiserRegistryLocation": "Netherlands",
  "sponsorName": "INITIATIVE MEDIA B.V.",
  "firstShownAt": "2025-12-05T00:00:00.000Z",
  "lastShownAt": "2026-05-26T00:00:00.000Z",
  "estimatedAudience": "400K-500K",
  "estimatedAudienceLower": 400000,
  "estimatedAudienceUpper": 500000,
  "adFormat": "Video",
  "videos": [
    {
      "videoUrl": "https://library.tiktok.com/api/v1/cdn/...",
      "coverImageUrl": "https://p16-common-sign.tiktokcdn.com/..."
    }
  ],
  "targetAudienceSize": "15.9M-19.5M",
  "daysActive": 173,
  "detailFetched": true,
  "scrapedAt": "2026-05-27T22:56:02.374Z"
}
```

### Search methods and filters

| Capability | Supported |
|---|---|
| Keyword search | Yes |
| Advertiser name search | Yes |
| Advertiser business ID search | Yes |
| Direct ad URL enrichment | Yes |
| Numeric ad ID enrichment | Yes |
| Country filters | Yes |
| Date range filters | Yes |
| Ad type filter | Yes |
| Sort order | Yes |
| Creative format post-filter | Yes |
| Target region post-filter | Yes |
| Audience bucket post-filter | Yes |
| Quick search mode | Yes |
| Search pagination | Yes |
| Full detail-page enrichment | Yes |
| Video creative URLs | Yes |
| Image creative URLs | Yes |
| Sponsor and registry metadata | Yes |
| Targeting metadata | Yes |
| Forced Apify Residential Proxy | Yes |

### Pricing and cost expectations

This Actor is designed for pay-per-result pricing. A typical run can scrape the first 100 fully enriched TikTok ads for a keyword or advertiser in a few minutes. Detail enrichment makes one extra request per ad, so disabling `includeDetails` can make preview-only runs faster and cheaper.

The Actor always uses Apify residential proxies. For small tests, lower `maxAds` to 10 or 25. For scheduled monitoring, run daily with the same keyword or advertiser inputs and deduplicate by `adId` in your downstream workflow.

### Why use this Actor?

TikTok ad research is valuable for performance marketers, agencies, ecommerce teams, SaaS founders, and creative strategists who need to understand which hooks, offers, products, and creatives are currently active.

This scraper helps answer questions like:

- What TikTok ads are competitors running?
- Which advertisers and sponsors are active in a category?
- Which creatives are videos vs images?
- Which ads have broad or narrow estimated reach?
- Which audiences, ages, genders, and countries are being targeted?
- Which campaigns are still active or recently shown?

Because it runs on Apify, you also get scheduling, API access, datasets, webhooks, proxy rotation, and integrations without maintaining your own server.

# Actor input Schema

## `keywords` (type: `array`):

Search ad text and advertiser content by one or more words or phrases, such as competitor names, categories, products, or hooks.

## `queries` (type: `array`):

Alias for Keywords. Useful when triggering the Actor from API clients that use a generic queries field.

## `advertiserNames` (type: `array`):

Search by advertiser name as shown in TikTok Commercial Content Library.

## `advertiserBusinessIds` (type: `array`):

Search exact TikTok advertiser business IDs, such as IDs found in detail-page advertiser metadata.

## `adUrls` (type: `array`):

Paste TikTok Ad Library detail URLs or numeric ad IDs to enrich specific ads directly.

## `detailUrls` (type: `array`):

Alias for Direct Ad URLs or IDs. Kept for integration compatibility.

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

TikTok country codes to search. TikTok Commercial Content Library coverage is strongest for EEA, Switzerland, and the United Kingdom. Defaults to GB.

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

Optional start date for TikTok's last-shown date filter. Use YYYY-MM-DD.

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

Optional end date for TikTok's last-shown date filter. Use YYYY-MM-DD.

## `queryType` (type: `string`):

How TikTok should interpret keyword searches. Keyword is usually best for discovery; advertiser name is best for exact brand searches.

## `adType` (type: `string`):

TikTok ad type code. Use 1 for all ads, 2 for employment, 3 for housing, or 4 for credit if supported in the selected region.

## `sortOrder` (type: `string`):

Sort order passed to TikTok search.

## `quickSearch` (type: `boolean`):

Skip detail-page enrichment for faster preview runs. Disable this when using region targeting filters or when you need sponsor, registry, and targeting metadata.

## `adFormats` (type: `array`):

Optional post-filter for detected creative format.

## `regionFilter` (type: `array`):

Optional post-filter for target regions found on detail pages, such as GB, DE, FR, NL, ES, IT, or CH. Requires detail enrichment.

## `minAudienceLower` (type: `integer`):

Optional post-filter using the lower bound of TikTok's estimated audience bucket. Example: 100000 keeps ads with buckets starting at 100K or higher.

## `maxAudienceLower` (type: `integer`):

Optional post-filter using the lower bound of TikTok's estimated audience bucket. Example: 1000000 keeps ads with buckets starting at 1M or lower.

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

Maximum number of unique ads to save across all search sources and direct ad URLs.

## `maxPages` (type: `integer`):

Maximum pagination pages to fetch per search source. TikTok search pages normally contain 12 ads.

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

Fetch each TikTok ad detail page to get advertiser business ID, registry location, sponsor, targeting, and richer media metadata.

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

Number of ad detail pages to fetch in parallel.

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

Base delay in milliseconds between retry attempts after transient failures.

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

Number of retries for transient HTTP, timeout, or proxy failures.

## Actor input object example

```json
{
  "keywords": [
    "nike"
  ],
  "countries": [
    "GB"
  ],
  "dateFrom": "2026-04-27",
  "dateTo": "2026-05-27",
  "queryType": "keyword",
  "adType": "1",
  "sortOrder": "last_shown_date,desc",
  "quickSearch": false,
  "maxAds": 100,
  "maxPages": 5,
  "includeDetails": true,
  "maxConcurrency": 5,
  "requestDelayMs": 500,
  "maxRetries": 3
}
```

# Actor output Schema

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

TikTok Commercial Content Library ads with advertiser, creative, media, reach, sponsor, targeting, and detail metadata stored in the default dataset.

# 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 = {
    "keywords": [
        "nike"
    ],
    "countries": [
        "GB"
    ],
    "queryType": "keyword",
    "adType": "1",
    "sortOrder": "last_shown_date,desc",
    "quickSearch": false,
    "maxAds": 100,
    "maxPages": 5,
    "includeDetails": true,
    "maxConcurrency": 5,
    "requestDelayMs": 500,
    "maxRetries": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("elliotpadfield/tiktok-ads-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 = {
    "keywords": ["nike"],
    "countries": ["GB"],
    "queryType": "keyword",
    "adType": "1",
    "sortOrder": "last_shown_date,desc",
    "quickSearch": False,
    "maxAds": 100,
    "maxPages": 5,
    "includeDetails": True,
    "maxConcurrency": 5,
    "requestDelayMs": 500,
    "maxRetries": 3,
}

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

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "nike"
  ],
  "countries": [
    "GB"
  ],
  "queryType": "keyword",
  "adType": "1",
  "sortOrder": "last_shown_date,desc",
  "quickSearch": false,
  "maxAds": 100,
  "maxPages": 5,
  "includeDetails": true,
  "maxConcurrency": 5,
  "requestDelayMs": 500,
  "maxRetries": 3
}' |
apify call elliotpadfield/tiktok-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=elliotpadfield/tiktok-ads-library-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Ads Library Scraper - Ad Spy",
        "description": "Scrape TikTok Commercial Content Library ads by keyword, advertiser, business ID, country, date range, or ad URL. Extract creatives, video URLs, targeting, reach buckets, sponsors, and advertiser metadata.",
        "version": "1.0",
        "x-build-id": "jL5q8ggEUCRMCJwjb"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/elliotpadfield~tiktok-ads-library-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-elliotpadfield-tiktok-ads-library-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/elliotpadfield~tiktok-ads-library-scraper/runs": {
            "post": {
                "operationId": "runs-sync-elliotpadfield-tiktok-ads-library-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/elliotpadfield~tiktok-ads-library-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-elliotpadfield-tiktok-ads-library-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "keywords": {
                        "title": "Keywords",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Search ad text and advertiser content by one or more words or phrases, such as competitor names, categories, products, or hooks.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "nike"
                        ]
                    },
                    "queries": {
                        "title": "Quick Keyword Queries",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Alias for Keywords. Useful when triggering the Actor from API clients that use a generic queries field.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "advertiserNames": {
                        "title": "Advertiser Names",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Search by advertiser name as shown in TikTok Commercial Content Library.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "advertiserBusinessIds": {
                        "title": "Advertiser Business IDs",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Search exact TikTok advertiser business IDs, such as IDs found in detail-page advertiser metadata.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "adUrls": {
                        "title": "Direct Ad URLs or IDs",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Paste TikTok Ad Library detail URLs or numeric ad IDs to enrich specific ads directly.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "detailUrls": {
                        "title": "Direct Detail URLs",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Alias for Direct Ad URLs or IDs. Kept for integration compatibility.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "Countries",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "TikTok country codes to search. TikTok Commercial Content Library coverage is strongest for EEA, Switzerland, and the United Kingdom. Defaults to GB.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "GB"
                        ]
                    },
                    "dateFrom": {
                        "title": "Start Date",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "type": "string",
                        "description": "Optional start date for TikTok's last-shown date filter. Use YYYY-MM-DD."
                    },
                    "dateTo": {
                        "title": "End Date",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "type": "string",
                        "description": "Optional end date for TikTok's last-shown date filter. Use YYYY-MM-DD."
                    },
                    "queryType": {
                        "title": "Keyword Query Type",
                        "enum": [
                            "keyword",
                            "advertiserName",
                            "all"
                        ],
                        "type": "string",
                        "description": "How TikTok should interpret keyword searches. Keyword is usually best for discovery; advertiser name is best for exact brand searches.",
                        "default": "keyword"
                    },
                    "adType": {
                        "title": "Ad Type",
                        "enum": [
                            "1",
                            "2",
                            "3",
                            "4"
                        ],
                        "type": "string",
                        "description": "TikTok ad type code. Use 1 for all ads, 2 for employment, 3 for housing, or 4 for credit if supported in the selected region.",
                        "default": "1"
                    },
                    "sortOrder": {
                        "title": "Sort Order",
                        "enum": [
                            "last_shown_date,desc",
                            "last_shown_date,asc",
                            "first_shown_date,desc",
                            "first_shown_date,asc",
                            "audience_size,desc",
                            "audience_size,asc"
                        ],
                        "type": "string",
                        "description": "Sort order passed to TikTok search.",
                        "default": "last_shown_date,desc"
                    },
                    "quickSearch": {
                        "title": "Quick Search",
                        "type": "boolean",
                        "description": "Skip detail-page enrichment for faster preview runs. Disable this when using region targeting filters or when you need sponsor, registry, and targeting metadata.",
                        "default": false
                    },
                    "adFormats": {
                        "title": "Ad Formats",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional post-filter for detected creative format.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "regionFilter": {
                        "title": "Target Region Filter",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional post-filter for target regions found on detail pages, such as GB, DE, FR, NL, ES, IT, or CH. Requires detail enrichment.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "minAudienceLower": {
                        "title": "Minimum Audience Bucket",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Optional post-filter using the lower bound of TikTok's estimated audience bucket. Example: 100000 keeps ads with buckets starting at 100K or higher."
                    },
                    "maxAudienceLower": {
                        "title": "Maximum Audience Bucket",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Optional post-filter using the lower bound of TikTok's estimated audience bucket. Example: 1000000 keeps ads with buckets starting at 1M or lower."
                    },
                    "maxAds": {
                        "title": "Maximum Ads",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of unique ads to save across all search sources and direct ad URLs.",
                        "default": 100
                    },
                    "maxPages": {
                        "title": "Maximum Search Pages",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum pagination pages to fetch per search source. TikTok search pages normally contain 12 ads.",
                        "default": 5
                    },
                    "includeDetails": {
                        "title": "Include Full Ad Details",
                        "type": "boolean",
                        "description": "Fetch each TikTok ad detail page to get advertiser business ID, registry location, sponsor, targeting, and richer media metadata.",
                        "default": true
                    },
                    "maxConcurrency": {
                        "title": "Maximum Concurrency",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Number of ad detail pages to fetch in parallel.",
                        "default": 5
                    },
                    "requestDelayMs": {
                        "title": "Retry Delay",
                        "minimum": 0,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Base delay in milliseconds between retry attempts after transient failures.",
                        "default": 500
                    },
                    "maxRetries": {
                        "title": "Maximum Retries",
                        "minimum": 0,
                        "maximum": 8,
                        "type": "integer",
                        "description": "Number of retries for transient HTTP, timeout, or proxy failures.",
                        "default": 3
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
