# TikTok Video Scraper: Stats, Music, Hashtags & MP4 (`s_actors/tiktok-video-scraper`) Actor

Scrape TikTok videos and photo posts by link, ID or profile: views, likes, shares, saves, comments, hashtags, music, place, author followers. Download MP4 without watermark and photo post images. Tracks views between runs: growth since the last check and plays per day.

- **URL**: https://apify.com/s_actors/tiktok-video-scraper.md
- **Developed by:** [Superior Actors](https://apify.com/s_actors) (community)
- **Categories:** Social media, Videos, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.23 / 1,000 videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### TikTok Video Scraper: Stats, Music, Hashtags & MP4

Scrape **TikTok videos and photo posts** by link, ID or profile to CSV, Excel or JSON: **plays, likes, comments, shares, saves**, engagement rate, posting date, duration, **hashtags**, mentions, **sound**, **place and country**, TikTok categories and the **author's followers**. Optionally **download the MP4 without watermark** and all images of photo posts. Schedule it and every row shows **views growth since the last check**.

```json
{ "videos": ["https://www.tiktok.com/@nasa/video/7665075736742530317", "@nasa"], "downloadVideos": true }
```

No TikTok login, no cookies, no browser extension. Use it as a **TikTok video API**: one call returns clean JSON.

#### What you get

One row per video or photo post. Real example, October 2026:

| videoAuthorUsername | videoPlayCount | videoLikeCount | videoCommentCount | videoShareCount | videoSaveCount | engagementRate | hashtags |
|---|---|---|---|---|---|---|---|
| nasa | 1,500,000 | 99,200 | 2,925 | 3,189 | 7,264 | 7.5 | |
| tiktok | 559,300 | 12,300 | 1,470 | 478 | 770 | 2.69 | thevoice |
| nytimes (photo post, 10 images) | 3,103 | 58 | 2 | 3 | 4 | 2.16 | vancouver, canada, travel |

| Field | Description |
|---|---|
| `videoId`, `videoUrl`, `videoDescription`, `videoCreatedAt` | Video ID, link, caption and exact posting time (UTC) |
| `videoPlayCount`, `videoLikeCount`, `videoCommentCount`, `videoShareCount`, `videoSaveCount` | Plays, likes, comments, shares and saves as TikTok shows them |
| `engagementRate` | (likes + comments + shares + saves) / plays, in % |
| `durationSeconds`, `width`, `height`, `definition`, `coverUrl` | Video length, size, quality (`720p`, `1080p`) and cover image |
| `isPhotoPost`, `photoTitle`, `imageUrls` | Photo posts (slideshows) with links to every image |
| `hashtags`, `mentions` | Hashtags and mentioned @usernames from the caption |
| `musicTitle`, `musicAuthor`, `musicId`, `musicIsOriginal`, `musicDurationSeconds`, `musicUrl`, `musicAudioUrl`, `musicCoverUrl` | The sound: title, artist, original or not, sound page and audio file |
| `language`, `subtitleLanguages`, `categories` | Caption language, available subtitles, TikTok's topic categories (`Science`, `Entertainment`...) |
| `locationCountry`, `placeName`, `placeAddress`, `placeCity`, `placeCategory` | Country the video was posted from and the tagged place |
| `isAd`, `isAiGenerated`, `duetEnabled`, `stitchEnabled` | Ad, AI-generated label, duet and stitch settings |
| `videoAuthorUsername`, `videoAuthorName`, `videoAuthorId`, `videoAuthorSecUid`, `videoAuthorVerified`, `videoAuthorBio`, `videoAuthorAvatarUrl` | The creator |
| `videoAuthorFollowerCount`, `videoAuthorFollowingCount`, `videoAuthorLikeCount`, `videoAuthorVideoCount` | Creator's followers, following, total likes and number of videos |
| `videoFileUrl`, `imageFileUrls`, `coverFileUrl` | Permanent download links with **Download videos** / **Download covers** |
| `videoPlayCountChange`, `videoLikeCountChange`, `videoCommentCountChange`, `videoShareCountChange`, `videoSaveCountChange`, `playsPerDaySinceLastCheck`, `previousCheckAt`, `history` | Views tracker: growth since the previous check and the last 30 checks |
| `input`, `inputProfile`, `position`, `scrapedAt` | Which input the row came from |

TikTok rounds plays, likes, comments and shares from 10,000 on its own website (1.5M = 1,500,000); saves are exact. Every tool that reads TikTok without logging in gets the same numbers.

#### How it works

1. Add **videos or profiles**: `tiktok.com/@user/video/...`, photo posts `/photo/...`, short links `vm.tiktok.com/...`, video IDs, `tiktok.com/@user` or `@user`
2. Optional: **Download videos (MP4)**, **Download covers**
3. Run, then download the dataset as CSV, Excel, JSON or HTML. Files are in the run's **Storage → Key-value store**

| Input | What it does |
|---|---|
| **TikTok videos or profiles** | Any mix of links, IDs and profiles. A profile gives its latest videos (**Videos per profile**, default 5, `0` = all) |
| **Download videos (MP4)** | MP4 without watermark for videos, every image (JPG) for photo posts |
| **Download covers** | Cover JPG, free (TikTok's own cover links expire after a few days) |
| **Track views over time** | On by default: each row shows growth since this video was last checked |

A video that is deleted, private or not found gives a row with `error` and is not charged.

#### Why this Actor

| | |
|---|---|
| 📈 **Views tracker** | Schedule it daily or hourly: plays, likes, comments, shares and saves gained since the last check, plays per day, last 30 checks |
| ⬇️ **MP4 without watermark** | Clean video files and photo post images with permanent links |
| 📍 **Place, country and categories** | Tagged place with address, posting country, TikTok's topic labels, AI-generated flag |
| 🎵 **Sound details** | Title, artist, original or not, sound page and audio file link |
| 👤 **Creator stats on every row** | Followers, total likes and video count of the author |
| 💰 **$0.29 per 1,000 videos** | Several times cheaper than the popular TikTok video scrapers, no subscription |

#### Views tracker: monitor your videos

1. Add the videos you want to follow (yours, competitors', a campaign's)
2. Save as a task and add a schedule, e.g. every morning
3. **First run** stores the stats. **Every later run** adds `videoPlayCountChange`, `playsPerDaySinceLastCheck` and the other changes, plus `history` with the last 30 checks: ready for a chart

The history is kept in your account (key-value store `tiktok-video-history`) and is shared by all your runs and tasks. Connect [Google Sheets](https://apify.com/s_actors/google-sheets-import-export), Slack or email with an integration to receive the numbers.

#### Pricing

Pay per result, no subscription needed. Apify Scale and Business plans pay less:

| Event | Free and Starter plans | Scale plan | Business plan |
|---|---|---|---|
| Run start | $0.001 | $0.001 | $0.001 |
| Video in the results | $0.00029 | $0.000261 | $0.000232 |
| Video download (MP4 or photo post images) | $0.00099 | $0.000891 | $0.000792 |

| Task | Cost |
|---|---|
| Stats of 1,000 videos | ~$0.29 |
| 100 videos with MP4 download | ~$0.13 |
| Daily views tracker of 20 videos for a month | ~$0.20 per month |

Videos that are not found are not charged. Storing downloaded files uses your Apify storage.

#### Ready-made tasks

Open it, change the videos, and run:

| Task | What you get |
|---|---|
| [TikTok Video Stats Checker: Views, Likes, Shares](https://apify.com/s_actors/tiktok-video-scraper/examples/tiktok-video-stats-checker) | Plays, likes, comments, shares and saves of a list of videos |

#### FAQ

**Are the view counts exact?** They are the numbers TikTok shows on its website. TikTok itself rounds plays, likes, comments and shares from 10,000 (for example 1.5M), so small changes of big videos show up in steps. Saves and smaller numbers are exact.

**Does the MP4 have a watermark?** No, the Actor saves the clean version TikTok plays on its website. Photo posts give every image as a JPG.

**How long do the download links work?** `videoFileUrl`, `imageFileUrls` and `coverFileUrl` point to your Apify storage and work as long as the run's storage is kept (unnamed storages are removed after your plan's data retention period). TikTok's own links (`coverUrl`, `imageUrls`, `musicAudioUrl`) expire after a few days.

**How many videos of a profile?** All of them: set **Videos per profile** to `0` for every video of the profile, or a number for the latest ones (newest first).

**Does it work with short links and photo posts?** Yes: `vm.tiktok.com`, `vt.tiktok.com` and `tiktok.com/t/` links and `/photo/` posts work like videos.

**Do I need a TikTok account or cookies?** No. The Actor reads public videos the way the TikTok website does for a visitor.

#### Use with the API and AI agents

Run it via the [Apify API](https://docs.apify.com/api/v2) from Python, Node.js or any HTTP client, or connect it to Claude, ChatGPT and other AI agents through the [Apify MCP server](https://mcp.apify.com): "Which of these 30 TikToks gained the most views this week?"

#### Other tools

| Tool | What it does |
|---|---|
| [TikTok Profile Scraper](https://apify.com/s_actors/tiktok-profile-scraper) | All videos of TikTok profiles: plays, likes, dates, exact followers, new-video alerts, MP4 download |
| [TikTok Comments Scraper](https://apify.com/s_actors/tiktok-comments-scraper) | Comments and replies of TikTok videos and profiles, keyword filter, only-new alerts |
| [TikTok Transcript Scraper](https://apify.com/s_actors/tiktok-transcript-scraper) | Transcripts and subtitles of TikTok videos and profiles: text, SRT, VTT, translations |
| [TikTok Followers Scraper](https://apify.com/s_actors/tiktok-followers-scraper) | Followers and following lists of TikTok profiles: bio emails, follow time, new followers and unfollows |
| [TikTok Trending Hashtags Scraper](https://apify.com/s_actors/tiktok-trending-hashtags-scraper) | Trending TikTok hashtags by country: ~45 per country (not just the top 3), views, trend curve, top creators, new-trend alerts |
| [TikTok Trending Videos Scraper](https://apify.com/s_actors/tiktok-trending-videos-scraper) | Top TikTok videos by country: ~80 per country (not just the top 4), period and organic views, engagement, likes, creators, new-video alerts |
| [TikTok Viral Videos & Explore Scraper](https://apify.com/s_actors/tiktok-explore-scraper) | Viral TikTok videos from the Explore page in any country and 21 categories: plays, likes, plays per hour, creators, new-video alerts |
| [TikTok Trending Sounds & Songs Scraper](https://apify.com/s_actors/tiktok-trending-sounds-scraper) | Trending TikTok sounds and songs by country and Explore category: videos using each sound, plays, creators, commercial use, MP3 |
| [YouTube Video Details Scraper](https://apify.com/s_actors/youtube-video-details-scraper) | Exact views, likes, tags and views history of YouTube videos |
| [Telegram Channel Analytics](https://apify.com/s_actors/telegram-channel-analytics) | Exact subscribers, reach and ads of public Telegram channels |
| [Google Sheets Import & Export](https://apify.com/s_actors/google-sheets-import-export) | Send the video stats to a Google Sheet |

#### Is it legal?

The Actor collects only public videos and stats that TikTok shows to any visitor, without logging in. Videos and their captions are the creators' content: respect copyright when you reuse downloaded files, and use personal data such as usernames in line with GDPR and other privacy laws.

# Actor input Schema

## `videos` (type: `array`):

One per line: video or photo post links (tiktok.com/@user/video/..., /photo/...), short links (vm.tiktok.com/..., tiktok.com/t/...), video IDs, or profiles (tiktok.com/@user or @user). A profile gives its latest videos (see Videos per profile).

## `maxVideosPerProfile` (type: `integer`):

Used only when you add a profile (tiktok.com/@user or @user): how many of its latest videos to scrape, newest first. 0 = all videos of the profile. Video links are not affected.

## `downloadVideos` (type: `boolean`):

Save each video as an MP4 without the TikTok watermark (and all images of photo posts as JPG) to the run's key-value store. The row gets videoFileUrl (or imageFileUrls). Charged per downloaded video, on top of the video row.

## `downloadCovers` (type: `boolean`):

Save each video's cover image (JPG) to the run's key-value store and add coverFileUrl to the row. Free. TikTok's own cover links (coverUrl) stop working after a few days.

## `trackHistory` (type: `boolean`):

Stores plays, likes, comments, shares and saves of each video at every run in your account (key-value store tiktok-video-history) and adds videoPlayCountChange, videoLikeCountChange, videoCommentCountChange, videoShareCountChange, videoSaveCountChange, playsPerDaySinceLastCheck and the last 30 checks (history) to each row. The first run has no change yet.

## `maxConcurrency` (type: `integer`):

How many videos are scraped at the same time. Downloads run at most 3 at a time.

## `proxyConfiguration` (type: `object`):

Requests go direct first and switch to Apify datacenter proxies (then residential) when TikTok refuses them. The default works for most runs.

## `debugLog` (type: `boolean`):

Log every retried request (for troubleshooting).

## Actor input object example

```json
{
  "videos": [
    "https://www.tiktok.com/@charlidamelio/video/7137423965982592302",
    "https://www.tiktok.com/@nasa/video/7665075736742530317"
  ],
  "maxVideosPerProfile": 5,
  "downloadVideos": false,
  "downloadCovers": false,
  "trackHistory": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "debugLog": false
}
```

# Actor output Schema

## `overview` (type: `string`):

Plays, likes, comments, shares, saves, engagement, date, hashtags, sound, MP4 link.

## `tracker` (type: `string`):

Growth since the previous check of each video: plays, likes, comments, shares, saves, plays per day.

## `files` (type: `string`):

MP4s, photo post images and covers saved by the run.

## `all` (type: `string`):

Every field of every row.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videos": [
        "https://www.tiktok.com/@charlidamelio/video/7137423965982592302",
        "https://www.tiktok.com/@nasa/video/7665075736742530317"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s_actors/tiktok-video-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "videos": [
        "https://www.tiktok.com/@charlidamelio/video/7137423965982592302",
        "https://www.tiktok.com/@nasa/video/7665075736742530317",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("s_actors/tiktok-video-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videos": [
    "https://www.tiktok.com/@charlidamelio/video/7137423965982592302",
    "https://www.tiktok.com/@nasa/video/7665075736742530317"
  ]
}' |
apify call s_actors/tiktok-video-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s_actors/tiktok-video-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Y8KrLvORemEOTG3X9/builds/VSphpGjTHIM1dYiaX/openapi.json
