TikTok Scraper - Videos, Profiles and Hashtags avatar

TikTok Scraper - Videos, Profiles and Hashtags

Pricing

from $0.24 / 1,000 results

Go to Apify Store
TikTok Scraper - Videos, Profiles and Hashtags

TikTok Scraper - Videos, Profiles and Hashtags

Scrape TikTok videos and profiles by handle, hashtag, keyword or link. Video rows carry plays, likes, comments, shares, saves, caption, sound and author. A profile gives its own row plus its 10 or so newest videos; hashtags and search go deeper. $0.25 per 1,000 rows.

Pricing

from $0.24 / 1,000 results

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

51

Total users

27

Monthly active users

a day ago

Last modified

Categories

Share

Scrape TikTok videos and profiles by handle, hashtag, keyword or link: every video comes back with its plays, likes, comments, shares and saves, the caption, the sound, the author and the file links, and every profile with followers, lifetime likes, bio and the verified flag. Nothing to log into.

One thing to know before you spend anything: a profile returns about a dozen rows, the profile itself plus its ten or eleven newest videos. That is all TikTok shows a signed-out visitor, and no value of resultsPerPage changes that. Hashtags and keyword searches page much deeper, so those are the modes to use when you want volume.

InputHandles, hashtags, keywords, or TikTok profile, video and tag links
OutputOne row per video or profile: plays, likes, comments, shares, saves, caption, hashtags, tagged accounts, sound, author, file links and the input it came from; followers, lifetime likes and bio on profiles
Ceiling2,000 rows per run, or per input with resultsPerInput; a profile gives about 12
Account neededNone
Price$0.25 per 1,000 rows on the free plan, down to $0.244 on Business. The free plan's $5 a month covers about 20,000

🔍 What TikTok Scraper does

Four ways in, and you can mix them in one run:

You give itYou get
profilesThe profile row, then its newest videos, about a dozen rows per handle
hashtagsVideos posted under the tag, paging as deep as your limit allows
searchQueriesThe videos TikTok returns for the keyword
startUrlsA profile link, a /video/ link for one video, or a /tag/ link

resultsPerPage counts rows for the whole run, not per input. That matters when you list several: once the first hashtag has used the allowance, the second returns nothing. Set resultsPerInput and each input gets its own limit.

Rows are deduplicated inside a run, so a video that turns up under two of your hashtags is returned and billed once. maxRunSeconds stops a slow feed and hands back what it has so far, which keeps a search that crawls along from running up a bill.

📋 What data you get from each TikTok video and profile

What you getField
Which kind of row it istype (video or profile)
Video id and the link a person can openid, webVideoUrl
Caption, and the hashtags in ittext, hashtags
Accounts tagged in the captionmentions
Which of your inputs found itsourceInput, sourceType
TikTok's own subtitles, when you ask for themsubtitles, subtitlesLanguage
When it went up, and the region TikTok files it undercreateTime, region
Plays, likes, comments, shares, saves and downloadsplayCount, diggCount, commentCount, shareCount, collectCount, downloadCount
Whether it is an adisAd
Length, cover image and the video file linksvideo.duration, video.cover, video.dynamicCover, video.playAddr, video.downloadAddr
The sound: id, title, artist, audio link, original or not, lengthmusic
Who posted itauthor.id, author.uniqueId, author.nickname, author.avatar
Profile handle, display name, bio, avatar and the blue tickuniqueId, nickname, signature, avatar, verified
Followers, following, lifetime likes and video countfollowerCount, followingCount, heartCount, videoCount
The profile id that survives a rename, and the profile linksecUid, url

▶️ How to scrape TikTok videos and profiles

  1. Open TikTok Scraper and click Try for free.
  2. Fill in whichever box fits: Profiles, Hashtags, Search queries or Start URLs.
  3. Set Max results per run, or Results per input to give each input its own limit. Start at 50 while you look at the output.
  4. Click Start.
  5. Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.

Start it with every box empty and you get one labelled sample row that is not charged. It is a placeholder, so judge the real shape from the row further down this page.

💰 How much does it cost to scrape TikTok videos and profiles?

$0.25 per 1,000 rows. Paid plans pay a little less: $0.248 on Starter, $0.246 on Scale and $0.244 on Business. A profile row costs the same as a video row. On the free plan, the $5 Apify gives you each month covers about 20,000 rows.

You pay for rows that carry data. The sample row, diagnostic rows and duplicates caught inside a run are not charged, and resultsPerPage caps both the rows and the spend.

