# TikTok Search Scraper (`maximedupre/tiktok-search-results-scraper`) Actor

Search public TikTok videos or creator profiles by keyword. Save captions, hashtags, engagement counts, profile details, media links, music, subtitles, and the first search value for each row.

- **URL**: https://apify.com/maximedupre/tiktok-search-results-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.10 / 1,000 videos

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 for videos and creators

For social media researchers, marketers, and content teams, this Actor searches TikTok's public video or creator results by keyword. It saves captions, hashtags, engagement counts, creator details, media links, music, subtitles, and the first search value for each row, so you can review public search data in a dataset without a TikTok login or source credential.

- Find public videos from a keyword with **[TikTok video search](https://apify.com/maximedupre/tiktok-search-results-scraper/examples/tiktok-video-search)**.
- Find public creator profiles from a keyword with **[TikTok creator search](https://apify.com/maximedupre/tiktok-search-results-scraper/examples/tiktok-creator-search)**.
- Explore public hashtag results with **[TikTok hashtag search](https://apify.com/maximedupre/tiktok-search-results-scraper/examples/tiktok-hashtag-search)**.
- Follow sounds found in video search with **[TikTok music search](https://apify.com/maximedupre/tiktok-search-results-scraper/examples/tiktok-music-search)**.
- Spot topic patterns in public search with **[TikTok trends](https://apify.com/maximedupre/tiktok-search-results-scraper/examples/tiktok-trends)**.

#### 📊 TikTok results you can save

The dataset has two row types. Video rows include the post, caption, hashtags, public engagement counts, creator details, media links, music, subtitles, and location data when TikTok supplies them. Creator rows include profile details, account flags, public counts, and the search rank. Each row keeps the keyword or expanded search value that first found it.

#### ▶️ Run a TikTok keyword search

Choose **Videos** or **Creators**, enter one or more keywords, and start the Actor. The list and search setup are shared across the target you choose. For a shorter run and less review work, set the matching result limit. Leave a work limit empty to return all available results until the source is exhausted.

For video searches, choose relevance, most-liked, or newest order. You can also search TikTok suggestions, hashtags, or sounds found in the first video results. If the same public source item appears again through another keyword or expansion, only its first saved match is kept and later matches are ignored.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `target` | string | Chooses `videos` for public video posts or `creators` for public creator profiles. Options for the other target are ignored. |
| `videoResultLimit` | integer | For Videos only, stops after this many video results for the run. Leave it empty to return all available results until the source is exhausted. |
| `videoSortOrder` | string | For Videos only, orders results by `relevance`, `mostLiked`, or `newest`. |
| `includeSuggestedSearches` | boolean | For Videos only, also searches TikTok suggestions for each keyword and records the value that first surfaces each saved video. |
| `includeHashtagExpansion` | boolean | For Videos only, also searches hashtags found in the initial video results. |
| `includeMusicExpansion` | boolean | For Videos only, also searches sounds found in the initial video results. |
| `creatorResultLimit` | integer | For Creators only, stops after this many creator profiles for each keyword. Leave it empty to return all available results until the source is exhausted. |
| `searchKeywords` | array of strings | One or more keywords used with one shared search setup for the selected target. |

Leave the selected work limit empty to return all available results until the source is exhausted. Set a limit when you want fewer rows to review.

**Example input**

This is the public input from a successful current-beta run using the default video setup.

```json
{
  "target": "videos",
  "videoResultLimit": 20,
  "videoSortOrder": "relevance",
  "includeSuggestedSearches": false,
  "includeHashtagExpansion": false,
  "includeMusicExpansion": false,
  "searchKeywords": [
    "cooking"
  ]
}
```

#### 🧾 Output

The run output includes a dataset URL and saves one of the two row shapes below. Optional fields appear when TikTok supplies them. Playback, cover, music, subtitle, and other media links remain source-hosted.

**Run output fields**

| Field | Type | What it does |
| --- | --- | --- |
| `datasetUrl` | string | URL for the saved search result rows. |

**Video result fields**

| Field | Type | What it does |
| --- | --- | --- |
| `resultType` | string | The row type, `video`. |
| `searchKeyword` | string | The keyword or expanded search value that first found this video. |
| `video` | object | Public details for the TikTok video. |
| `video.id` | string | Public TikTok video ID. |
| `video.caption` | string | Text in the video caption. |
| `video.hashtags` | array of strings | Hashtags shown with the video. |
| `video.publishedAt` | string | Time when the video was published. |
| `video.url` | string | Permanent public TikTok link for the video. |
| `video.engagement` | object | Public engagement totals for the video. |
| `video.engagement.views` | integer | Public view count. |
| `video.engagement.likes` | integer | Public like count. |
| `video.engagement.comments` | integer | Public comment count. |
| `video.engagement.shares` | integer | Public share count. |
| `video.engagement.bookmarks` | integer | Public bookmark count. |
| `video.creator` | object | Public identity and account totals for the video creator. |
| `video.creator.id` | string | Public TikTok ID for the creator. |
| `video.creator.username` | string | Creator username on TikTok. |
| `video.creator.displayName` | string | Creator display name on TikTok. |
| `video.creator.profileUrl` | string | Public TikTok profile link for the creator. |
| `video.creator.isVerified` | boolean | Whether TikTok marks the creator as verified. |
| `video.creator.followers` | integer | Public follower count for the creator. |
| `video.creator.following` | integer | Public account count that the creator follows. |
| `video.creator.likes` | integer | Public total likes on the creator account. |
| `video.creator.videoCount` | integer | Public number of videos on the creator account. |
| `video.media` | object | Video size, playback, and cover details. |
| `video.media.width` | integer | Video width in pixels. |
| `video.media.height` | integer | Video height in pixels. |
| `video.media.aspectRatio` | number | Video width divided by its height. |
| `video.media.durationSeconds` | number | Video duration in seconds. |
| `video.media.playbackUrl` | string | Source-hosted URL for playing the video. |
| `video.media.coverUrl` | string | Source-hosted cover or thumbnail image URL. |
| `video.music` | object | Sound details when the video has available music data. |
| `video.music.id` | string | Public TikTok ID for the sound. |
| `video.music.title` | string | Title of the sound. |
| `video.music.artist` | string | Artist listed for the sound. |
| `video.music.album` | string | Album listed for the sound. |
| `video.music.durationSeconds` | number | Sound duration in seconds. |
| `video.music.coverUrl` | string | Source-hosted cover image URL for the sound. |
| `video.subtitles` | array of objects | Caption tracks available for the video. |
| `video.subtitles[].language` | string | Language of the caption track. |
| `video.subtitles[].format` | string | File format of the caption track. |
| `video.subtitles[].url` | string | Source-hosted URL for the caption track. |
| `video.location` | object | Public location details when TikTok supplies them. |
| `video.location.id` | string | Public TikTok ID for the location. |
| `video.location.name` | string | Public name of the location. |
| `video.location.address` | string | Public address of the location. |
| `video.location.city` | string | Public city of the location. |
| `video.location.region` | string | Public region of the location. |
| `video.location.country` | string | Public country of the location. |

**Example video row**

This genuine row came from a successful current-beta video run. It includes music data; subtitle and location fields are optional and are not present in this row.

```json
{
  "resultType": "video",
  "searchKeyword": "cooking",
  "video": {
    "id": "7671401171554209044",
    "caption": "Amazing cooking spicy noodle hotdog - egg recipe  Amazing video ",
    "hashtags": [],
    "publishedAt": "2026-08-07T21:14:42.000Z",
    "url": "https://www.tiktok.com/@polins___angels/video/7671401171554209044",
    "engagement": {
      "views": 1800000,
      "likes": 120300,
      "comments": 902,
      "shares": 12500,
      "bookmarks": 6608
    },
    "creator": {
      "id": "7614403533082002440",
      "username": "polins___angels",
      "displayName": "Polin’s Angels",
      "profileUrl": "https://www.tiktok.com/@polins___angels",
      "isVerified": false,
      "followers": 967200,
      "following": 12,
      "likes": 8200000,
      "videoCount": 725
    },
    "media": {
      "width": 1024,
      "height": 576,
      "aspectRatio": 1.7777777777777777,
      "durationSeconds": 1224,
      "playbackUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/alisg/tos-alisg-pve-0037c001/oARhhBd2AleIvm1qMkcFEpydQBHfW062ngDTEZ/?a=1988&bti=ODszNWYuMDE6&&bt=1461&ft=aEeq8qT0mIoPD12sTlsI3wU.7BAbMeF~O5&mime_type=video_mp4&rc=Ozg1PDw0OWU7OTVoODlpZ0BpM3FnO2w5cnE3PDMzODczNEAtNGAuLzBeXzIxNDMvNV4wYSNnZnNqMmRjaG9hLS1kMWBzcw%3D%3D&expire=1787594894&l=202608221747501BDF24CE4D7AF2019D05&ply_type=2&policy=2&signature=d3f4c6a6eeab9439bc88220b4c0a891e&tk=tt_chain_token&btag=e000a8000",
      "coverUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-alisg-p-0037/og2ANwAyiAKBZq5nBYBMasSiEAaBsLUCPnIAE~tplv-tiktokx-origin.image?dr=9636&x-expires=1787590800&x-signature=QHXPATvaGhx4yPbPj1KRJxTWj90%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast8"
    },
    "music": {
      "id": "7671401487913749268",
      "title": "orijinal ses",
      "artist": "Polin’s Angels",
      "durationSeconds": 1224,
      "coverUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-alisg-avt-0068/871da9873d8f70638ace05ab59a884df~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=065fb6a0&x-expires=1787590800&x-signature=WkWvzHbKi8EL1wEv93KULICmgsI%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast8"
    }
  }
}
```

**Creator result fields**

| Field | Type | What it does |
| --- | --- | --- |
| `resultType` | string | The row type, `creator`. |
| `searchKeyword` | string | The keyword that found this creator profile. |
| `resultRank` | integer | Creator position returned for this search keyword. |
| `creator` | object | Public identity, profile, flags, and account totals for the creator. |
| `creator.id` | string | Public TikTok ID for the creator. |
| `creator.username` | string | Creator username on TikTok. |
| `creator.displayName` | string | Creator display name on TikTok. |
| `creator.profileUrl` | string | Public TikTok profile link for the creator. |
| `creator.bio` | string | Creator bio text. |
| `creator.websiteUrl` | string | Public website linked from the creator profile. |
| `creator.isVerified` | boolean | Whether TikTok marks the creator as verified. |
| `creator.isPrivate` | boolean | Whether TikTok marks the creator account as private. |
| `creator.isBusinessAccount` | boolean | Whether TikTok marks the creator account as a business account. |
| `creator.followers` | integer | Public follower count for the creator. |
| `creator.following` | integer | Public account count that the creator follows. |
| `creator.likes` | integer | Public total likes on the creator account. |
| `creator.videoCount` | integer | Public number of videos on the creator account. |

**Example creator row**

This genuine row came from a successful current-beta creator run.

```json
{
  "resultType": "creator",
  "searchKeyword": "recipes",
  "resultRank": 1,
  "creator": {
    "id": "6815201689773556741",
    "username": "toni.kr8s",
    "displayName": "Toni Kroos",
    "profileUrl": "https://www.tiktok.com/@toni.kr8s",
    "isVerified": true,
    "isPrivate": false,
    "isBusinessAccount": false,
    "bio": "Ex-Player @realmadrid \nMy foundation: www.tonikroos-stiftung.de",
    "followers": 14000000,
    "following": 70,
    "likes": 98200000,
    "videoCount": 371
  }
}
```

#### 💳 Pricing

Pricing uses pay-per-event. The buyer-facing **Video** event costs `$0.0001` for each public video saved to the dataset. Set the video result limit to control how many video rows a run can save. The Apify Pricing tab is the source of truth if the displayed price changes.

#### 🔌 Integrations

The run output includes `datasetUrl` for the saved search rows. Use that URL to bring the dataset into your Apify workflow. This guide shows how to connect Actors:

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens if a video matches more than one keyword?

The Actor keeps the first saved match for that public video. Later appearances through another keyword or expansion are ignored, and the row keeps the first search value.

##### Can I search videos and creators in one run?

No. Choose one target for a run. The keyword list and shared search setup apply to that target, and options for the other target are ignored.

##### What if TikTok shows fewer results than my limit?

The Actor returns the available results it can collect during the run. TikTok search is fuzzy and availability changes, so an exact count or complete coverage is not promised.

##### Can I use the video links after the run?

Video rows include permanent public TikTok post links. Playback and cover links come from TikTok, and signed media links may expire.

##### Do I need a TikTok login or API key?

No. The Actor searches TikTok's public surface without a buyer login or source credential.

##### What does an empty result limit do?

Leave the selected work limit empty to return all available results until the source is exhausted. Set a limit when you want fewer rows and a smaller review task.

### 📝 Changelog

**0.0: Initial release**

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~tiktok-search-results-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [TikTok Profile Mention Scraper](https://apify.com/maximedupre/tiktok-profile-mention-scraper) finds public videos that mention selected profile handles.
- [TikTok Hashtag Search Scraper](https://apify.com/maximedupre/tiktok-hashtag-search-scraper) finds public hashtag results and metrics from keywords, hashtags, or tag URLs.
- [TikTok Live Search Scraper](https://apify.com/maximedupre/tiktok-live-search-scraper) searches active TikTok LIVE rooms by keyword and exports room data.
- [TikTok Keywords Discovery Tool](https://apify.com/maximedupre/tiktok-keywords-discovery-tool) collects TikTok autocomplete suggestions before you build search terms.
- [Influencer Scraper](https://apify.com/maximedupre/influencer-scraper) finds public creator profiles across TikTok, Instagram, and YouTube.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `target` (type: `string`):

Choose what you want to find.

## `videoResultLimit` (type: `integer`):

For Videos only. Stop after this many video results for the run. Leave it empty to return all available results until the source is exhausted.

## `videoSortOrder` (type: `string`):

For Videos only. Choose how matching videos are ordered.

## `includeSuggestedSearches` (type: `boolean`):

For Videos only. Also search TikTok suggestions for each keyword and record the value that first surfaces each saved result.

## `includeHashtagExpansion` (type: `boolean`):

For Videos only. Also search hashtags found in the initial video results.

## `includeMusicExpansion` (type: `boolean`):

For Videos only. Also search sounds found in the initial video results.

## `creatorResultLimit` (type: `integer`):

For Creators only. Stop after this many creator profiles for each keyword. Leave it empty to return all available results until the source is exhausted.

## `searchKeywords` (type: `array`):

Enter one or more keywords. The same list and settings are used for the target you choose.

## Actor input object example

```json
{
  "target": "videos",
  "videoResultLimit": 20,
  "videoSortOrder": "relevance",
  "includeSuggestedSearches": false,
  "includeHashtagExpansion": false,
  "includeMusicExpansion": false,
  "searchKeywords": [
    "cooking"
  ]
}
```

# Actor output Schema

## `datasetUrl` (type: `string`):

URL for the saved search result rows.

# 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 = {
    "target": "videos",
    "videoResultLimit": 20,
    "searchKeywords": [
        "cooking"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/tiktok-search-results-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 = {
    "target": "videos",
    "videoResultLimit": 20,
    "searchKeywords": ["cooking"],
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/tiktok-search-results-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 '{
  "target": "videos",
  "videoResultLimit": 20,
  "searchKeywords": [
    "cooking"
  ]
}' |
apify call maximedupre/tiktok-search-results-scraper --silent --output-dataset

```

## MCP server setup

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