TikTok Video Scraper - Views, Likes & Hashtags
Eimantas V · @amethyst
Scrape TikTok video stats from a list of URLs: views, likes, comments, shares, saves, hashtags, sound, post date and creator followers. No login or API key.

About
TikTok Video Scraper — Views, Likes & Hashtags
TikTok video scraper that returns views, likes, comments, shares, saves and reposts for any list of video URLs, plus hashtags, the sound, the exact post date and the creator's follower count. No login, no API key, no browser.
Paste video URLs, get a spreadsheet of engagement. It is built for the job most TikTok data actually gets bought for: measuring how a specific set of posts performed — a campaign's deliverables, a competitor's last thirty uploads, a hashtag's top posts you collected elsewhere.
What you get
One row per video. Every field below was populated on a real captured video;
null means TikTok did not return it, never a stand-in zero.
| Field | Type | Notes |
|---|---|---|
playCount | integer | null | Views |
likeCount | integer | null | |
commentCount | integer | null | |
shareCount | integer | null | |
collectCount | integer | null | Saves |
repostCount | integer | null | Only present in TikTok's newer stats block |
engagementRate | number | null | (likes+comments+shares) ÷ views, as a % |
description | string | null | The caption |
createdAt | string | null | A real UTC timestamp, not a relative string |
createdAtUnix | integer | null | |
hashtags | array | Tags the creator typed, in caption order and original casing |
challenges | array | Every challenge TikTok associates — a superset of the above |
mentions | array | @-handles in the caption |
musicTitle / musicAuthor / musicId | string | null | The sound |
musicIsOriginal | boolean | null | Original audio vs a licensed track |
durationSeconds / width / height | integer | null | |
coverUrl | string | null | |
authorHandle / authorName / authorId | string | null | |
authorFollowerCount | integer | null | The creator's followers at scrape time |
authorHeartCount / authorVideoCount | integer | null | |
authorVerified | boolean | null | |
authorSignature | string | null | Creator bio |
isAd | boolean | null | Branded content flag |
isAigc | boolean | null | AI-generated content flag |
locationCreated | string | null | Country code |
duetEnabled / stitchEnabled | boolean | null | |
commentsDisabled | boolean | null |
Engagement rate is null when it cannot be computed
If views are missing or zero, engagementRate is null rather than 0 or
Infinity. A rate over an unknown denominator is not a measurement, and a
buyer sorting on it would otherwise be sorting on an artefact.
hashtags and challenges are different things, and are kept apart
TikTok exposes hashtags in two places that disagree, and the longer list is not the better one.
hashtags is what the creator actually typed. It comes from the caption,
with character offsets that prove where each tag appears, so it preserves the
creator's own casing rather than TikTok's normalised form.
challenges is TikTok's own association set. It uses canonical casing and
it can include tags that appear nowhere in the caption. On the video used to
build this Actor the two differed twice over: the creator typed
#petsoftiktok, challenges reports it as PetsOfTikTok, and challenges
additionally carried bonevoyage — a tag the caption never contained. Merging
them would have made every row assert something false about the creator, so the
two stay separate.
Use hashtags for "what did they tag this with". Use challenges for reach and
discovery analysis, where TikTok's own associations are the point.
Input
{
"videos": [
"https://www.tiktok.com/@scout2015/video/6718335390845095173",
"https://www.tiktok.com/@nasa/video/7016181555718065413",
"6718335390845095173"
],
"maxVideos": 1000,
"requestDelayMs": 1500
}
Full video URLs, photo-post URLs, /v/ and /embed/v2/ links, and bare numeric
ids all work; extra query parameters are ignored. You can also chain from
another Actor's dataset with sourceDatasetId.
Pricing
One flat monthly rental, shown on this page, with a free trial. There is no per-video fee: scrape as many videos as you need.
Runs use your credits for compute and proxy traffic, as every Actor does. Each video is one request of about 100 KB through the platform's datacenter proxy. Measured on Bytewells: one video in 9 seconds at 512 MB for $0.0004 of credits, start-up included, so 1,000 videos cost well under $0.40.
What this does NOT do
Stated plainly, because a listing that overpromises collects one-star reviews:
- No comments. TikTok's comment endpoint was measured to answer either a
91-byte
status_code: 5envelope or an HTTP 200 with zero bytes unless the request carries a rotatingX-Bogus/msTokensignature. Reverse-engineering a rotating signature is a maintenance treadmill, so this Actor does not pretend to offer comments. - No video discovery. You supply the video URLs. Profile pages, tag pages, the explore feed and music pages were all measured to carry no video list server-side — zero ids across every route tried. Pair this with a discovery Actor if you need to find videos first.
- No profile-only scraping. Pass videos. A profile URL is rejected with a message telling you so.
- No video file downloads or transcripts.
- No
vm.tiktok.comshort links. Expanding one needs a redirect this Actor does not follow; it is rejected with a message rather than guessed at. - No historical or time-series data. Every count is as of the moment it was scraped. Run it on a schedule if you want a series.
- Private and deleted videos return an error row, not data.
How it works, and the honest part
One plain HTTP GET per video. TikTok server-renders the full video metadata into the watch page, so there is no browser, no login, no cookie, no API key and — the part that matters for durability — no signed request. Nothing here rotates on a TikTok deploy.
Reliability
- Measured 19/20 on real videos from datacenter IPs, the single miss a timeout rather than a block. Datacenter is the IP class the platform actually runs on, which is why that is the number quoted rather than a residential one.
- Deleted is distinguishable from blocked. TikTok answers a missing video
with HTTP 200 and
statusCode 10204/"item doesn't exist", where a block has no rehydration payload at all. Those become different rows: a typedvideo-not-founderror row, versus a retry on a fresh IP. - Blocked requests are retried on a different datacenter IP, twice, with a hard backoff. A not-found is never retried — TikTok will say the same thing from every IP, so retrying spends requests to learn nothing.
- The id is checked on the way out. TikTok serves a video even when the handle in the URL is wrong, so the Actor refuses to emit a row whose returned id does not match the one requested.
- The response gate never keys on size. A not-found page measured 369 KB against a real page's 394 KB — close enough that any size threshold would misclassify. Only shape is used.
robots.txt
You should know this before you rent, so it is here rather than buried.
https://www.tiktok.com/robots.txt disallows a broad set of paths and bans
several named crawler user-agents outright. This Actor requests the ordinary
public watch page, sends no credentials, and bypasses no authentication or
access control — it reads what any logged-out visitor sees. Whether that is
acceptable for your purpose is a decision for you and your legal advisers, and
it depends on your jurisdiction and what you do with the data.
Proxy
The platform's datacenter proxy, on by default, and used to rotate IPs when a video comes back blocked. Residential is deliberately not offered: it is billed per gigabyte, and at 87 KB per video it would dominate the cost of a run for a transport that was measured not to need it.
FAQ
- What data does it return for each TikTok video?
- Views, likes, comments, shares, saves and reposts, an engagement rate, the caption, hashtags and challenges (kept apart), mentions, the sound, the exact post time in UTC and the creator's follower count. A value TikTok does not return is null, never a stand-in zero.
- Do I need a TikTok account, login or API key?
- No. Each video is one plain request for its public page, with no browser, login, cookie, API key or signed request.
- Does it find videos for me?
- No. You supply the video URLs. Profile URLs and vm.tiktok.com short links are rejected with a message, not guessed at.
- Does it return comments?
- No. For comments and replies, use TikTok Comments Scraper by the same publisher.
- How much does it cost?
- One flat monthly rental, shown on this page, with a free trial and no per-video fee. Each video is one request of about 100 KB through the platform's datacenter proxy, billed to your Bytewells credits. Measured on Bytewells: 1,000 videos cost well under $0.40.
- What happens with deleted or private videos?
- They return an error row with the reason (for example video-not-found) instead of data. A missing video is not retried, because TikTok gives the same answer from every address; a blocked request is retried on another address.
- Can I use it through the API or from AI agents?
- Yes. Start runs through the Bytewells API (bytewells.com/docs/api), schedule them and read the dataset as JSON; webhooks work too. The API is Apify-compatible, so apify-client works with the Bytewells base URL. AI agents can run it as a tool through the Bytewells MCP server (bytewells.com/docs/mcp).
Input
Preview of the input form. Rent the Actor to fill it in and start runs from the console.
Fields
videosFull video URLs (tiktok.com/@handle/video/123...), photo-post URLs, /v/ or /embed/v2/ links, or bare numeric video ids. Extra query parameters are ignored. A vm.tiktok.com short link is rejected with a message rather than guessed at, because expanding it needs a redirect this Actor does not follow.
startUrlsThe same videos in the shape other Actors and the Apify UI hand over. Merged with the list above and deduplicated by video id.
sourceDatasetIdRead video URLs out of another run's dataset, for chaining after a profile or hashtag Actor.
sourceDatasetFieldWhich field in that dataset holds the video URL. Defaults to url.
maxVideosA ceiling on how many of the supplied videos are scraped. One request per video, so this is also the request count.
requestDelayMsApplied across the whole run, not per worker, so this is the real interval between requests to TikTok whatever the concurrency. Measured from Apify datacenter IPs: 19 of 20 videos hydrated at 4s spacing, the single miss a timeout rather than a block.
maxConcurrencyHow many videos are fetched at once. The pacing above still bounds the overall request rate.
proxyConfigApify datacenter proxy, on by default, and used to retry a blocked video on a different IP. Residential is deliberately not used: it is billed per gigabyte and the transport was measured not to need it.
API
Bytewells speaks the Apify API. Existing integrations keep working: point apify-client at https://bytewells.com/api and use your Bytewells API token (Console → Settings → API access). The Actor ID is amethyst/tiktok-video-scraper (or amethyst~tiktok-video-scraper in URLs).
JavaScript · apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({
token: process.env.BYTEWELLS_TOKEN,
baseUrl: 'https://bytewells.com/api',
});
const input = {
"videos": [
"https://www.tiktok.com/@scout2015/video/6718335390845095173"
],
"maxVideos": 1000,
"requestDelayMs": 1500,
"maxConcurrency": 4,
"proxyConfig": {
"useApifyProxy": true
}
};
const run = await client.actor('amethyst/tiktok-video-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);Python · apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["BYTEWELLS_TOKEN"], api_url="https://bytewells.com/api")
run_input = {
"videos": [
"https://www.tiktok.com/@scout2015/video/6718335390845095173"
],
"maxVideos": 1000,
"requestDelayMs": 1500,
"maxConcurrency": 4,
"proxyConfig": {
"useApifyProxy": True
}
}
run = client.actor("amethyst/tiktok-video-scraper").call(run_input=run_input)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)HTTP · curl
curl -X POST "https://bytewells.com/api/v2/acts/amethyst~tiktok-video-scraper/runs" \
-H "Authorization: Bearer $BYTEWELLS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"videos":["https://www.tiktok.com/@scout2015/video/6718335390845095173"],"maxVideos":1000,"requestDelayMs":1500,"maxConcurrency":4,"proxyConfig":{"useApifyProxy":true}}'Runs are billed as compute from your credit balance. Paid Actors need an active rental or trial; otherwise the API answers 402 rental-required.
Related
More Actors from the same publisher.

