TikTok's discovery surface is huge, and search is how most apps get a foothold in it. Whether you are building a creator-sourcing tool, monitoring brand keywords, or expanding a keyword universe for a content team, you need three distinct search endpoints and an honest understanding of how their responses differ. This guide walks through the three search APIs offered by TikLiveAPI, compares their shapes, gives you five production-ready recipes, and covers pagination and caching patterns that actually hold up at scale.
All examples authenticate with the X-Api-Key header. Grab one from your profile after registering (100 free credits on signup), and test interactively in the playground before wiring anything up.
TikLiveAPI exposes three search primitives, each tuned for a different discovery target. Despite sharing a base path prefix, their request parameters and response shapes diverge in ways that matter.
This endpoint lives under the users category and finds creator accounts by keyword. It accepts keyword, count, and cursor. The top-level response key is user_list, and each item nests a user object that uses camelCase fields like uniqueId, avatarThumb, and secUid.
GET https://api.tikliveapi.com/search-user/?keyword=coffee&count=20&cursor=0
X-Api-Key: YOUR_KEY
Use this when the search target is a person or brand handle. It is the right entry point for influencer sourcing, brand monitoring (do competitors have a creator account on this keyword?), and audience-overlap research where you later pull followers or following lists.
This sits under the search category and finds posts (videos) by keyword. It accepts keyword, count, cursor, publish_time (a time-window filter), and sort_by (relevance vs recency). The presence of those last two parameters is what makes this endpoint qualitatively different from the other two.
GET https://api.tikliveapi.com/search-video/?keyword=cold+brew&count=20&cursor=0&publish_time=7&sort_by=0
X-Api-Key: YOUR_KEY
The publish_time filter lets you scope to the last 24 hours, 7 days, 30 days, or 90 days, which is what makes this endpoint the foundation of any trend-discovery workflow. The sort_by parameter lets you flip between TikTok's relevance ranking and a chronological feed.
Challenges (hashtags) get their own endpoint. It accepts keyword, count, and cursor and returns a list of challenge objects with their own IDs that you can later feed into the challenge posts endpoint.
GET https://api.tikliveapi.com/search-challenge/?keyword=barista&count=20&cursor=0
X-Api-Key: YOUR_KEY
The challenge ID you get back is the input parameter for /challenge-posts/, which is how you go from a hashtag string to the videos under it. This two-step pattern (search the challenge, then list its posts) is the canonical way to enumerate hashtag content.
If you only remember one thing about TikTok APIs: response shapes are not consistent across endpoints, because they reflect different upstream TikTok APIs. The user_list wrapper from /search-user/ nests camelCase user objects (uniqueId, secUid). Meanwhile user posts returns a videos[] array with snake_case items (aweme_id, play_count). And post detail returns a flat snake_case object with no wrapper at all.
This is not a bug. It mirrors what TikTok itself returns internally. The implication for your code: build a normalization layer up front. Pick one canonical shape for your application (snake_case is usually safest because most video and post endpoints already use it), and write small adapters per endpoint. Trying to consume raw responses across multiple endpoints will lead to subtle bugs around missing fields.
Given a seed keyword, find out how saturated it is and what content already ranks. Run /search-video/ twice: once with sort_by=0 (relevance) and once with sort_by=1 (recency), each scoped to publish_time=30.
GET /search-video/?keyword=pour+over&count=50&sort_by=0&publish_time=30
GET /search-video/?keyword=pour+over&count=50&sort_by=1&publish_time=30
Aggregate play_count, digg_count, and unique author counts from both result sets. The ratio of unique authors to videos tells you whether the keyword is dominated by a few creators or genuinely competitive. The delta between the relevance-sorted and recency-sorted lists tells you which authors TikTok's algorithm favors versus who is merely posting frequently.
Run /search-user/ every six hours on your brand keyword and store the resulting user_list. New entries that you have never seen before are new accounts squatting on the keyword. Existing entries whose followerCount from user info has grown significantly are creators worth a partnership conversation.
GET /search-user/ with keyword=<brand>
for each item in user_list:
fetch /userinfo-by-username/?username=<uniqueId>
diff stats.followerCount against last snapshot
alert on new uniqueId or growth above threshold
This is two credits per creator per check, so cache the user info response for at least 24 hours and only re-fetch profiles that showed up in today's search.
You need 50 creators in a niche for an outreach campaign. Run /search-user/ on three or four related keywords, deduplicate by secUid (more stable than uniqueId, which can be changed), then pull user info for each candidate to filter on follower count and video count.
seeds = ["latte art", "espresso", "barista tips", "coffee shop"]
candidates = {}
for seed in seeds:
for item in get("/search-user/", keyword=seed, count=50).user_list:
candidates[item.user.secUid] = item.user
for secUid, user in candidates.items():
info = get("/userinfo-by-username/", username=user.uniqueId)
if 10000 <= info.stats.followerCount <= 500000:
keep(user)
This pattern uses search as a top-of-funnel signal and user info as the qualifier. The follower band filters out micro-accounts and mega-accounts you cannot afford.
This is where /search-video/'s publish_time filter earns its keep. Run the same keyword with publish_time=1 (24 hours) and publish_time=7 (7 days) and compare the average play_count in each window. If the 24-hour average is materially higher than the 7-day average, the keyword is trending up. If it is lower, the trend is cooling.
recent = get("/search-video/", keyword=k, publish_time=1, count=50, sort_by=1)
baseline = get("/search-video/", keyword=k, publish_time=7, count=50, sort_by=1)
velocity = avg(recent.play_count) / avg(baseline.play_count)
# velocity > 1.5 means the keyword is heating up
Run this against a watchlist of 20 to 50 keywords on a daily cron and surface the top-velocity entries to your content team.
Start with one seed challenge. Search for it with /search-challenge/ and grab the top result's challenge ID. Pull its posts with /challenge-posts/ and extract every hashtag mentioned in the captions. Count frequency, dedupe, and you have a ranked list of co-occurring hashtags that you can feed back into /search-challenge/ for a second hop.
seed = "coldbrew"
challenge_id = get("/search-challenge/", keyword=seed).challenge_list[0].cid
posts = get("/challenge-posts/", challenge_id=challenge_id, count=100)
co_tags = count_hashtags_in(posts)
for tag, count in top(co_tags, 10):
expanded[tag] = get("/search-challenge/", keyword=tag)
This is the same logic SEO tools use for keyword expansion, adapted to TikTok's hashtag graph. Two hops is usually enough; beyond that the signal degrades.
All three search endpoints use cursor-based pagination. The first call sends cursor=0; subsequent calls send the cursor value returned in the previous response. Most endpoints also return a hasMore boolean that you should respect as the loop termination condition, not the cursor value alone.
cursor = 0
results = []
while True:
res = get("/search-video/", keyword="latte", count=20, cursor=cursor)
results.extend(res.videos)
if not res.hasMore:
break
cursor = res.cursor
if len(results) >= 200:
break # always cap your max pages
Two cautions. First, always cap your maximum page depth. TikTok's search results get noisier the deeper you go, and you are spending credits for diminishing returns. Two hundred items is plenty for most use cases. Second, do not assume the same query returns the same results on consecutive calls. TikTok personalizes and rotates results, so if you need a stable snapshot you have to store it yourself.
Note that followers and following endpoints use a time timestamp parameter for pagination instead of a cursor. This is the only consistent exception in the API, and it exists because those lists are time-ordered server-side. Search endpoints all stick to cursor.
Credits never expire on TikLiveAPI, but they do get spent. A sensible caching policy can cut your monthly burn by an order of magnitude.
Cache search results for 15 to 60 minutes keyed on the full query string. Search rankings shift hourly but not by the second, and most consumer apps render the same results to multiple users within a session. A Redis layer with a 30-minute TTL is the default I recommend.
Cache user info for 6 to 24 hours keyed on secUid. Follower counts move slowly enough that hourly freshness is almost never required. The exception is during a viral spike, where you might want to bypass cache and refetch.
Cache post detail nearly forever keyed on aweme_id. Once a video exists, its metadata is essentially immutable. The only fields that change are counters (play_count, digg_count), and you can refresh just those on a longer cadence.
Do not cache user posts, followers, or following lists for longer than 15 minutes. These are the endpoints where staleness causes visible bugs in user-facing apps.
Every request is one credit regardless of which search endpoint you hit. There is no per-endpoint multiplier and no monthly minimum, which makes capacity planning straightforward: count requests, multiply by your credit cost.
For the recipes above, expect roughly these credit budgets per run: keyword research 2 to 4 credits per keyword, competitor monitoring 1 plus N credits where N is the number of qualified candidates, creator sourcing 4 plus M credits where M is the unique creator count, trend discovery 2 credits per keyword per day, keyword expansion 1 plus K credits where K is the number of expanded tags you fetch.
The single biggest waste pattern I see is fetching /userinfo-by-username/ for every result of every search call without a cache. Always check your cache before spending a credit.
Use sort_by=0 (relevance) when you want TikTok's algorithmic ranking, which is what most users see. Use sort_by=1 (recency) when you are doing trend analysis or need a chronological feed. For competitor monitoring, run both and compare.
The two endpoints proxy different TikTok internal APIs that use different conventions. The pragmatic fix is to normalize at your ingestion layer rather than fighting it downstream.
Yes, just include the hashtag text in the keyword parameter without the # sign. But for systematic hashtag work, /search-challenge/ followed by /challenge-posts/ is more reliable because you get a stable challenge ID.
Results come from TikTok in real time with minimal proxy latency. Search rankings themselves are updated by TikTok on the order of minutes to hours, not seconds.
hasMore becomes false. The cursor value at that point is not guaranteed to be meaningful, so do not persist it for a future resume; start fresh with cursor=0 on the next run.
The proxy accepts Authorization: Bearer YOUR_KEY as well, but X-Api-Key is canonical and is what the playground and documentation examples use.
Open the playground, paste a keyword into each of the three search endpoints, and watch the response shapes side by side. Once you have the shapes internalized, the recipes above become straightforward to assemble. For full parameter references and example responses, the search documentation is your source of truth.
Ready to put what you read into code? Try our endpoints live or grab the full reference.