Leaving out pinned videos is a paid option, billed per video left out as "Pinned video left out" (see the Pricing tab). Videos the likes and date filters leave out are not charged. Subtitles cost nothing extra.

One case people miss: a private account still costs its profile row, because the profile is real data even when the videos behind it are hidden.

📥 What you give it

{
"profiles": ["nasa"],
"hashtags": ["spacex"],
"resultsPerPage": 50,
"maxRunSeconds": 90
}
FieldDefaultWhat it is
profilesnoneHandles, with or without @. The form opens with nasa filled in as an example, which is a starting point rather than a default.
hashtagsnoneTags, with or without #.
searchQueriesnoneKeywords to search TikTok for.
startUrlsnoneLinks pasted straight in: a profile, a /video/ link or a /tag/ link. Anything else is skipped.
resultsPerPage50Rows for the whole run, 1 to 2,000. This is also your spend cap. Not used when resultsPerInput is set.
resultsPerInputnoneRows for each profile, hashtag, search and link, 1 to 2,000. Empty keeps the one limit for the run.
maxRunSeconds90Stops the scrape at this point and returns what it has, 10 to 300. Raise it if you would rather have the rows than the time back.
minLikes, maxLikesnoneOptional add-on, off unless you set a value: keep only videos inside this likes range. A video with no like count is left out, the same as one outside the range; a count of 0 is a real count. These filters apply to videos only: a profile's own row is always returned, and its diggCount is the number of videos that account has liked.
postedAfter, postedBeforenoneOptional add-on, off unless you set a date: keep only videos posted on or after postedAfter and before postedBefore, as dates like 2026-10-01, counted in UTC. A video with no posting date is left out, the same as one outside the range. Anything that is not a date stops the run before it starts, with a BAD_INPUT row. Hashtag and search feeds are not sorted by date or likes, so with either add-on set an input stops after 10 pages in a row with no match.
excludePinnedfalsePaid option, profiles only: leave out the videos a creator pinned to the top of their profile. TikTok marks nothing as pinned, so they are read from the list order, and a pinned video that is also the creator's newest stays in.
includeSubtitlesfalseAdd TikTok's own subtitles to each video row, as text. Hashtag and search runs take longer with it on.
sessionCookiesnoneOptional: your own session, used only for your run. You are responsible for using it within the site's terms. The field is stored encrypted.
proxyConfigurationoffLeave it off. It is there for people sending traffic through their own servers at high volume.
notionConnector, notionParentIdnoneOptional. Write each row into a Notion database as well as the dataset.

📤 What you get back

A real video row from a real run. The caption ends with an emoji, so it is cut short here, and the media links are trimmed:

{
"ok": true,
"type": "video",
"id": "7358577498319342891",
"webVideoUrl": "https://www.tiktok.com/@.../video/7358577498319342891",
"text": "Got me feeling like Snow White and shii... #fyp #cats #disneyprincess",
"createTime": "2024-04-16T21:19:04.000Z",
"hashtags": ["fyp", "cats", "disneyprincess"],
"region": "US",
"playCount": 17912733,
"diggCount": 3674504,
"commentCount": 12854,
"shareCount": 244131,
"collectCount": 282047,
"downloadCount": 8092,
"isAd": false,
"video": { "duration": 11, "cover": "https://p16-common-sign.tiktokcdn-us.com/...", "playAddr": "https://v45.tiktokcdn-us.com/...", "downloadAddr": "https://v45.tiktokcdn-us.com/..." },
"music": { "id": "7402610556690860833", "title": "kagefumi", "authorName": "-", "original": true, "duration": 36 },
"author": { "id": "6806757644620350470", "uniqueId": "...", "nickname": "...", "avatar": "https://p19-common-sign.tiktokcdn-us.com/..." }
}
FieldHow to read it
typeVideos and profiles share one dataset, so check this before anything else.
playCount and the other countersRead at the moment of the run. On a profile's videos a counter that could not be read is null; on hashtag and search rows it reads 0.
text, hashtagsEmpty when the creator wrote no caption or used no tags.
video.playAddr, video.downloadAddr, video.coverSigned links that stop working after a short while.
musicThe sound the video uses, or null when there is none.
mentionsThe accounts tagged in the caption, each as { "uniqueId", "id" }. The caption shows a tag as the person's display name, so read the handle here. On hashtag and search rows only the id is known and uniqueId is null; on a profile's video read from the short public entry, mentions is null.
sourceInput, sourceTypeWhat you typed that found the row, and whether it was a profile, hashtag, search or videoUrl. A video found by two inputs comes once, under the first.
subtitles, subtitlesLanguageOnly with includeSubtitles on: the subtitles TikTok publishes for the video as plain text, and their language, such as eng-US. Both null when TikTok has none for that video or the file could not be read.
secUidOn profile rows. It stays the same when the creator changes their handle, so track it rather than uniqueId.