TikTok Comments Scraper - Replies, Likes & Commenters
Eimantas V · @amethyst
Scrape TikTok comments and replies from video links or profiles: text, likes, reply counts, dates and commenter IDs. No login, no browser, flat monthly price.
Social mediaVideosMarketing$19/mo7-day free trial
YouTube Search Scraper - Videos, Shorts & Channels
Eimantas V · @amethyst
Scrape YouTube search results: videos, Shorts, channels and playlists with exact views, likes, dates and tags. Every filter, date ranges, deep search. No login.
Social mediaVideosMarketing$19/mo7-day free trial
Facebook Ads Library Scraper - Meta Ads, All Countries
Eimantas V · @amethyst
Scrape the Facebook Ads Library in any country: ad copy, images, videos, landing pages, CTAs, run dates and advertiser Pages. No login, no token needed.
MarketingSocial mediaBusiness$29/mo7-day free trial
Facebook Pages Scraper - Emails, Phones & Followers
Eimantas V · @amethyst
Scrape Facebook Pages by link, username or ID: email, phone, website, address, exact followers, category, rating and social links. No login or cookies.
Lead generationSocial mediaMarketing$19/mo7-day free trial
Facebook Posts Scraper - Pages, Profiles & Reactions
Eimantas V · @amethyst
Scrape posts from public Facebook Pages and profiles: text, date, reactions by type, comments, shares, video views and media. Date filters and new-post alerts.
Social mediaMarketingLead generation$19/mo7-day free trial
Instagram Profile Scraper - Followers, Posts & Emails
Eimantas V · @amethyst
Scrape Instagram profiles by username or URL: exact followers, following and posts, bio, links, emails and phones from bios, engagement rate, latest posts.
Social mediaLead generationMarketing$19/mo7-day free trial