TikTok Scraper avatar

TikTok Scraper

Pricing

from $10.00 / 1,000 tiktok video downloadeds

Go to Apify Store
TikTok Scraper

TikTok Scraper

Download TikTok videos without watermark, plus TikTok profiles, hashtags, comments-free video metadata, explore feed and keyword suggestions. 6 modes, no login or cookies needed.

Pricing

from $10.00 / 1,000 tiktok video downloadeds

Rating

0.0

(0)

Developer

Monster Leads

Monster Leads

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

TikTok Scraper — Download TikTok Videos Without Watermark

Download TikTok videos and scrape TikTok profiles, TikTok hashtags, TikTok trending videos and TikTok keyword suggestions — all from one TikTok scraper. No TikTok login, no TikTok cookies, no browser, no API key from TikTok.

Paste any TikTok link and get back a direct MP4 download URL in about a second, plus every quality TikTok offers and the full metadata around the video: creator, follower count, views, likes, comments, shares, the sound and the cover image.

The MP4 URLs this TikTok scraper returns are plain CDN links. Open one in a browser, hand it to curl, wget, yt-dlp or your own downloader — no special headers and no session required.


⬇️ Download TikTok videos (the main feature)

This is what most people come here for, so it is the default mode. Give the TikTok Scraper a list of TikTok links and it returns direct MP4 URLs for each TikTok video.

Input

{
"mode": "download",
"videoUrls": [
"https://www.tiktok.com/@nasa/video/7665075736742530317",
"https://vm.tiktok.com/ZMabcdefg/",
"7665075736742530317"
]
}

Every TikTok link format works. You do not have to clean anything up first:

What you pasteWorks?
https://www.tiktok.com/@nasa/video/7665075736742530317✅ Full TikTok link
https://vm.tiktok.com/ZMabcdefg/✅ TikTok short link (redirect followed for you)
https://vt.tiktok.com/ZSabcdefg/✅ TikTok short link, other domain
https://www.tiktok.com/@user/photo/7665075736742530317✅ TikTok photo post
https://www.tiktok.com/v/7665075736742530317✅ Legacy TikTok link
7665075736742530317✅ Bare TikTok video ID

Output — one row per TikTok video

{
"type": "video",
"video_id": "7665075736742530317",
"desc": "A supermoon rises behind the Washington Monument 🌕 #nasa #moon",
"hashtags": ["nasa", "moon"],
"duration_seconds": 15,
"download_url": "https://v16-webapp-prime.tiktok.com/video/tos/useast2a/…",
"download_url_watermarked": "https://v16-webapp-prime.tiktok.com/video/tos/useast2a/…",
"mirrors": [
"https://v16-webapp-prime.tiktok.com/video/tos/useast2a/…",
"https://v19-webapp-prime.tiktok.com/video/tos/useast2a/…"
],
"qualities": [
{
"gear": "normal_1080_0",
"bitrate": 2419521,
"codec": "h264",
"format": "mp4",
"width": 1080,
"height": 1920,
"size": 4538291,
"url": "https://v16-webapp-prime.tiktok.com/video/tos/useast2a/…",
"mirrors": ["…", "…", "…"]
},
{ "gear": "lower_540_0", "bitrate": 843122, "width": 540, "height": 960, "…": "…" }
],
"cover": "https://p16-sign.tiktokcdn-us.com/obj/tos-useast5-p-0068-tx/…",
"width": 1080,
"height": 1920,
"file_size_bytes": 4538291,
"author": "nasa",
"nickname": "NASA",
"tiktok_url": "https://www.tiktok.com/@nasa/video/7665075736742530317"
}

The qualities ladder

Every quality TikTok encoded is returned, sorted highest bitrate first. Take qualities[0] for the best file, or the last entry for the smallest.

Each quality carries its own mirrors — the same file on several TikTok CDN hosts. If one host is slow or refuses a connection, retry the next mirror instead of scraping the video again.

download_url is the stream TikTok's own player uses. download_url_watermarked is TikTok's "save video" URL. Which one carries a visible watermark is TikTok's choice and it varies by video, so both are given rather than promising a clean file that TikTok might not serve.


👤 Scrape a TikTok profile