🧾 Reading the output

Three kinds of row can land in your dataset.

RowHow to spot itBilled
A video or a profileok: true and a typeyes
The sample row_sample: trueno
A diagnosticok: false and an errorCodeno

Filter on ok == true and you have your data. A diagnostic never stops the run; it moves on to the next input.

CodeWhat it means
NOT_FOUNDTikTok shows the handle, video or tag as gone or private.
BAD_INPUTA handle carried characters TikTok does not use, or an option could not be used, such as a date that is not a date. For an option, nothing is searched.
RATE_LIMITED, SERVER_ERROR, NETWORKThat item would not answer this run. Re-running usually clears it.
NOT_SERVEDThis request was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED.
TIME_LIMITThe run neared the time limit set for it on Apify and stopped, keeping every row it had delivered. If nothing had come back by then, the run ends as failed.
NO_RESULTSNothing came back at all for the whole run.

One quirk of the Overview table: its columns are the video ones, so a profile row shows almost nothing there and a diagnostic reads as a blank line. Open the row itself or download the JSON and everything is present.

💡 What people use it for

  • Keeping an eye on a set of creators. Run the handles weekly and compare the counts on their newest videos.
  • Pulling the videos under a campaign hashtag, then reading the captions for how people talk about it.
  • Keyword research: search a phrase and see which videos TikTok actually puts in front of people.
  • A quick check on one video from a link somebody dropped in a chat.

From a hashtag to a creator shortlist, in three runs:

  1. Run this on a hashtag in your niche and copy the author.uniqueId column.
  2. Paste those handles into TikTok Profile Scraper and sort on followerCount.
  3. Put the webVideoUrl of the videos worth a closer look into TikTok Comments Scraper and read what the audience says.

🚧 What it does not do

  • A profile is not an archive. About a dozen rows per handle, and no input changes that.
  • No comments and no follower lists. Comments come from TikTok Comments Scraper.
  • The limit is shared across your inputs unless you set resultsPerInput. One busy hashtag can use the whole run.
  • Subtitles only where TikTok publishes them. Nothing is generated from the audio; no subtitles means null.
  • A private account still costs its profile row. You get the profile, then a NOT_FOUND row saying the videos are private.
  • A profile's video can arrive with null counters when only the short public entry could be read. It is still a delivered row and it is charged.
  • On hashtag and search rows, a counter TikTok left out reads as 0, not as missing.
  • maxRunSeconds cuts quietly. When it fires you get a partial result and no row saying so, so check the log if a count looks short.
  • Media links expire. They are signed and short lived.
  • It is not an official TikTok tool. Dami's Studio is independent and is not affiliated with or endorsed by TikTok, or by any other company named on this page.

🧭 Which TikTok scraper do you need?

If you wantUse
Profiles, hashtags, keyword search and single videos in one runThis one
Follower and like counts for a list of handlesTikTok Profile Scraper
Videos posted under a hashtagTikTok Hashtag Scraper
Videos using one soundTikTok Sound Scraper
Comments under a videoTikTok Comments Scraper
The hashtags ranking in a country right nowTikTok Trending Hashtags

❓ Questions people ask

Do I need a TikTok account to scrape TikTok?

No. Everything is read signed out. The cookie field is optional.

Why did a profile only return 12 rows?

That is what TikTok publishes for a creator to a signed-out visitor, so no setting gets you the full back catalogue. Hashtag and search modes are where the depth is.

Is resultsPerPage per input or per run?

Per run, the total across every input. For a limit on each one, set resultsPerInput.

Why do the numbers differ from what I see in the app?

The app rounds big counts and the row does not. Counts also move by the minute on a video that is doing well, so compare against the time of your run. If something is missing, open the page in a private browser window: what a signed-out visitor sees there is what this actor can read.

Can I call it from code or connect it to an AI assistant?

Yes. The API tab has ready-made code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/tiktok-scraper. Either way the run happens on your Apify account at the same price.

This reads public profiles and public videos only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Include the handles, tags or links you used and the run ID, and the log is usually enough for us to see what happened.