TikTok Search Scraper: Keywords, Hashtags, Creators
Pricing
from $0.20 / 1,000 tiktok posts
TikTok Search Scraper: Keywords, Hashtags, Creators
Scrape TikTok search results by keyword — pay only per result. Views, likes, comments, shares, bookmarks, channel stats, music, subtitles, direct video URLs as JSON. Output compatible with popular TikTok scrapers. No proxies or login needed. Works via API, schedules and integrations.
Pricing
from $0.20 / 1,000 tiktok posts
Rating
5.0
(1)
Developer
Yevhenii Molodtsov
Maintained by CommunityActor stats
3
Bookmarked
27K
Total users
362
Monthly active users
8 days ago
Last modified
Categories
Share
TikTok Search Scraper is a TikTok search API alternative for keyword and hashtag research. Give it a list of search keywords and it returns every matching TikTok video as structured data — views, likes, comments, shares and bookmarks, creator/channel stats, music, subtitles and direct video URLs — as JSON, CSV or Excel. An optional expansion mode harvests TikTok's search suggestions, hashtag feeds and sound feeds to discover roughly 10x more creators per keyword. No login, no cookies, no TikTok account and no proxy setup: you enter keywords, you pay per result.
Typical uses: social listening, trend and hashtag analysis, influencer and creator discovery, competitor research, and building TikTok datasets — from the Apify Console, the API, a schedule, or an AI agent over MCP.
What data does TikTok Search Scraper extract?
One dataset item per video, including:
- Engagement — views, likes, comments, shares, bookmarks
- Post — title/caption, hashtags, upload timestamp (raw + ISO), permanent post URL
- Channel — id, name, username, avatar, verified flag, follower/following counts, total videos and likes
- Video — width, height, ratio, duration, direct video URL, cover and thumbnail images
- Music — song id, title, artist, album, duration, cover art
- Extras — subtitle/caption tracks with URLs, POI (location) data, collab info, the keyword that found the video, and (in expansion mode) which pool surfaced it
A keyword's full first result set (~200 videos) arrives in a single request, so a run typically finishes in seconds. Every field is shown in the output example below.
How to scrape TikTok search results
In the Apify Console
- Open TikTok Search Scraper in Apify Store and click Try for free.
- Enter one or more Search Keywords — a topic, a brand, a hashtag term, a creator niche. Each keyword is searched independently and the results are combined into one dataset.
- Optionally set Maximum number of items (the form prefills 100), a Sort Type, or turn on Expansion Pools for creator discovery. Leave the proxy field empty — proxies are built in.
- Click Start. The run ends when every keyword is exhausted or
maxItemsis reached. - Open the Dataset tab and download the results as JSON, CSV, Excel, XML or RSS, or read them through the API.