Get a TikTok creator's follower count, total likes, video count, bio, region and verification status — plus their recent TikTok videos.

{
"mode": "profile",
"profileUrls": ["https://www.tiktok.com/@nasa", "@khaby.lame", "bbc"],
"maxProfileVideos": 10
}

Full links, @handles and bare usernames all work. TikTok numeric user IDs do not — TikTok's profile pages key on the username only.

{
"type": "profile",
"unique_id": "nasa",
"nickname": "NASA",
"user_id": "6727327145951183874",
"sec_uid": "MS4wLjABAAAA…",
"signature": "Exploring the universe and our home planet.",
"avatar": "https://p16-sign.tiktokcdn-us.com/…",
"verified": true,
"private": false,
"region": "US",
"follower_count": 8300000,
"following_count": 12,
"heart_count": 91700000,
"video_count": 512,
"profile_url": "https://www.tiktok.com/@nasa"
}

On follower and like counts: TikTok's own web payload overflows heartCount into a negative number for very large creators (a 32-bit integer bug on TikTok's side). This TikTok scraper reads the string-typed statsV2 values instead, so the totals you get are the accurate ones.


#️⃣ Scrape a TikTok hashtag

Get the numbers behind a TikTok topic — total views across the hashtag and how many TikTok videos use it — plus a sample of the videos themselves.

{
"mode": "hashtag",
"hashtags": ["fyp", "cooking", "https://www.tiktok.com/tag/booktok"],
"maxHashtagVideos": 10
}
{
"type": "hashtag",
"tag": "cooking",
"hashtag_id": "17951",
"desc": "Show us what's on the menu.",
"view_count": 546058192966,
"video_count": 8241033,
"is_commerce": false,
"hashtag_url": "https://www.tiktok.com/tag/cooking"
}

Set maxHashtagVideos to 0 to get only the stats row. That is the cheapest way to compare the reach of many TikTok hashtags at once — one row and one charge per hashtag.

TikTok reports videoCount as 0 on one of its endpoints and rounds viewCount to the nearest hundred million on another. This TikTok scraper reads the precise values, so 546058192966 is the real figure, not 546100000000.


🧭 Scrape the TikTok explore feed

TikTok's public recommendation feed — trending TikTok videos with full engagement stats.

{ "mode": "explore", "maxExploreVideos": 8 }

Explore rows carry the complete stat set: play_count, digg_count, comment_count, collect_count, share_count, the sound, and the video's own hashtag list.


🔎 TikTok keyword suggestions

The terms TikTok's own search box suggests — real TikTok search demand, for SEO and hashtag research.

{ "mode": "keywords", "keyword": "cooking" }
{
"type": "keyword",
"word": "cooking asmr",
"seed_keyword": "cooking",
"group_id": "6549558169829721606",
"search_url": "https://www.tiktok.com/search?q=cooking%20asmr"
}

TikTok localises suggestions by region, so the same seed returns different terms in different markets.


ℹ️ TikTok video info only

Title, creator, cover and embed code for a TikTok video, without resolving download URLs. Use it when you only need to identify a video rather than fetch it.

{ "mode": "videoInfo", "videoUrls": ["https://www.tiktok.com/@nasa/video/7665075736742530317"] }

How many TikTok results can I get?

Read this before planning a large TikTok scrape — it is the one thing that surprises people.

ModeResults per callPagination?
⬇️ Download TikTok videos1 per link, unlimited linksn/a — paste as many TikTok links as you want
ℹ️ TikTok video info1 per link, unlimited linksn/a
👤 TikTok profile1 profile + ~10 videos❌ TikTok caps the video list
#️⃣ TikTok hashtag1 stats row + ~10 videos❌ TikTok caps the video list
🧭 TikTok explore8 videos❌ TikTok returns one batch
🔎 TikTok keywords~8 suggestions❌ fixed by TikTok

Download and Video info scale without limit — give this TikTok scraper 10,000 TikTok links and you get 10,000 rows.

The listing modes do not, and that ceiling belongs to TikTok, not to this actor. TikTok's embed pages serve roughly 10 videos and ignore every pagination parameter — cursor, offset, page and count all return the identical batch. Asking for 500 videos from one TikTok hashtag returns about 10, and the run log tells you so rather than leaving you to guess.

