# TikTok Bulk Video Search (`spider_studio/tiktok-video-search`) Actor

Search public TikTok videos for multiple keywords concurrently with reusable device identities, proxy rotation, and bounded retries. Pay only for keyword searches that return videos.

- **URL**: https://apify.com/spider\_studio/tiktok-video-search.md
- **Developed by:** [NewLai](https://apify.com/spider_studio) (community)
- **Categories:** Automation, Videos, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.20 / 1,000 keyword searcheds

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?

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

### What does TikTok Video Search do?

**TikTok Video Search finds public TikTok videos for multiple keywords or phrases in one run** and returns the original structured records exposed by TikTok's mobile search response. It is useful as a lightweight TikTok search API alternative for research, discovery, and automation. The Actor runs on the Apify platform, so searches can be started from the Console, API, schedules, webhooks, or integrations without managing a long-running server. **You pay only for keyword searches that return at least one video.**

This Actor searches one result page per keyword and writes one Dataset record for each keyword. It does not log into [TikTok](https://www.tiktok.com/), access private accounts, or download video files.

### Why use TikTok Video Search?

- Discover public videos for content research, trend tracking, and campaign monitoring.
- Search up to 1,000 deduplicated keywords with bounded concurrency in one run.
- Receive structured TikTok video objects instead of parsing a browser page.
- Continue a search with the returned cursor and search ID.
- Reuse the same shared Upstash device pool as the TikTok Profile Scraper.
- Recover from temporary network, proxy, rate-limit, and upstream failures with bounded retries.
- Use Apify API access, scheduling, integrations, proxy rotation, run logs, and monitoring.

### What TikTok search data can the Actor extract?

| Field | Type | Description |
| --- | --- | --- |
| `keyword` | string | Normalized search phrase used for the run. |
| `success` | boolean | Whether the search completed successfully. |
| `items` | array | Public TikTok video records returned for this page. |
| `hasMore` | boolean | Whether TikTok reports another page. |
| `cursor` | number or string | Offset to use for the next page. |
| `searchId` | string | Search-session ID to pass to the next page. |
| `error` | string or null | Safe failure message after retries are exhausted. |

Each object in `items` is kept in TikTok's upstream format so downstream systems can use all available video, author, statistics, music, cover, and playback fields.

### How to search TikTok videos

1. Open the Actor's **Input** tab.
2. Add one or more entries to `keywords`, such as `AI tools` and `travel tips`.
3. Keep `offset` at `0` and `searchId` empty for the first page.
4. Choose a page size from 1 to 30 per keyword with `count`.
5. Start the run and open the **Dataset** result.
6. To request the next page, start another run containing only that keyword, set `offset` to its returned `cursor`, and set `searchId` to its returned `searchId`.

### How much does it cost to search TikTok?

The Actor uses pay-per-event pricing at **$0.0012 for each keyword that returns at least one public TikTok video**. Failed searches, invalid results, and searches that remain empty after all retries are written to the Dataset but are not charged. Retries do not create additional billable events. For example, 100 successful non-empty keyword searches cost $0.12. You can set a maximum cost per run in Apify to control spending; the Actor stops writing further result groups when that limit is reached.

### Input

See the Input tab for the full schema. A first-page request looks like this:

```json
{
  "keywords": ["AI tools", "travel tips", "easy recipes"],
  "offset": 0,
  "searchId": "",
  "count": 12
}
```

`keywords` is required and accepts 1 to 1,000 entries of 1 to 100 characters each. Entries are trimmed and exact duplicates are ignored while preserving input order. The other fields are optional and apply to every keyword. Pagination tokens belong to the keyword that produced them, so a non-empty `searchId` is accepted only when `keywords` contains one entry.

The deployed Actor expects the `upstashRedisRestUrl` and `upstashRedisRestToken` Apify secrets used by `profile-scraper`. The shared sorted-set key defaults to `tiktok:device`. Users starting an already configured Actor run do not need to submit Redis credentials in Actor input.

### Output

The default Dataset contains one record per unique keyword, in input order. A failed keyword does not discard successful results from other keywords. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
  "keyword": "AI tools",
  "success": true,
  "items": [
    {
      "aweme_id": "7420000000000000000",
      "desc": "Example public TikTok video",
      "author": { "unique_id": "example.creator" },
      "statistics": { "play_count": 12345 }
    }
  ],
  "hasMore": true,
  "cursor": 12,
  "searchId": "20260823000000000000000000000000",
  "error": null
}
```

When all failure retries for a keyword fail, the Actor still writes a predictable uncharged record with `success: false`, an empty `items` array, and a safe `error` message. Empty but otherwise valid TikTok responses are retried three times by default; if every attempt remains empty, the result is accepted as a legitimate successful search with zero items and is not charged. Deployers can set `TIKTOK_FAIL_ON_ERROR=true` if any failed keyword should also fail the Actor run after all records have been written.

### Retry and advanced options

Keywords run concurrently, limited by `TIKTOK_MAX_CONCURRENCY` (default 5, maximum 20). Network requests retry HTTP 408, 425, 429, and common 5xx responses with exponential backoff. If a complete keyword search fails or returns no videos, the Actor retries with a fresh HTTP session, a newly leased device, and a fresh Apify Proxy session when Apify Proxy is enabled. `TIKTOK_MAX_EMPTY_RESULT_RETRIES` controls empty-result retries and defaults to 3. A custom `TIKTOK_PROXY_URL` is reused as supplied, so a provider-specific sticky session ID remains sticky across retries. Device leases use an atomic Upstash Lua command, so concurrent searches and Actors do not select a cooling device. All retry counts, timeouts, and delays are bounded through the environment variables documented in `.env.example`.

For the lowest latency, request only the page size you need. Keep the default Residential Proxy unless a tested custom proxy is supplied by the Actor owner. Never place proxy or Upstash credentials in Actor input.

### Related TikTok Actors

- [TikTok Profile & Public Videos Scraper](https://apify.com/spider_studio/tiktok-profile-scraper) resolves public TikTok profiles and retrieves a paginated page of their public videos.
- [TikTok Video Downloader API - Direct Video URLs](https://apify.com/spider_studio/tiktok-video-resolver) converts TikTok video and short links into direct playback/download URLs and metadata.

### FAQ, disclaimers, and support

#### Does this Actor access private TikTok data?

No. It only requests public keyword-search results and does not require a TikTok user login.

#### Why did a search return a failure record?

TikTok may rate-limit requests, a proxy can become unavailable, or every shared device can still be cooling down. Check the run log, confirm the Upstash secrets and device pool are configured, and retry later. Set `TIKTOK_FAIL_ON_ERROR=true` in the Actor environment if an automation requires a failed run status.

Our Actors are ethical and do not intentionally extract private user data. Results can nevertheless contain public personal data selected by TikTok users. Personal data may be protected by the GDPR and other laws. Do not collect or use personal data without a legitimate reason; consult qualified legal counsel if unsure. Follow TikTok's terms and applicable laws. Use the Actor's Issues tab for bug reports or custom-solution requests, and use its API tab for programmatic access.

# Actor input Schema

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

Keywords or phrases to search for on TikTok. Duplicate entries are ignored.

## `offset` (type: `integer`):

Result offset. Use 0 for the first page and the returned cursor for the next page.

## `searchId` (type: `string`):

Search ID returned by a previous page. A non-empty value can only be used with one keyword.

## `count` (type: `integer`):

Number of public videos requested for each keyword.

## Actor input object example

```json
{
  "keywords": [
    "AI tools",
    "travel tips"
  ],
  "offset": 0,
  "searchId": "",
  "count": 12
}
```

# Actor output Schema

## `dataset` (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 = {
    "keywords": [
        "AI tools",
        "travel tips"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("spider_studio/tiktok-video-search").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": [
        "AI tools",
        "travel tips",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("spider_studio/tiktok-video-search").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 '{
  "keywords": [
    "AI tools",
    "travel tips"
  ]
}' |
apify call spider_studio/tiktok-video-search --silent --output-dataset

```

## MCP server setup

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

```

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/V06UTlYijver7KXFD/builds/9nfZiECPjcm8EholW/openapi.json