The minimal input is a single keyword:
{ "keywords": ["ai tools"] }
A richer example:
{"keywords": ["artificial intelligence", "machine learning"],"maxItems": 1000,"sortType": "RELEVANCE","location": "US","includeSearchKeywords": true}
From the API or CLI
Synchronous run that returns the items directly:
curl -X POST "https://api.apify.com/v2/acts/xmolodtsov~tiktok-search-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"keywords": ["ai tools"], "maxItems": 200}'
With the Apify CLI:
$apify call xmolodtsov/tiktok-search-scraper --input '{"keywords": ["ai tools"], "maxItems": 200}'
How much does it cost to scrape TikTok?
This Actor is priced pay per result: you are charged only for items actually written to the dataset — not for compute time, not for retries, not for setup, and proxies are included. The price per result depends on your Apify plan:
| Apify plan | Price per 1,000 results |
|---|---|
| Free | $0.30 |
| Bronze | $0.25 |
| Silver | $0.22 |
| Gold | $0.20 |
| Platinum | $0.18 |
| Diamond | $0.15 |
Worked example: 5 keywords × ~200 videos each ≈ 1,000 results — $0.30 at the Free-plan rate, $0.25 on Bronze, $0.15 on Diamond. (A Free-plan run is capped at 10 results — see Free plan limits — so in practice it costs a fraction of a cent.)
Runs that return zero results, or fail, produce zero billable items and cost you nothing. Batching many keywords into one run is the most cost-efficient way to use the Actor.
Is scraping TikTok free?
You can try it for free. Apify's free plan includes a monthly free usage credit that can be spent on pay-per-result Actors like this one, with no payment method required. On the free plan, however, this Actor applies the developer-set limits described next (10 results per run, 5 runs per month). Any paid Apify plan removes them and lowers the price per result.
Free plan limits
On the Apify Free plan, this Actor is limited to:
- 10 results per run (
maxItemsis clamped to 10), and - 5 runs per calendar month (the counter resets on the 1st), and
- classic keyword search only — expansion pools are disabled, and
- Apify Proxy (residential) is used instead of the Actor's built-in proxy — its bandwidth is billed to your own Apify account at Apify's proxy rates (a 10-result run is well under 1 MB). Paid plans use the built-in proxy at no extra cost.
These limits are set by the developer, not by Apify. Every free-plan run is announced in the run log and status message, for example: "Free plan: run 1/5 this month, capped at 10 results (a limit set by the developer, not by Apify). Upgrade to any paid Apify plan for unlimited runs and results."
When the monthly quota is used up, the run ends successfully with an explanatory status message and no results — it does not fail, and produces no billable items.
Why? Pay-per-result revenue only counts for users on paid plans, so a free-plan run costs the developer real money (the built-in proxies) while earning nothing. Any paid Apify plan removes all of these limits — paid users are never limited, on any tier.
Input and output
Input parameters
| Field | Type | Default | Description |
|---|---|---|---|
keywords | array | — (required) | Search terms, each searched independently; results are combined into one dataset |
maxItems | integer | 1000 via API; the Console form prefills 100 | Global cap on output items across all keywords and expansion pools |
maxItemsPerKeyword | integer | — | Optional cap per single keyword; keywords are processed sequentially against the global maxItems budget |
sortType | enum | RELEVANCE | RELEVANCE, MOST_LIKED, DATE_POSTED. Sorting is applied after fetching, per keyword — TikTok ignores server-side sort parameters |
location | string | US | ISO 3166-1 alpha-2 country code, passed to TikTok as the region parameter. Cosmetic — TikTok keys results off the request's IP address, not off this parameter, so it does not produce a per-country result set |
includeSearchKeywords | boolean | true | Adds keyword + inputSource to each item |
expansion | array | [] (off) | Opt-in harvest pools: suggest, hashtag, music — see Expansion mode |
relevanceThreshold | number | 0.3 | Music pool only: fraction (0–1) of a sound's first-page captions that must match the keyword or its hashtags before that sound is crawled. Higher = stricter |
uniqueAuthors | boolean | false | Emit at most one item per creator (channel.id) |
maxPostsPerAuthor | integer | — | Cap on items per creator in the classic search results; the expansion pools always emit at most one item per creator regardless of this value (empty = no cap) |
proxyConfiguration | object | — (leave empty) | Not needed — proxies are built in and included in the price. Advanced users may route through their own proxy URLs or Apify Proxy |
Out-of-range values are clamped (item caps to 1–100,000, relevanceThreshold to 0–1);
an unknown sortType fails the run with a clear message.
Output example
{"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 },"collabInfo": null,"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"}

Field notes:
subtitleInformationisnullor an array of caption tracks, each withcaption_format,caption_length,lang,language_code,is_auto_generated,url,url_listandversion.poiisnullor an object withpoiName,address,cityCode,cityName,latitude,longitudeandregionCode.- Channel stats TikTok omits for a card are
null(e.g.channel.videos); engagement counters default to0. expansion_sourceappears only whenexpansionis set — see the next section.
Note:
keywordandinputSourceintentionally carry the same value — both exist for compatibility with pipelines built around the common TikTok scraper output format.
CDN links expire:
video.url,video.coverandvideo.thumbnailare signed, short-lived TikTok CDN links — download or process them promptly after the run.postPageis the permanent link to the video.
Drop-in compatible with the common TikTok scraper output format
The output schema follows the field layout popular TikTok search scrapers on Apify Store
already use — same field names, same nesting, same types (views, likes, channel.*,
video.*, song.*, subtitleInformation, poi, keyword/inputSource, …). Point
your existing pipelines, parsers and spreadsheets at this Actor unchanged.
Expansion mode and creator discovery
By default the Actor runs the classic keyword search. Set expansion to opt into extra
harvest pools, all seeded from the keyword's own search hits and run after the classic
search for that keyword:
suggest— TikTok's own search suggestions for your keyword; each suggestion is then run through the normal search (up to ~200 items per suggestion).hashtag— the feed of the keyword's own hashtag plus up to five of the tags that appear most on the keyword's search results.music— the feeds of up to five of the sounds those same results use most. Each sound is probed first: if fewer thanrelevanceThresholdof its first-page captions match the keyword or its hashtags, the sound is skipped as off-topic (trending sounds carry every niche).
The pools exist to widen creator coverage, so each pool emits only creators the run has not seen yet — one item per creator. Creators are deduplicated run-globally across every pool, so the pools stack instead of repeating each other (measured 85–95% disjoint). With all three on, a keyword surfaces roughly 10x more unique creators than plain search.
Each item gains an expansion_source field — relevance (classic search), suggest,
hashtag or music — naming the pool that first surfaced that creator. The keyword and
inputSource fields still carry the original input keyword, so attribution never
drifts to the suggestion, hashtag or sound that found the video.
Cost stays predictable: maxItems bounds the total across all pools, and a pool stops
for a keyword once two consecutive suggestions, tags or sounds yield fewer than five new
creators. A pool hiccup never costs the classic-search items already collected. For creator
discovery rather than post collection, set uniqueAuthors:
{"keywords": ["recipe"],"expansion": ["suggest", "hashtag", "music"],"uniqueAuthors": true,"maxItems": 2000}
Expansion pools are available on paid Apify plans; free-plan runs use classic search only.
Integrations, API and MCP
JavaScript and Python clients
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('xmolodtsov/tiktok-search-scraper').call({keywords: ['ai tools', 'fitness'],maxItems: 500,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClientclient = ApifyClient(token="YOUR_APIFY_TOKEN")run = client.actor("xmolodtsov/tiktok-search-scraper").call(run_input={"keywords": ["ai tools", "fitness"], "maxItems": 500},)items = client.dataset(run["defaultDatasetId"]).list_items().items
Schedules, webhooks and exports
The Actor works with all standard Apify platform features: schedules (e.g. daily keyword monitoring), webhooks (get notified when a run finishes), and dataset export to JSON, CSV, Excel, XML or RSS — plus integrations like Zapier, Make and Google Sheets.
Use with AI agents (MCP)
The Actor is available through Apify's MCP server at mcp.apify.com,
so AI agents and assistants that speak the Model Context Protocol — Claude, ChatGPT and
others — can call it by name, xmolodtsov/tiktok-search-scraper, pass the same input
described above, and read the dataset back. Pricing and free-plan limits apply as usual.
Monitoring runs
Every run writes a STATISTICS record to its key-value store with total items, request
and failed-request counts, duration and throughput (items/sec), a per-keyword breakdown
(with per-pool counts when expansion is on), and a failureReason token — ok when items
shipped, empty when TikTok answered with no posts, or a block/network token otherwise.
Handy for dashboards and alerting on scheduled runs.
Related actors
- TikTok Profile Scraper — scrape
TikTok profiles and their latest posts by handle. Pair the two: discover creators with
this Actor (
uniqueAuthors+ expansion), then feedchannel.usernameinto the profile scraper for full profile stats and each creator's recent videos. If you already know the handles, start there; this Actor is for finding videos and creators you do not know yet.
FAQ
Is it legal to scrape TikTok?
The Actor collects only publicly available data — the same information any logged-out visitor sees on TikTok search. It never logs in, never accesses private accounts, and collects no data behind authentication. You are responsible for how you use the data: respect TikTok's terms of service and comply with personal-data laws such as the GDPR in your jurisdiction.
Personal data note: dataset items include creator names, usernames and avatars, which are personal data under the GDPR and similar laws. Collect only what you need, store it securely, and make sure you have a lawful basis for processing it. This is general guidance, not legal advice.
How many results do I get per keyword?
TikTok caps a single query string at ~200 unique results. The Actor broadens coverage with automatic additional query passes — accent, casing and spacing variants of your keyword, all real keyword searches, so results stay on-topic — and stops once extra queries stop returning enough new items, so you never pay for redundant fetching. Expect ~200–420 items per keyword in classic mode. To scale, add keywords or turn on expansion rather than expecting deeper pagination.
Why did I get zero results, and when does a run fail?
Usually an overly narrow keyword or a transient TikTok block. A keyword that returns nothing logs a warning. A run ends failed only when TikTok never returned a single valid response for at least one keyword — blocked or network-dead — and its status message then starts with a machine-readable failure token so automation can key retries off it. A run where TikTok answered but there genuinely were no results succeeds with an empty dataset. Either way zero items means zero charge, so re-run or try broader keywords.
Is search exact-match? Can I filter by date or country?
No. Search is fuzzy, not exact-match — TikTok's search behaves like TikTok's search,
and a nonsense keyword still returns ~30 loosely related videos rather than nothing.
There is no server-side date filter; use sortType: "DATE_POSTED" and filter on
uploadedAtFormatted downstream. location is passed to TikTok but does not partition
results by country (see the input table).
Does it download the videos?
No — it returns direct video URLs and metadata, not video files. That is why runs finish in
seconds and cost fractions of a cent: no gigabytes of video move through the Actor.
Download the files yourself from video.url if you need them (see the CDN-expiry note
above).
Will I hit rate limits? Are duplicates possible?
The Actor paces its requests and retries transient failures automatically, so you do not need to throttle it. Run-global deduplication guarantees the same video is never written twice within a run, even when it matches several keywords, query passes or expansion pools. For very large keyword lists, one batched run beats many small runs.
Where do I get support or request a feature?
Open the Issues tab on the Actor's page in Apify Console to report a problem or ask for a field or feature. Include the run ID — every run logs its context (plan, origin) so support cases can be diagnosed from the log.