# TikTok Search Scraper (Pay Per Result) (`xmolodtsov/tiktok-search-scraper`) Actor

Search TikTok by keyword and export videos with full metadata: views, likes, comments, shares, bookmarks, hashtags, channel stats with follower counts, music and direct CDN video URLs. Batch many keywords per run, zero duplicate posts, no video downloads. $0.15 per 1K posts.

- **URL**: https://apify.com/xmolodtsov/tiktok-search-scraper.md
- **Developed by:** [Yevhenii Molodtsov](https://apify.com/xmolodtsov) (community)
- **Categories:** Social media, Lead generation, Videos
- **Stats:** 7 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.15 / 1,000 tiktok posts

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 Search Scraper (Pay Per Result)

Search TikTok by keywords and get videos with full metadata — engagement metrics
(views, likes, comments, shares, bookmarks), channel info, music, subtitles, POI
and direct CDN video URLs. No video downloads: fast runs, small footprint.

### Input

```json
{
    "keywords": ["artificial intelligence"],
    "maxItems": 1000,
    "sortType": "RELEVANCE",
    "location": "US",
    "includeSearchKeywords": true
}
```

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `keywords` | array | — (required) | Search terms, each searched independently |
| `maxItems` | integer | 1000 | Global cap on output items |
| `maxItemsPerKeyword` | integer | — | Optional per-keyword cap |
| `sortType` | enum | `RELEVANCE` | `RELEVANCE`, `MOST_LIKED`, `DATE_POSTED` |
| `location` | string | `US` | ISO 3166-1 alpha-2 country code; results as seen from that region |
| `includeSearchKeywords` | boolean | `true` | Adds `keyword` + `inputSource` to each item |
| `proxyConfiguration` | object | Apify RESIDENTIAL | Proxy settings |

### Output

One dataset item per video, e.g.:

```json
{
    "inputSource": "artificial intelligence",
    "id": "7668211941134847250",
    "title": "…",
    "views": 116870,
    "likes": 3806,
    "comments": 43,
    "shares": 617,
    "bookmarks": 267,
    "hashtags": ["ai", "tech"],
    "channel": { "id": "…", "name": "…", "username": "…", "avatar": "…", "verified": true, "url": "…", "followers": 1606104, "following": 47, "videos": null, "likes": 0 },
    "uploadedAt": 1785402000,
    "uploadedAtFormatted": "2026-07-30T09:00:00.000Z",
    "video": { "width": 1080, "height": 1440, "ratio": "1080p", "duration": 36.1, "url": "https://…", "cover": "https://…", "thumbnail": "https://…" },
    "song": { "id": 7668211998743612000, "title": "…", "artist": "…", "album": null, "duration": 36, "cover": "https://…" },
    "subtitleInformation": null,
    "postPage": "https://www.tiktok.com/@user/video/7668211941134847250",
    "poi": null,
    "keyword": "artificial intelligence"
}
```

### Proxies (this is where the cost lives)

TikTok's search endpoint **blocks North-American exit IPs** (they return a zero-byte HTTP
200, indistinguishable from a bad request shape). It does *not* require residential IPs —
EU **datacenter** exits work fine. The actor therefore rotates exits over
`GB, DE, FR, NL, PL, ES, IT, SE` regardless of the `location` input (`location` is still
sent to TikTok as its `region` param; result sets are not strongly geo-partitioned).

The Actor ships with its own datacenter proxies — users do not supply any. Sources, in order:

1. `proxyConfiguration.proxyUrls` from input (explicit user override)
2. `PROXY_URL_TEMPLATE` env var — a literal `{country}` is substituted
3. `CUSTOM_PROXY_URL` / `OXYLABS_DC_PROXY_URL` env var — its `-country-XX` token is rewritten
4. Apify Proxy — **only** when input explicitly sets `useApifyProxy: true`

There is deliberately **no automatic fallback to Apify residential**. Residential costs
\~$10/GB against ~$0.50–1.50/GB for our own datacenter exits, so a silent failover would
multiply cost per 1k items ~6x ($0.014 → $0.088) and, at a low price point, quietly turn
every run into a loss. If the configured proxy breaks, the run fails loudly instead.

Apify's own datacenter proxies can't substitute: US-only on our plan, and measured 1/5
success against TikTok search.

### Limits worth knowing

- TikTok caps a single query string at **~200 unique results**. The actor widens coverage
  by searching surface variants of the keyword and by rotating exit countries — both are
  real keyword searches, so results stay on-topic. Expect **~200–420 items per keyword**.
- Expansion stops automatically once queries stop returning enough new items, because each
  extra query costs a full-size response whether or not its items are new.
- `sortType` is applied **client-side**: TikTok accepts `sort_type`/`publish_time` on this
  endpoint but ignores them.
- No post is ever written twice within a run, across keywords, variants and exits.

### Local development

```bash
npm install
apify run   # reads INPUT from storage/key_value_stores/default/INPUT.json
```

Statistics (throughput, proxy MB per 1k items) are stored in the `STATISTICS`
key of the run's key-value store.

# Actor input Schema

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

Keywords/terms to search on TikTok. Each keyword is searched independently and results are combined into one dataset.<br><br><strong>Tip:</strong> You can batch many keywords in a single run for maximum cost efficiency.

## `maxItems` (type: `integer`):

Maximum total number of videos on output (across all keywords).

## `maxItemsPerKeyword` (type: `integer`):

Optional cap of results per single keyword. If omitted, keywords share the global <code>maxItems</code> budget evenly.

## `sortType` (type: `string`):

Sort order for search results.

## `location` (type: `string`):

Retrieve results as seen from this region (ISO 3166-1 alpha-2 country code, e.g. <code>US</code>). Uses region-matched proxies.

## `includeSearchKeywords` (type: `boolean`):

If enabled, each result includes the <code>keyword</code> and <code>inputSource</code> fields with the search keyword that found it.

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

Leave empty — the Actor ships with its own proxies. Only set this if you want to route through your own.

## Actor input object example

```json
{
  "keywords": [
    "artificial intelligence"
  ],
  "maxItems": 100,
  "sortType": "RELEVANCE",
  "location": "US",
  "includeSearchKeywords": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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": [
        "artificial intelligence"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("xmolodtsov/tiktok-search-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": ["artificial intelligence"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("xmolodtsov/tiktok-search-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": [
    "artificial intelligence"
  ],
  "maxItems": 100
}' |
apify call xmolodtsov/tiktok-search-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/9ClZjZnyfJM6H05Uf/builds/B26RWCQo3qsEIMWJx/openapi.json
