TikTok Scraper - Videos by Keyword, Hashtag & Profile avatar

TikTok Scraper - Videos by Keyword, Hashtag & Profile

Pricing

from $2.49 / 1,000 videos

Go to Apify Store
TikTok Scraper - Videos by Keyword, Hashtag & Profile

TikTok Scraper - Videos by Keyword, Hashtag & Profile

Pricing

from $2.49 / 1,000 videos

Rating

0.0

(0)

Developer

Lantern Lab

Lantern Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

TikTok Scraper - Videos by Keyword, Hashtag or Profile

Collect public TikTok videos three ways: by keyword, by hashtag or from a profile. No login, no cookies, no account of your own. The Actor only reads what TikTok shows a signed-out visitor. $2.49 per 1,000 videos, plus $0.005 per run, and an input that finds nothing costs nothing. See Pricing.

Input:

{
"searchQueries": ["pasta recipe"],
"hashtags": ["cooking"],
"profiles": ["https://www.tiktok.com/@nasa"],
"maxResults": 30
}

Output - one row per video (recordType: "video"), plus one free input_summary row per keyword, hashtag or profile. Sample from a real run:

{
"recordType": "video",
"platform": "tiktok",
"videoId": "7700397098994273549",
"url": "https://www.tiktok.com/@nasa/video/7700397098994273549",
"description": "NASA 🤝 college football. We heard y’all like a good air show. Roll Tide!",
"hashtags": [],
"publishedAt": "2026-10-25T00:33:47+00:00",
"playCount": 110300,
"likeCount": 7362,
"commentCount": 239,
"shareCount": 229,
"collectCount": 474,
"durationSecs": 16,
"isImagePost": false,
"coverUrl": "https://p16-common-sign.tiktokcdn.com/...",
"isAd": false,
"language": "en",
"author": { "username": "nasa", "nickname": "NASA", "followerCount": 2100000, "verified": true },
"music": { "id": "7700397137514793741", "title": "original sound - NASA", "authorName": "NASA", "isOriginal": false },
"inputType": "profile",
"input": "nasa",
"position": 2,
"collectedAt": "2026-10-30T12:49:27+00:00"
}

Why this one:

  • Exact caps. maxResults: 30 returns at most 30 videos per keyword, hashtag or profile - never a page more, never charged for more.
  • Hashtag results carry the hashtag. TikTok's hashtag feed sometimes lists videos whose caption does not contain the tag; they are dropped (and counted in excludedNotTagged), not sold to you.
  • No duplicates. Videos are de-duplicated on TikTok's video ID across the whole run; a repeat is skipped and not charged.
  • Empty is not the same as blocked. Every input gets an input_summary row: complete, limit_reached, partial, blocked, no_results or not_found, with the reason. A run that returns no videos is not charged at all - not even the run fee.

What it does

  • Keyword search: the videos TikTok shows signed-out visitors for a keyword on its public keyword page (tiktok.com/discover/<keyword>), in TikTok's order.
  • Hashtag: the top of the hashtag's public video feed (about 100 videos for a signed-out visitor), plus the hashtag's total video and view counts in the summary row.
  • Profile: a public account's videos, newest first, plus the account's follower and video counts in the summary row.
  • For each video: ID, link, caption, hashtags, publish time, plays, likes, comments, shares, saves, duration, cover image, author (username, nickname, follower count, verified badge) and sound.

What it does not do

  • Not TikTok's signed-in search. TikTok's search box requires login for full search; this Actor uses the public keyword page, which shows about 60-100 videos per common keyword. Rare or made-up phrases have no such page and come back no_results with search:no_public_keyword_page, free of charge.
  • No login-only content, no private accounts (reported not_found with profile:private_account).
  • No video downloads and no transcripts - for spoken text use TikTok Transcript.
  • No comments - use TikTok Comments Scraper with the video links from this Actor.
  • Minimal personal data. Only the author's public username, nickname, follower count and verified badge. No user IDs, bios, emails or avatars.

Input

FieldDefaultMeaning
searchQueries-Keywords, one per line.
hashtags-cooking, #cooking or https://www.tiktok.com/tag/cooking.
profiles-nasa, @nasa or https://www.tiktok.com/@nasa.
maxResults30Videos per keyword, hashtag or profile (1-1,000).
proxyConfigurationApify Residential, USUsed only for requests TikTok refuses direct - in practice hashtag lists.
requestDelaySecs0.5Minimum pause between two requests.

At least one keyword, hashtag or profile is required.

Output

