TikTok Hashtag Scraper - Videos, Views & Captions
Pricing
from $0.24 / 1,000 results
TikTok Hashtag Scraper - Videos, Views & Captions
TikTok hashtag scraper: the videos under a hashtag, one row each with plays, likes, comments, shares and saves, the caption, author and sound, a link to the video, and a flag on branded posts. The limit covers the whole run, not each tag. $0.25 per 1,000 videos.
Pricing
from $0.24 / 1,000 results
Rating
5.0
(1)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
53
Total users
16
Monthly active users
4 hours ago
Last modified
Categories
Security
Limited permissionsShare
TikTok hashtag scraper for the videos posted under any hashtag: one row per video with plays, likes, comments, shares and saves, the caption, the author, the sound, and a video link. Search words, creators, sounds and single video links work too, and every video costs the same. Nothing to log into.
The thing to know before your first run: a hashtag feed is what TikTok shows a visitor today, not the full history of the tag, and a creator's profile gives only their newest 10 or so videos. The limit covers the whole run unless you fill in Videos per input.
| Input | Hashtags or tiktok.com/tag/ links; also search words, profiles, sound links and video links |
| Output | One row per video: plays, likes, comments, shares, saves, caption, hashtags, author, sound, branded flag, both video file links, and the input that found it. On request: creator numbers, size and place, subtitles, comments, image copies |
| Ceiling | 2,000 videos per run, or per input; about 10 per profile |
| Account needed | None |
| Price | $0.25 per 1,000 videos on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 20,000 |
🔍 What TikTok Hashtag Scraper does
It walks the feed behind each tag and flattens every video into one row. Search words, profiles, sounds and video links go in their own boxes and come back in the same shape.
The same video showing up under two of your inputs is returned once and billed once, labelled with the first. You can keep only videos above or below a like count or inside a date range, cap how many come from one creator, or have the run read ten times your limit and return the most liked, most played, newest or oldest.
A few field names are TikTok's own: diggCount is likes, collectCount is saves, and isAd marks
branded content.
📋 What data you get from each TikTok hashtag video
| What you get | Field |
|---|---|
| Video id and the link a person can open | id, webVideoUrl |
| Caption, and the hashtags in it | text, hashtags |
| When it went up, and the region TikTok reports | createTime, region |
| Plays, likes, comments, shares, saves and downloads | playCount, diggCount, commentCount, shareCount, collectCount, downloadCount |
| Branded content flag | isAd |
| Length, still and animated covers | video.duration, video.cover, video.dynamicCover |
| The video file links | video.playAddr, video.downloadAddr |
| The sound: id, title, artist, the creator's own or not, length, and its album | music, musicAlbum |
| Who posted it, and a link to their profile | author, authorProfileUrl |
| What you typed that found it, and which box it was in | sourceInput, sourceType |
| The tag's total views and how many creators used it | hashtagInfo |
| Accounts tagged in the caption, as ids | mentions |
| Optional: followers, following, total likes, video count, verified, private, account start, bio and bio link | creator |
| Optional: width and height, and the place the creator tagged | videoWidth, videoHeight, location |
| Optional: TikTok's own subtitles as text | subtitles, subtitlesLanguage |
| Optional: links to copies of the cover, the creator's picture, the sound's cover and photos | storedImages |
▶️ How to scrape TikTok hashtags
- Open TikTok Hashtag Scraper and click Try for free.
- Type tags into Hashtags, one per line, or fill in any of the other boxes.
- Set Max videos per run, or Videos per input to give each one its own share. Start at 50 while you look at the output.
- Switch on any extras you want, then click Start.
- Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.
Give it at least one input. A run with nothing in any box ends with one free BAD_INPUT row, not a sample.
💰 How much does it cost to scrape TikTok hashtags?
$0.25 per 1,000 videos on the Free plan. Paid plans pay a little less: $0.248 on Starter, $0.246 on Scale and $0.244 on Business. On the free plan, the $5 Apify gives you each month covers about 20,000 videos.
You pay for videos delivered. A comment row, when you ask for comments, is charged as a result at the same price. Diagnostic rows, a video found twice, and videos a sort reads but does not return are not charged. The likes and date filters and the image copies are optional add-ons, off unless you set them. They are free until 9 November 2026, and from that day:
| Add-on | Price |
|---|---|
| Likes and date filters | $0.01 per 1,000 videos they check and leave out, the same on every plan |
storeImages | $0.25 per 1,000 image copies on the Free plan, a little less on paid plans |
📥 What you give it
{"hashtags": ["cats", "spacex"],"resultsPerInput": 50,"sortBy": "mostLiked","minLikes": 1000}
| Field | Default | What it is |
|---|---|---|
hashtags | none | Tags, with or without #. The form opens with cats filled in as an example, which is a starting point rather than a default. |
startUrls | none | Or paste links like https://www.tiktok.com/tag/cats. A plain word or #word here counts as a hashtag too. Anything else is skipped and named in the run log. |
searchQueries | none | Words to search for, one search per line. |
profiles | none | Usernames or profile links. Each gives that creator's newest videos, about 10. No row for the profile itself. |
musicUrls | none | Sound links or the number at the end of one. Each gives videos that use that sound. |
videoUrls | none | Links to single videos, share links included. |
resultsPerPage | 50 | Videos for the whole run, 1 to 2,000. Not used when resultsPerInput is set. |
resultsPerInput | none | Videos for each hashtag, search, profile, sound and link, 1 to 2,000. |
sortBy | feed | feed keeps TikTok's order. mostLiked, mostPlayed, newest or oldest read up to ten times your limit (2,000 at most per input) and return the top ones. |
minLikes, maxLikes | none | Optional add-on. A video whose like count could not be read is left out. |
postedAfter, postedBefore | none | Optional add-on. Dates in UTC, like 2026-10-01; before is exclusive. |
postedWithinDays | none | Optional add-on. The last this many days. Use it instead of postedAfter. |
maxVideosPerCreator | none | At most this many videos from one creator in the run. |
excludePinned | false | Profiles only: leave out the videos a creator pinned. |
includeCreatorStats | false | Add the creator block. About a second per creator. |
includeVideoDetails | false | Add width, height and place. Reads each video's own page. |
includeSubtitles | false | Add TikTok's own subtitles, when it has them. |
commentsPerVideo | none | Up to 200 comments under each video, as their own rows. |
storeImages | false | Optional add-on. Keep copies of the images in this run's storage. |
sessionCookies | none | Optional: your own session, used only for your run. You are responsible for using it within the site's terms. The field is stored encrypted. |
proxyConfiguration | off | Leave it off. It is there if you want to send traffic through your own servers. |
notionConnector, notionParentId | none | Optional. Write each video into a Notion database as well as the dataset. |
A filter value that cannot be used, like a minLikes above maxLikes, stops the run before any
lookup with a free BAD_INPUT row, rather than returning videos you did not ask for.
📤 What you get back
A real row from a real run. The caption starts with emoji, so it is cut short here, and the media links are trimmed:
{"ok": true,"type": "video","id": "7417800442127633707","webVideoUrl": "https://www.tiktok.com/@lilpawdrama/video/7417800442127633707","text": "...#cat #cutecat #catsoftiktok #catlover #cats #funny #pets #usa_tiktok","createTime": "2024-09-23T11:34:25.000Z","hashtags": ["cat", "cutecat", "catsoftiktok", "catlover", "cats", "funny", "pets"],"region": "US","playCount": 136727,"diggCount": 22693,"commentCount": 127,"shareCount": 437,"collectCount": 1968,"downloadCount": 803,"isAd": true,"video": { "duration": 30, "cover": "https://p16-common-sign.tiktokcdn-us.com/...", "playAddr": "https://v45.tiktokcdn-us.com/...", "downloadAddr": "https://v45.tiktokcdn-us.com/..." },"music": { "id": "7136445672676411393", "title": "Cute", "authorName": "Aurel Surya Lie", "original": false, "duration": 179 },"author": { "id": "7412528791307715627", "uniqueId": "lilpawdrama", "nickname": "lilpawdrama", "avatar": "https://p19-common-sign.tiktokcdn-us.com/..." }}
Every row ends with the newer columns, and the extras you switch on come after them. Here is how a
real row ended on 24 October 2026, from the nasa profile with every extra on, links trimmed:
{"sourceInput": "nasa","sourceType": "profile","hashtagInfo": null,"musicAlbum": null,"authorProfileUrl": "https://www.tiktok.com/@nasa","mentions": [],"creator": { "followerCount": 2136111, "followingCount": 23, "heartCount": 11352112, "videoCount": 59, "verified": true, "privateAccount": false, "bio": "Making the seemingly impossible, possible.✨", "bioLink": "science.nasa.gov/...", "accountCreatedAt": "2026-07-20T15:55:49.000Z" },"videoWidth": 720,"videoHeight": 1280,"location": null,"subtitles": null,"subtitlesLanguage": null,"storedImages": { "cover": "https://api.apify.com/v2/key-value-stores/.../records/image-....jpg?signature=...", "authorAvatar": "https://api.apify.com/v2/key-value-stores/...", "musicCover": "https://api.apify.com/v2/key-value-stores/...", "photos": [] }}
On a hashtag row hashtagInfo reads like { "id": "5216", "name": "cats", "viewCount": 439996153779, "creatorCount": 30102752 }.
| Field | How to read it |
|---|---|
id | Unique per video. Use it as your dedupe key across runs. |
createTime | When it was posted, as an ISO timestamp. |
playCount and the other counters | As TikTok reports them at read time. A counter TikTok did not send reads 0. |
video.playAddr, video.downloadAddr | Signed links that stop working after a short while. |
music, musicAlbum | null when the video has no sound, or the sound has no album. |
hashtagInfo | Filled on hashtag rows, null on the others. |
location | null when the creator tagged no place. |
🧾 Reading the output
Three kinds of row land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| A video | ok: true and type: "video" | yes |
| A comment, when you asked for them | ok: true and type: "comment", with videoId | yes, as a result |
| A diagnostic | ok: false and an errorCode | no |
Filter on type == "video" and you have your videos. An input that fails gets its own row, and
the run moves on to the next one.
| Code | What it means |
|---|---|
NOT_FOUND | TikTok has no such tag, account, sound or video, or the account is private. |
NO_RESULTS | Nothing came back for the whole run, or nothing matched your filters. |
RATE_LIMITED | That input would not answer this run. Re-running usually clears it. |
NOT_SERVED | This request was not served this run. Re-run it later. Runs before 13 October 2026 wrote BLOCKED here. |
TIME_LIMIT | The run neared its time limit and stopped, keeping every video it had delivered. If none had come back by then, the run still ends as succeeded, with an amber status message. |
BAD_INPUT | Nothing to look up, or a filter value that cannot be used. The run ends straight away as succeeded, and the row names the field. |
The Overview table shows five columns, so a diagnostic row reads as a nearly blank line there. Open the row itself or download the JSON and everything is present.
💡 What people use it for
- Finding which posts under a niche tag actually travelled: sort by most played and keep the top 50.
- Building a list of the creators behind a tag: one video per creator, with creator numbers switched on.
- Building a swipe file of hooks: caption, sound, length and play count in one table.
- Separating branded posts from organic ones with
isAdbefore reporting on reach.
From a trending tag to the people behind it, in two runs:
- Run TikTok Trending Hashtags for
your country and copy the
hashtagcolumn. - Paste those tags here with Videos per creator at 1 and Add creator numbers on, then sort
the rows on
creator.followerCount.
🚧 What it does not do
- No replies under comments and no follower lists. Replies and comments in bulk are in the table below.
- The feed is not an archive.
- A profile stops at about 10 videos, the newest ones on the public profile.
- A sort ranks what the feed serves, not TikTok's own all-time list.
- Media links expire. They are signed and short lived, unless you keep image copies.
- A counter TikTok does not send reads as
0. On a fresh video that can mean "not published yet" rather than none. - An empty input ends the run with a
BAD_INPUTrow instead of returning a sample. - 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 want | Use |
|---|---|
| Videos under a hashtag, a search, a creator, a sound or a link, filtered or sorted | This one |
| A creator's profile row with their newest videos | TikTok Scraper |
| Follower and like counts for a list of handles | TikTok Profile Scraper |
| Comments with their replies, for a list of videos | TikTok Comments Scraper |
| The hashtags ranking in a country right now | TikTok Trending Hashtags |
| Posts and reels under an Instagram hashtag | Instagram Hashtag Scraper |
❓ Questions people ask
Do I need a TikTok account to scrape hashtags?
No. The cookie field is optional.
Is the limit per hashtag or per run?
Per run, unless you fill in Videos per input: then each hashtag, search, profile, sound and link gets that many.
Why did I get fewer videos than I asked for?
TikTok stopped handing out more of that feed, an earlier input had already used the run's allowance, or your filters left the rest out. A narrow filter on a busy tag stops after ten pages in a row with no match.
Do the video links expire?
Yes, both file links and the image links are signed and expire. Switch on image copies if you need the pictures to last as long as the run's storage.
Can I call it from code or connect it to an AI assistant?
The API tab has code for Python, JavaScript and the
CLI. MCP clients like Claude and ChatGPT use
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/tiktok-hashtag-scraper; coding assistants can load our
skill file. All three bill
your Apify account at the same price.
Is scraping TikTok legal?
This reads 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. A bio can hold contact details, and the rules on cold contact apply to those. TikTok's own terms still apply to what you do with the data. 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 inputs you used and the run ID, and the log is usually enough for us to see what happened.