# TikTok Search Scraper - Videos by Keyword (`s-r/tiktok-search-scraper`) Actor

Search TikTok by keyword and get every matching video as data: caption, author and follower count, views, likes, comments, shares, sound, hashtags and the media URLs.

- **URL**: https://apify.com/s-r/tiktok-search-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## TikTok Search Scraper

Search TikTok by keyword and get the results as data. One row per video, with
the caption, who posted it and how many followers they have, the view, like,
comment and share counts, the sound, the hashtags and the media URLs.

Give it as many search terms as you like, one per line. It searches each one
the way the site does and walks the results until it has what you asked for or
TikTok stops serving.

### Results are regional, and that is not a detail

TikTok returns different videos to different countries for the same words. A
search for a product term from the US and from the Netherlands returns two
almost entirely different sets, in two different languages. The **Country** and
**Language** inputs control this, and every row records which term produced it,
so a run across several markets stays sortable rather than silently mixed.

If you are researching one market, set both. If you are comparing markets, run
the same terms once per country and group by the country afterwards.

### What you get per video

- `description`, `created_at`, `url`, `video_id`
- `handle`, `nickname`, `author_id`, `author_verified`
- `follower_count`, `author_video_count`
- `play_count`, `like_count`, `comment_count`, `share_count`, `collect_count`
- `duration_seconds`, `width`, `height`, `cover_url`
- `play_url` and `download_url`, the site's two media addresses
- `music_title`, `music_author`, `music_id`
- `hashtags`, `is_ad`
- `search_term`, `search_page`, `position`

`follower_count` next to `play_count` is the pairing most people are after. A
video with 400,000 views from an account with 2,000 followers is a different
signal from the same view count on an account with two million, and both come
back on the same row so you never have to join them.

The two media addresses behave differently from ordinary links: they are
authorised by the session that produced them, so pasting one into a browser
returns an error. If you want files rather than statistics, use **TikTok Video
Downloader**, which fetches and hosts them for you.

### How many videos you can get

TikTok serves roughly **200 unique videos per keyword** and then stops. Asking
for more returns what exists rather than failing, and the run summary reports
how many came back. If you need more coverage on a topic, use more terms:
several related phrases return overlapping but distinct sets, and together they
go well past what any single phrase will give you.

Videos come back around 30 to a page, so a 60-video term is two page loads and
a 200-video term is about seven. A run of five terms at 60 each finishes in
well under a minute.

### Errors

A term that returns nothing becomes an entry in the `errors` record rather than
a silently missing set of rows:

| Code | Meaning |
|---|---|
| `bad_input` | No search terms supplied |
| `no_results` | The search ran and matched no videos |
| `refused` | TikTok declined to serve that page of results |
| `signer_unavailable` | The run could not prepare itself; rerun |

`no_results` and `refused` are deliberately different. A term nobody has posted
about and a request TikTok declined look identical if you only count rows, and
only one of them is worth rerunning.

### Run settings

The default memory of 2 GB is what this needs; it is not padding. Lower it and
runs may fail to start. Timeout defaults to an hour, which is far more than a
normal run takes.

### Related actors

For a specific account's videos rather than a keyword search, use **TikTok
Scraper - Profiles, Videos & Hashtags**. For the video files themselves, use
**TikTok Video Downloader**. For shop listings and prices, use **TikTok Shop
Scraper**, and for advertising, **TikTok Ads Library Scraper**.

# Actor input Schema

## `search` (type: `array`):

One per line. Exactly what you would type into TikTok's search box.

## `maxVideosPerKeyword` (type: `integer`):

TikTok serves roughly 200 unique videos per keyword before it stops, so asking for more returns what exists.

## `country` (type: `string`):

Two-letter country code. Results are regional, so this changes what comes back.

## `language` (type: `string`):

Two-letter language code for the search.

## Actor input object example

```json
{
  "search": [
    "lego botanicals",
    "air fryer recipe"
  ],
  "maxVideosPerKeyword": 60,
  "country": "us",
  "language": "en"
}
```

# Actor output Schema

## `videos` (type: `string`):

One row per video.

## `summary` (type: `string`):

Keywords searched and videos returned.

## `errors` (type: `string`):

Keywords that returned nothing, with the reason.

# 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 = {
    "search": [
        "lego botanicals"
    ],
    "country": "us",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/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 = {
    "search": ["lego botanicals"],
    "country": "us",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/tiktok-search-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 '{
  "search": [
    "lego botanicals"
  ],
  "country": "us",
  "language": "en"
}' |
apify call s-r/tiktok-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/tiktok-search-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/S3HU9qg6rFiNPFU3E/builds/zeraR8cBNyiZmg8qy/openapi.json