One dataset with two kinds of rows. Two views are predefined: Videos and Per-input status. A RUN_SUMMARY record in the key-value store has run totals: request outcomes per API path, proxy traffic, and the first refusals.

Video fields:

FieldMeaning
videoId, urlTikTok's video ID and link.
description, hashtagsCaption as published; hashtags in it, lower-case.
publishedAtWhen TikTok published it (UTC).
playCount, likeCount, commentCount, shareCount, collectCountCounters as TikTok reports them at collection time.
durationSecs, isImagePostLength in seconds (null for photo posts).
coverUrlCover image. TikTok's image links expire after a while.
isAd, languageAs TikTok reports them; null when the list does not say.
authorusername, nickname, followerCount, verified.
musicid, title, authorName, isOriginal.
inputType, input, positionWhich input produced the row and its position in that input's results.
collectedAtWhen the Actor read it (UTC).

A field TikTok does not provide is null, never guessed.

input_summary rows

collectionStatusMeaning
completeTikTok's list ended before your cap (list_end:... in reasons says how), and for profiles and hashtags it covers at least 90% of the count TikTok displays.
limit_reachedStopped at maxResults (or at the run's maximum cost).
partialSomething is missing; reasons says what - for example refused:empty_body after some videos were read, or hashtag:feed_ended_below_video_count.
blockedTikTok refused the list before any video was read.
no_resultsThe keyword has no public keyword page, or the list was empty.
not_foundThe hashtag or account does not exist, or the account is private.
invalid_inputThe input is not a keyword, hashtag or profile.

Also: videosCollected, duplicatesSkipped, excludedNotTagged, pagesRead and detail (hashtag: ID, title, video and view counts; profile: username, nickname, verified, follower and video counts).

How it works

The Actor opens tiktok.com once in a real browser as a signed-out visitor and then reads TikTok's own web API with that visitor session, the way the website does. Requests go direct first. When TikTok refuses a request direct - in our tests only the hashtag feed - that kind of request is retried through the proxy you configured and stays on it for the rest of the run; if TikTok still refuses, the Actor opens a new visitor session a few times before marking the input blocked or partial.

How much you get

Measured on Apify on 2026-10-30, no proxy used (every request was answered direct), one visitor session per run. TikTok changes its web client often, so numbers after a change may differ.

  • Keyword search: 82 and 94 videos for skincare routine and electric bike review before TikTok's keyword page ended - about 60-100 videos per keyword is what a signed-out visitor is shown.
  • Hashtag: TikTok serves a signed-out visitor only the top of a hashtag's feed - about 100 videos (91 tagged videos for #booktok, which has 88 million). When the feed ends far below the hashtag's video count, the summary row says partial with hashtag:feed_ended_below_video_count, never complete. In the same feed, 11 of 108 listed videos (and 70 of 100 for #cooking) did not carry the hashtag and were dropped.
  • Profile: all 61 videos of @nasa, newest first, matching the 61 the profile shows.
  • Caps: with maxResults: 30, each of the three inputs returned exactly 30 videos.
  • Duplicates: 0 in the output. Asking for nasa and @NASA in one run returned the 61 videos once; the second input reports duplicatesSkipped: 62 (TikTok repeats a pinned video).
  • Empty inputs: a made-up keyword, hashtag and account came back no_results / not_found, and the run was not charged.

If you need more than the first ~100 videos of a keyword or hashtag, split it into more specific keywords or hashtags.

Pricing

Pay per event: $2.49 per 1,000 videos, plus $0.005 per run. Apify platform usage, including proxy traffic, is included; you pay only these two events.

EventPriceCharged for
result$0.00249 ($2.49 per 1,000)Each video row. input_summary rows are free.
run-start$0.005Once per run, together with the first video. A run that returns no video is not charged.

Example: 3 keywords x 100 videos = 300 videos costs $0.005 + 300 x $0.00249 = $0.752.

To cap a run, set Maximum cost per run in the run options. When it is reached, the Actor stores no further videos, marks the input it cut short limit_reached with cap:maxTotalChargeUsd, says so in the status message, and does not start the remaining inputs.

Notes

  • Respect TikTok's terms and local law, and only collect what you need. Usernames and nicknames are personal data in many jurisdictions.
  • TikTok changes its web client often. RUN_SUMMARY shows request outcomes per API path and the first refusals.

Licenses

Request signing is adapted from Douyin_TikTok_Download_API by Evil0ctal and contributors, licensed under the Apache License 2.0. The license and notice are in dtk/LICENSE and dtk/NOTICE.