Two ways to work with that:

  1. Collect over time. The explore feed and hashtag pages rotate. A scheduled run every few hours accumulates a much larger TikTok dataset than any single run can.
  2. Fan out. Scrape 50 TikTok hashtags at ~10 videos each rather than expecting 500 from one.

You are only ever charged for rows actually delivered, so a capped result never costs you what you asked for.


Pricing

This TikTok scraper is pay per result — $1 per 1,000 list results. Nothing is charged when TikTok refuses an item.

EventPriceWhat it is
TikTok video downloaded$0.01One TikTok video resolved to MP4 URLs with the full quality ladder
TikTok profile scraped$0.01One TikTok creator's stats, bio and verification
TikTok hashtag scraped$0.01One TikTok hashtag's total views and video count
TikTok video info scraped$0.01One TikTok video's title, creator and cover
TikTok video listed$0.001One TikTok video from a hashtag, profile or the explore feed
TikTok keyword scraped$0.001One TikTok search suggestion

Worked examples

What you runCost
Download 100 TikTok videos$1.00
1,000 TikTok keyword suggestions$1.00
One TikTok hashtag: stats + 10 videos$0.02
50 TikTok hashtags, stats only$0.50
One TikTok profile + 10 videos$0.02
Explore feed, 8 TikTok videos$0.008

Single fetches cost 10× a list row because each one is a full page load through its own residential proxy — one such call does the work of about ten list rows.

Failed TikTok items are free. A deleted, private or region-locked TikTok video still appears in your dataset with an error field explaining what happened, and it is never charged. You always see which inputs failed.


Output formats

Every run writes to a standard Apify dataset. Export as JSON, CSV, Excel, XML, JSONL, HTML or RSS, or pull it through the Apify API from Python, Node.js or curl.

The dataset has ready-made views: Overview (all TikTok result types side by side), TikTok videos, TikTok profiles, TikTok hashtags and TikTok keywords.

Missing engagement stats are null, never 0. A TikTok video scraped from a hashtag page has digg_count: null because TikTok's embed page does not send like counts — that is different from a video with zero likes, and this TikTok scraper does not blur the two.


Frequently asked questions

Do I need a TikTok account or cookies? No. This TikTok scraper needs no TikTok login, no cookies and no TikTok API key.

Can I download TikTok videos without a watermark? Both URLs TikTok exposes are returned: the stream its player uses and its "save video" URL. Which is watermark-free depends on the video, so pick whichever suits and check the file.

Can anyone open the download URLs? Yes — they are ordinary CDN links. No headers, no cookies and no proxy needed. Download them from anywhere.

Do the download URLs expire? TikTok's CDN links are signed and do not stay valid forever. Fetch the file reasonably soon rather than storing URLs for weeks, and re-run the actor if a link has gone stale.

Can I scrape TikTok comments? Not in this version. TikTok's comment endpoint requires a logged-in session, which this scraper deliberately avoids. Only public TikTok data is collected.

Can I get more than 10 videos from a TikTok hashtag? Not in one call — see How many TikTok results can I get?. Schedule repeat runs or fan out across more hashtags.

Is scraping TikTok legal? This TikTok scraper collects only public TikTok data — no login, no private accounts, no personal data behind a barrier. You are responsible for how you use what you collect, including copyright in TikTok videos and any applicable data-protection rules. Downloaded TikTok videos belong to their creators.

Can I run this TikTok scraper on a schedule? Yes. Use Apify Schedules to run it hourly or daily — the recommended way to build a large TikTok dataset given TikTok's per-call caps.


Integrations

Connect this TikTok scraper to Zapier, Make, n8n, Slack, Google Sheets, Airtable, GitHub or any webhook through the Apify platform, or drive it from the Apify API.

from apify_client import ApifyClient
client = ApifyClient('<YOUR_API_TOKEN>')
run = client.actor('tiktok-scraper').call(run_input={
'mode': 'download',
'videoUrls': ['https://www.tiktok.com/@nasa/video/7665075736742530317'],
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
print(item['download_url'])