# TikTok Search Scraper: Keyword Videos by Region, No Login (`stanvanrooy6/tiktok-search-scraper`) Actor

Scrape TikTok search results by keyword. One row per video with views, likes, comments, shares, creator stats, music and hashtags. Real country and language targeting, server-side sort and date filters. No login, no cookies, no API key. Pay per result.

- **URL**: https://apify.com/stanvanrooy6/tiktok-search-scraper.md
- **Developed by:** [Stan Van Rooy](https://apify.com/stanvanrooy6) (community)
- **Categories:** Social media, Videos
- **Stats:** 7 total users, 2 monthly users, 98.2% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 videos

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Search Scraper: Keyword Video Search by Region, No Login 🔍

The TikTok Search Scraper turns any **keyword search into a clean dataset of TikTok videos**: one row per video with caption, creator, play and like counts, music, hashtags and direct links. It runs with **no login, no cookies and no third-party API key**, and it lets you pick the **country and language** the search is run as, with **server-side sort and date filters**, just like the TikTok app.

Type a few keywords, pick a region, click Start, and download JSON, CSV or Excel, or pull the results straight from the Apify API.

### 🚀 How to search TikTok by keyword

1. Enter one or more keywords (one per line).
2. Choose the region (US, UK, Germany, France, Japan and 30 more) and optionally the app language.
3. Set how many videos you want per keyword and any sort or date filter.
4. Click **Start**.

That is it. No TikTok account, no browser extension, no proxy setup on your side.

### 📊 What data can you scrape from TikTok search?

**Per video**

- Video ID, canonical URL and share link
- Caption text, detected language, hashtags and mentioned accounts
- Publish time (ISO 8601 and Unix timestamp)
- Play, like, comment, share, save and repost counts
- Creator: handle, nickname, user ID, follower and following counts, total likes, verified flag, avatar
- Music: sound ID, title, artist, original sound flag, audio URL
- Duration, width, height, static and animated cover URLs, direct video URL
- Photo posts: image URLs
- Promoted flag and the country TikTok attributes the video to

Every row also carries the keyword it matched, its rank in the results, the region the search ran as and which sort or date slice surfaced it, so you can join and audit results in your own pipeline.

### 📥 Input

| Field | Type | Notes |
|---|---|---|
| `keywords` | array | Search queries, one per line. **Required.** |
| `region` | string | Country the search is run as. Default `US`. See supported regions below. |
| `language` | string | App language code such as `en`, `de`, `fr`, `ja`. Default `auto` (the region's main language). |
| `maxResults` | integer | Unique videos per keyword. Default `100`, `0` for everything TikTok will serve. |
| `sort` | string | `relevance` (default), `likes` (most liked) or `newest`. Applied server side. |
| `publishedWithin` | string | `all` (default), `day`, `week`, `month`, `3months`, `6months`. Applied server side. |
| `deepSearch` | boolean | Default `true`. After the main results end, also runs the other sort orders and narrower date windows and merges the unique videos. |
| `includeAds` | boolean | Default `false`. Keep videos TikTok marks as promoted. |

### 📤 Output

```json
{
  "video_id": "7629854397274639646",
  "url": "https://www.tiktok.com/@heysweetkay/video/7629854397274639646",
  "type": "video",
  "desc": "I reposted a classic, sue me #packmystanley #StanleyCup #amazonfinds",
  "create_time": "2026-04-17T22:12:13Z",
  "create_timestamp": 1776463933,
  "author": {
    "id": "7069110241456604206",
    "sec_uid": "MS4wLjABAAAA0foe...",
    "unique_id": "heysweetkay",
    "nickname": "heysweetkay",
    "follower_count": 303277,
    "following_count": 42,
    "total_favorited": 0,
    "video_count": 0,
    "verified": false,
    "avatar_url": "https://p16-common-sign.tiktokcdn-us.com/..."
  },
  "stats": {
    "play_count": 4346471,
    "digg_count": 186313,
    "comment_count": 602,
    "share_count": 10976,
    "collect_count": 12586,
    "repost_count": 0
  },
  "music": {
    "id": "7629854463947836191",
    "title": "original sound - heysweetkay",
    "author": "heysweetkay",
    "is_original": true,
    "play_url": "https://v19.tiktokcdn-us.com/..."
  },
  "hashtags": ["packmystanley", "StanleyCup", "amazonfinds"],
  "mentions": [],
  "duration_ms": 66202,
  "duration_s": 66.2,
  "width": 720,
  "height": 1280,
  "cover_url": "https://p16-common-sign.tiktokcdn-us.com/...",
  "dynamic_cover_url": "https://p16-common-sign.tiktokcdn-us.com/...",
  "play_url": "https://v16m.tiktokcdn-us.com/...",
  "download_url": null,
  "image_urls": [],
  "share_url": "https://www.tiktok.com/@heysweetkay/video/7629854397274639646?...",
  "is_ad": false,
  "language": "en",
  "region": "US",
  "search_region": "US",
  "keyword": "stanley cup",
  "rank": 1,
  "matched_by": "relevance:all",
  "platform": "tiktok"
}
```

#### Field descriptions

| Field | Description |
|---|---|
| `video_id`, `url`, `share_url` | TikTok video ID, canonical `/@user/video/<id>` URL and share link. |
| `type` | `video` or `photo` (image slideshow post). |
| `desc`, `language`, `hashtags`, `mentions` | Caption, detected caption language, hashtags without `#`, mentioned account IDs. |
| `create_time`, `create_timestamp` | Publish time, ISO 8601 UTC and Unix seconds. |
| `author` | Creator profile: `unique_id` is the handle, `sec_uid` the stable public ID, plus follower, following, total likes and video counts, verified flag and avatar. |
| `stats` | `play_count`, `digg_count` (likes), `comment_count`, `share_count`, `collect_count` (saves), `repost_count`. |
| `music` | Sound ID, title, artist, whether it is an original sound, audio URL. |
| `duration_ms`, `duration_s`, `width`, `height` | Video length and dimensions. |
| `cover_url`, `dynamic_cover_url`, `play_url`, `download_url` | Static cover, animated cover, direct MP4 (expires after a few hours), watermarked download link when TikTok exposes one. |
| `image_urls` | Image URLs for photo posts. |
| `is_ad` | True when TikTok marks the video as promoted (excluded by default). |
| `region` | Country TikTok attributes the video to. |
| `search_region`, `keyword`, `rank`, `matched_by` | Which search produced the row: region, keyword, 1-based position and the sort:window slice (for example `newest:month`). |

### ✨ Why this TikTok search scraper

- **No login, no cookies, no API key.** The scraper creates its own anonymous session for every run. You never hand over a TikTok account and there is no separate API subscription to buy.
- **Real region targeting.** Most TikTok search scrapers return whatever the proxy IP happens to see. This one runs the search as the TikTok app configured for your chosen country and language, which is what TikTok actually uses to rank results. In my tests, `berlin` searched as Germany returned 36 of 40 videos from German creators with German captions, versus 21 of 40 for the US default.
- **Server-side filters.** Sort by relevance, most liked or newest and restrict to the last day, week, month, 3 or 6 months, the same filters as the TikTok app. No client-side sorting of a random sample.
- **More results per keyword.** TikTok caps one search session at roughly 200 videos. Deep search runs the other sort orders and date windows for the same keyword and merges the unique videos, typically 250 to 300 per keyword.
- **Rich rows.** Full creator profile numbers, engagement counters, music and direct media URLs in every row.
- **Clean exports.** JSON, CSV or Excel from the Apify Console, or fetch results from the Apify API.
- **Pay per result.** From $0.25 per 1,000 videos, no monthly plan, volume discounts on higher plans.

### 💡 Use cases

- **Trend and hashtag research:** See which videos and creators rank for a topic in a given country right now.
- **Influencer discovery:** Find creators who rank for your niche, with follower counts and engagement in the same row.
- **Competitor and brand monitoring:** Track how often a brand or product appears in search and who is posting about it.
- **Content strategy:** Mine captions, hashtags and sounds that perform for a keyword.
- **Datasets for analysis and AI:** Build labeled video datasets per keyword and region for NLP, LLM or BI workflows.

### 🔌 TikTok search API alternative: run it from code

Every Apify Actor is also an API. If you need TikTok search results inside your own app or notebook and do not want to apply for TikTok's official Research API, call this scraper with the Apify client:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("stanvanrooy6/tiktok-search-scraper").call(run_input={
    "keywords": ["stanley cup", "air fryer recipes"],
    "region": "US",
    "maxResults": 200,
    "sort": "likes",
    "publishedWithin": "month",
})
for video in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(video["stats"]["play_count"], video["url"])
```

The same works from JavaScript, cURL or any HTTP client. See the **API** tab above for ready-made snippets and the dataset endpoints.

### 🌍 Supported regions

`US, GB, DE, FR, ES, IT, NL, BE, AT, CH, IE, PT, PL, SE, NO, DK, CA, MX, BR, AU, NZ, JP, KR, ID, PH, TH, VN, MY, SG, IN, AE, SA, TR, ZA, NG`

The region and language are sent to TikTok the way the app sends them, so results are localized server side. Set `language` explicitly if you want, for example, English captions ranked for a German audience.

### ⚠️ Limits and good to know

- TikTok serves roughly 200 videos per search session to anonymous clients. Deep search (on by default) adds the other sort orders and narrower date windows, which brings a typical keyword to 250 to 300 unique videos. Very niche keywords return fewer.
- TikTok returns partial matches for unusual queries, the same way the app does, so a nonsense keyword still returns videos.
- Direct video and audio URLs are signed by TikTok and expire after a few hours. Download what you need right after the run.
- Promoted videos are excluded by default. Set `includeAds` to keep them.
- Transient network errors are retried automatically and a blocked anonymous session is replaced by a fresh one, so long runs keep going.

### 💰 Pricing

This Actor uses **pay per event**, so there is no monthly subscription and you only pay for what you scrape.

- **Videos:** $0.25 per 1,000 videos on the Free and Starter plans, $0.22 on Scale and $0.20 on Business and above.
- **Run start:** $0.002 per GB of memory, under one cent for a default run.

Pulling 1,000 videos costs about $0.25, the same base rate as the cheapest keyword search scrapers on the Store and a fraction of the $3 to $4 per 1,000 charged by the big general TikTok scrapers, with region targeting and server-side filters those do not offer. New Apify accounts include monthly free usage credit, which is enough to try the scraper at no cost.

### 🎯 Example inputs

**Top 100 videos for two keywords in the US:**

```json
{
  "keywords": ["stanley cup", "air fryer recipes"],
  "region": "US",
  "maxResults": 100
}
```

**Everything TikTok will serve for a keyword, as seen in Germany:**

```json
{
  "keywords": ["rezepte"],
  "region": "DE",
  "maxResults": 0
}
```

**Most liked videos from the last week, fastest run:**

```json
{
  "keywords": ["taylor swift"],
  "region": "US",
  "sort": "likes",
  "publishedWithin": "week",
  "maxResults": 50,
  "deepSearch": false
}
```

### 🆚 How this compares to other TikTok search scrapers

| | This scraper | Typical keyword search scrapers | General TikTok scrapers |
|---|---|---|---|
| Region targeting | Server side, by country and app language | Depends on the proxy IP, often US only | Depends on the proxy IP |
| Sort and date filters | Applied by TikTok before ranking | Client-side sorting of the returned sample, if at all | Client-side |
| Results per keyword | 250 to 300 with deep search | 200 to 400 | Varies |
| Login, cookies, API key | None | None or a third-party key | None |
| Price per 1,000 videos | From $0.25 | $0.25 to $0.70 | $3 to $4 |

### ❓ FAQ

#### Do I need a TikTok account or login?

No. The scraper runs fully anonymous and cookie free. You never share credentials.

#### Do I need a third-party API key?

No. Everything runs inside the Actor. Some competing TikTok scrapers require you to bring a separate paid API key. This one does not.

#### Is there a free TikTok search scraper?

You can run this one for free within the monthly free usage credit that comes with every new Apify account. After that it is $0.25 per 1,000 videos (less on higher plans) with no subscription.

#### How many videos can I get per keyword?

Set `maxResults` to any number, or `0` for everything available. TikTok caps a search session at about 200 videos; with deep search a keyword typically returns 250 to 300 unique videos. See the limits section above.

#### Does region targeting really work?

Yes. The search is sent as the TikTok app configured for the chosen country and language, which TikTok uses for ranking. Compare the `region` and `language` fields of the rows across two runs to see the difference yourself.

#### What format can I export?

JSON, CSV and Excel from the Apify Console, or straight from the Apify API and dataset endpoints.

#### Is it legal to scrape TikTok search results?

The scraper only collects publicly visible data that any anonymous app user can see, and it does not log in or bypass access controls. Rows contain creator handles and names, so handle the data in line with GDPR, CCPA and your own use case. If you are unsure, consult a lawyer.

#### Can you add a field, a filter or a mode I need?

Yes. Open an issue on the Issues tab and describe what you need. Hashtag feeds and sound feeds are on the roadmap.

### 🤝 Feedback and feature requests

I actively maintain this Actor. Found a bug or need a field? Open an issue on the Issues tab.

### 🔗 Related TikTok scrapers

All four share the same no-login engine and output conventions.

- **[TikTok Shop Scraper](https://apify.com/stanvanrooy6/tiktok-shop-scraper)**: TikTok Shop reviews, star ratings and product data from any product URL, up to 25,000 reviews per product.
- **[TikTok Comments Scraper](https://apify.com/stanvanrooy6/tiktok-comments-scraper)**: export every comment and reply thread from any TikTok video, no login.
- **[TikTok Profile Scraper](https://apify.com/stanvanrooy6/tiktok-profile-scraper)**: follower counts, bio, links and the full post history of any TikTok user.

Typical workflow: find videos with the TikTok Search Scraper, pull the audience conversation with the TikTok Comments Scraper, profile the creators behind them with the TikTok Profile Scraper, and check what their TikTok Shop products are really rated with the TikTok Shop Scraper.

# Actor input Schema

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

Search queries, one per line. Each keyword is searched separately and every video row carries the keyword it matched.

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

Country whose TikTok results you want. The search is sent as the TikTok app configured for that country (region and app language), which is what decides the results server side. DE returns German creators and captions, JP Japanese ones, and so on.

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

Language code sent as the app language (for example en, de, fr, es, ja). auto picks the main language of the region. Affects which captions and creators rank.

## `maxResults` (type: `integer`):

Stop after this many unique videos per keyword. 0 means everything TikTok will serve (typically 200 to 300 per keyword with deep search on).

## `sort` (type: `string`):

Server-side sort of the search results, the same options as the TikTok app filter sheet.

## `publishedWithin` (type: `string`):

Server-side date filter: only videos posted inside this window.

## `deepSearch` (type: `boolean`):

TikTok caps one search session at about 200 videos. When on, the actor also runs the other sort orders and narrower date windows for the same keyword and merges the unique videos, which usually adds 30 to 50 percent more results. Turn off for the fastest run.

## `includeAds` (type: `boolean`):

Keep videos TikTok marks as ads. Off by default.

## `apiHost` (type: `string`):

Advanced: override the TikTok app API host.

## `proxyCountry` (type: `string`):

Advanced: country of the residential proxy when it should differ from the region.

## `deviceRegion` (type: `string`):

Advanced: register the anonymous device as this region instead of the search region.

## `proxyGroups` (type: `string`):

Advanced: comma separated Apify proxy groups, or none for no proxy.

## Actor input object example

```json
{
  "keywords": [
    "stanley cup",
    "air fryer recipes"
  ],
  "region": "US",
  "language": "auto",
  "maxResults": 100,
  "sort": "relevance",
  "publishedWithin": "all",
  "deepSearch": true,
  "includeAds": false
}
```

# Actor output Schema

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

One row per video from the keyword search (JSON). Use format=csv or format=xlsx for other exports.

## `videosCsv` (type: `string`):

The same rows as CSV.

# 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": [
        "stanley cup"
    ],
    "language": "auto",
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("stanvanrooy6/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": ["stanley cup"],
    "language": "auto",
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("stanvanrooy6/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 '{
  "keywords": [
    "stanley cup"
  ],
  "language": "auto",
  "maxResults": 100
}' |
apify call stanvanrooy6/tiktok-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stanvanrooy6/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/hhbXNd3EmsUYiRWPG/builds/7dmyqIOmVf3SoOjXS/openapi.json
