TikTok Scraper - Videos, Profiles & Comments
Pricing
from $2.00 / 1,000 results
TikTok Scraper - Videos, Profiles & Comments
Collect public TikTok videos, profiles, hashtag feeds, search results and available comments. Export engagement counts, bios and media links. Pay per delivered row, plus a small start fee.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
57
Total users
5
Monthly active users
a day ago
Last modified
Categories
Security
Limited permissionsShare
TikTok Scraper
Collect public TikTok videos, profiles and available comments from tiktok.com as rows you can export, without selecting a country.
- Read video descriptions, engagement counts, hashtags and media links.
- Collect profile identity, bios, public statistics and website links.
- Choose profile-only collection or request videos by creator, hashtag, keyword or direct link.
- Optionally add comment rows or save downloadable video files.
- Pay only for the rows you receive: $2.00 per 1,000 rows on the Free plan, plus a small start fee.
What does TikTok Scraper do?
TikTok Scraper collects publicly available content from tiktok.com. Results depend on what TikTok makes available for each input; the Actor does not promise every post or every field. There is no country selector or guarantee of coverage in a particular market.
- Creator videos (
user): enterprofilesto request a creator's videos; available profile rows may also be returned. - Profile only (
profile): enterprofilesfor public profile metadata without requesting posts. - Hashtags (
hashtag): enterhashtagsfor tagged videos. - Search (
search): enterkeywordsfor matching videos. - Specific videos (
video): entervideoUrlsfor individual video details. - Comments:
includeCommentsis off by default. Available comments become separate rows, billed at the same price as video and profile rows.
What data can you extract from TikTok?
The _type field distinguishes video, profile and comment rows. Fields vary by row type and availability.
Video rows
| Field | Description | Example |
|---|---|---|
_type | Row type | video |
videoId | TikTok video identifier | 7352941836204917025 |
videoUrl | Link to the video page | https://www.tiktok.com/@example/video/7352941836204917025 |
description | Video caption | A cooking idea #recipe |
author | Creator's username | example |
playCount | Reported views | 12000 |
likeCount | Reported likes | 850 |
commentCount | Reported comment count, not collected comment rows | 45 |
shareCount | Reported shares | 30 |
collectCount | Reported saves | 120 |
duration | Duration in seconds | 42 |
hashtags | Tags attached to the video | ["recipe"] |
playUrl | Source media link, which may expire | https://example.com/video.mp4 |
downloadUrl | Saved file link after a successful download | https://api.apify.com/v2/key-value-stores/STORE_ID/records/video_7352941836204917025.mp4 |
Video rows can also contain authorName, authorVerified, coverUrl, width, height, musicTitle, musicAuthor, createTime and scrapedAt.
Profile rows
| Field | Description | Example |
|---|---|---|
_type | Row type, also used in profile-only mode | user |
uniqueId | TikTok username | example |
nickname | Public display name | Jane Doe |
signature | Profile bio | Cooking ideas |
followerCount | Reported followers | 12000 |
followingCount | Reported accounts followed | 150 |
heartCount | Total profile likes | 45000 |
videoCount | Reported number of videos | 85 |
profileUrl | Public profile link | https://www.tiktok.com/@example |
web | Website and social links when available | {"website":"https://example.com","socials":[]} |
Profile rows may include verified and avatar. A limited profile response can have metadataOnly: true and omit statistics. Public contact fields such as phones and emails can be empty; leadAbsences explains missing contact details. A public handle is not proof of a legal name or company identity.
Comment rows
| Field | Description | Example |
|---|---|---|
_type | Row type | comment |
commentId | Comment identifier | 7352941836204917001 |
videoId | Parent video identifier when supplied | 7352941836204917025 |
text | Comment text | Thanks for sharing |
author | Commenter's public username | example |
replyCount | Reported reply count, not collected replies | 2 |
Comment rows can also contain authorName, likeCount, createTime and scrapedAt.
How to scrape TikTok
- Open TikTok Scraper in Apify Console. A free Apify account is enough to try it.
- Leave
modeonautoand fill one target list, such asprofiles. - Set
maxResultsto 5 for your first run. - Click Start and wait for completion.
- Open the dataset and download JSON, CSV or Excel, or read rows through the API.
An empty input ({}) starts an example run for the sample profile openai, using user mode and at most 3 rows. It uses the normal pricing, not a separate free preview. Filling one target list selects its mode automatically; profile-only collection requires mode: "profile".
Creator videos
Fill profiles with usernames or profile URLs. Automatic mode selects user. Profile rows and video rows share the limit. If posts are unavailable, available profile rows can still be saved; check RUN_SUMMARY and the status message for missing videos.
Profile only
Set mode to profile and fill profiles. This requests one profile row per available account, without posts. Increasing the row limit does not create extra profile rows.
Hashtag videos
Fill hashtags with tags such as travel, without #. Availability can differ from profile collection; the requested feed may return no usable rows.
Keyword search
Fill keywords with search phrases such as cooking tips. The input has no date filter or country selector. Results are not a complete catalogue of matching TikTok videos.
Specific videos
Fill videoUrls with full TikTok video-page URLs. Duplicate video targets are collected once. Without comments, one available video yields one video row. Enable downloadVideos to attempt saving its media file.
What to fill in
| Field | What to enter | Default |
|---|---|---|
mode | auto, user, profile, hashtag, search or video | auto |
profiles | Usernames or full profile URLs | No target default; sample openai |
hashtags | Tags without # | Empty |
keywords | Search phrases | Empty |
videoUrls | Full video-page URLs | Empty |
startUrls | Profile, tag, search or video URLs; sorted into the matching lists | No target default; sample profile URL |
maxResults | Row limit per input, from 1 to 1,000 | 70; sample 3 |
includeComments | Include available comments as separately billed rows | false |
enrichDetails | Include available public identity, bio-link and contact details | true |
downloadVideos | Attempt to save video files to the run's key-value store | false |
maxScrolls | Content-loading limit, from 1 to 50 | 15 |
pageTimeout | Page loading timeout, from 60 to 300 seconds | 120 |
resultsPerPage | Alternative name that overrides maxResults when set | Unset |
Creator videos:
{"mode":"user","profiles":["openai"],"maxResults":5}
Profile only:
{"mode":"profile","profiles":["openai"],"maxResults":1}
Hashtag videos:
{"mode":"hashtag","hashtags":["travel"],"maxResults":5}
Keyword search:
{"mode":"search","keywords":["cooking tips"],"maxResults":5}
Specific video; replace the illustrative URL with an existing public video:
{"mode":"video","videoUrls":["https://www.tiktok.com/@example/video/7352941836204917025"],"maxResults":1}
maxItemsandlimitare accepted as aliases formaxResults.- In automatic mode, URLs are sorted first, then video targets take priority over profiles, hashtags and keywords. Other target lists are ignored. Use separate runs for different modes.
- Close field-name misspellings can be corrected; other unknown fields are ignored with a note. Numeric limits can be adjusted to their supported range.
- Invalid targets stop the run with a field-specific message, such as
INVALID_INPUT: startUrls — use TikTok links. No result rows are charged; the start fee may still apply. INPUT_REPORTin the run's key-value store records input resolution, corrections, ignored fields and errors.INPUT_ECHOshows the effective settings.
Output example
Illustrative video row; values below are not a live measurement:
{"_type": "video","videoId": "7352941836204917025","videoUrl": "https://www.tiktok.com/@example/video/7352941836204917025","description": "A cooking idea #recipe","author": "example","authorName": "Jane Doe","playCount": 12000,"likeCount": 850,"commentCount": 45,"shareCount": 30,"collectCount": 120,"duration": 42,"hashtags": ["recipe"],"scrapedAt": "2026-10-24T08:00:00Z"}
Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. JSON preserves nested contact and link fields.
Why use this TikTok scraper?
- Pay per delivered row. Video, profile and comment rows use the same price.
- Keep available results. A missing target does not erase other delivered rows. Rows already written to the dataset remain available if a run stops.
- Understand missing data. Unavailable counts can be null or omitted; missing videos are reported rather than treated as proof of an empty account.
- Several inputs per run. Submit multiple targets of the same mode, with a limit for each input.
- No setup. You do not need to set up proxies or supply a TikTok account or cookies.
How much does it cost to scrape TikTok?
The Actor uses pay-per-event pricing. Each delivered row costs $0.002. The start event costs $0.00005 per GB of allocated memory, with a minimum of one event. At the default 1024 MB, one start costs $0.00005. Platform usage is included in these prices.
| Apify plan | Price per row | Price per 1,000 rows |
|---|---|---|
| Free | $0.002 | $2.00 |
| Starter | $0.002 | $2.00 |
| Scale | $0.002 | $2.00 |
| Business | $0.002 | $2.00 |
maxResultsapplies to each input: default 70, maximum 1,000. All row types share that allowance; it is not a promised result count.- The Free plan allows up to 200 rows per run and 10 total runs of this Actor. These are developer-set limits. Paid plans do not have this 10-run cap.
- The whole run is bounded by Maximum cost per run (
maxTotalChargeUsdin the API). A smaller spending allowance reduces the rows collected and delivered.
Example: 3 inputs delivering 5 rows each produce 15 rows. At 1024 MB, one start plus those rows costs 15 × $0.002 + $0.00005 = $0.03005 on the Free plan. Comment rows count toward the 15; enabling comments does not create a separate free allowance.
What happens when the run timeout is too short
If collection needs more time than the chosen timeout and automatic resumption is accepted, the run pauses instead of immediately failing. Its status message reads "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." It appears as ABORTED while paused.
When results are ready, the same run restarts automatically, reports "Resumed: delivering N rows.", writes rows to the same dataset and finishes as SUCCEEDED after successful delivery. Previously delivered rows are not delivered or charged again. You do not need to start another run.
- Automatic pauses are limited to 3 per run. Keep the normal 1800-second timeout to reduce interruptions.
run-syncandrun-sync-get-dataset-itemswait at most 300 seconds and can return an empty dataset during a pause. Start longer runs asynchronously, then read the dataset after SUCCEEDED, or use a succeeded-event webhook.- A manual abort or a collection error is not the same as this automatic pause. Check the status message before assuming the run will resume.
Use with AI agents and the API
Apify MCP server (Claude, ChatGPT, Cursor, VS Code)
Add this Actor to a client that supports remote MCP servers:
https://mcp.apify.com?tools=lentic_clockss/tiktok-scraper
Sign in with Apify using OAuth when prompted, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool returns run and dataset IDs; the agent can read rows with get-dataset-items. Enable that tool in the MCP client too if it is not already available.
Clients without remote MCP support can run npx @apify/actors-mcp-server --tools lentic_clockss/tiktok-scraper with APIFY_TOKEN set.
Example prompt: "Use TikTok Scraper in profile mode to get the public profile for openai, with maxResults set to 1. Show the bio and any available follower count."
Apify API
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/tiktok-scraper").call(run_input={"mode": "profile", "profiles": ["openai"], "maxResults": 1})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/tiktok-scraper').call({mode: 'profile', profiles: ['openai'], maxResults: 1});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
For asynchronous HTTP calls, send POST https://api.apify.com/v2/acts/lentic_clockss~tiktok-scraper/runs with JSON input and an Authorization: Bearer <YOUR_APIFY_TOKEN> header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.
Integrations
Use the Actor's Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable or your own webhook. Use Apify Schedules for repeated runs, and check run status as well as row counts.
FAQ
Is it legal to scrape TikTok?
This Actor targets public data, not private accounts. Public availability is not permission for every use. You are responsible for TikTok's terms, applicable data protection law and a lawful basis for processing personal data.
Why did my run end as ABORTED?
The automatic pause described above temporarily uses ABORTED. Look for the message saying it will resume automatically. A manually aborted run or a different error should not be treated as a scheduled resumption.
How many results can I get?
Up to maxResults rows per input, subject to availability, spending limits and the Free-plan cap. A profile-only input normally yields one row, even with a larger limit.
Why are some fields empty?
TikTok may not expose a statistic, contact detail or media link. Missing counts can be null or omitted. metadataOnly: true identifies a limited profile response; an absent count should not be read as zero.
Can I collect profiles without videos?
Yes. Use mode: "profile" with profiles. Automatic profile input instead selects user, which requests creator videos and may return profile rows.
Can I download video files?
Set downloadVideos to true. Successful downloads add downloadUrl without another dataset row. Files over 50 MiB are skipped. Download success and permanent storage are not guaranteed.
Does including comments collect every comment and reply?
No. includeComments requests available comment rows within the same limits. There is no dedicated full-comment or reply-history mode, and the reported commentCount is not the number of comments collected.
Why did a Free-plan run stop with a limit message?
The Actor allows 10 total runs and up to 200 rows per run on the Free plan. The limit message explains the restriction; paid plans are not subject to the 10-run cap.
Limitations
- Private accounts, login-only content and complete historical coverage are not supported.
- Search, hashtag feeds and creator posts may be unavailable even when a profile or direct video works. No usable rows can mean a failed run, not zero matching content.
- No country, date-range or guaranteed ranking filter is offered.
- Contact details are limited to available public information. A location label is not a street address or verified coordinates.
- Downloads depend on an available media link. Retain your own copy if long-term access matters.
Related scrapers
More social media and video scrapers from the same publisher:
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Found a problem or need another field? Open an issue in the Issues tab of this Actor's page and include the run ID and the input you used.