# TikTok Video, Profile & Comments Scraper — No Login (`cycha/tiktok-scraper`) Actor

Full TikTok video stats (plays, likes, comments, shares, saves, music, hashtags) from any video URL, exact profile stats for any username, and the comments and replies of each video. No login, no API key, no proxies needed.

- **URL**: https://apify.com/cycha/tiktok-scraper.md
- **Developed by:** [Ken Digital](https://apify.com/cycha) (community)
- **Categories:** Social media
- **Stats:** 23 total users, 6 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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, Profile & Comments Scraper — No Login

Turn any TikTok video URL into a full stats row, and any username into exact profile numbers. Reads the data TikTok itself embeds in its pages, so it needs no login, no API key and no proxy, and it runs in seconds on 256 MB of memory.

> **New name:** this actor is now `cycha/tiktok-scraper` (it was `joyouscam35875/tiktok-scraper` until 21 October 2026). If an API call or integration stopped working, update the name, or use the actor ID `UV8NNxfGts4hDdg9f`, which never changes.

**Videos** (per URL or ID): plays, likes, comments, shares, saves, reposts, description, hashtags, mentions, post date, duration, cover, music (title, author, original or not), author (username, nickname, verified, followers, total likes), photo-post detection, country of creation, ad and AI-generated flags.

**Comments** (per video, optional): text, likes, reply count, pinned and liked-by-creator flags, post date, language, author username, nickname and avatar, plus threaded replies with `parentCommentId`.

**Profiles** (per username): exact follower, following, total-likes, video and friend counts (not the rounded "163M" shown on the page), nickname, bio, bio link, verified, private, organization, seller and commerce flags, language, account creation date, avatar.

### What it does not do, on purpose

TikTok only serves a profile's video list, hashtag feeds and search results to logged-in browser sessions with a verified device fingerprint. Plain requests, headless browsers and residential proxies all get empty responses (checked September 2026). This actor does not pretend otherwise: give it video URLs and usernames and it returns complete, exact data every time. If you need to discover videos first, pair it with a search or hashtag actor, then feed the URLs here for the numbers.

### Quick start

```json
{
  "videoUrls": [
    "https://www.tiktok.com/@selllestin/video/7678609956152560916",
    "https://vm.tiktok.com/ZMabc123/"
  ],
  "profiles": ["@khaby.lame", "https://www.tiktok.com/@charlidamelio"],
  "includeComments": true,
  "maxCommentsPerVideo": 200,
  "includeReplies": true
}
```

### Input

| Field | Type | Description |
|---|---|---|
| `videoUrls` | array | Video or photo-post URLs, short links (`vm.tiktok.com`, `tiktok.com/t/`) or bare numeric IDs. |
| `profiles` | array | Usernames with or without `@`, or profile URLs. |
| `includeComments` | boolean | Also scrape the comments of every video in `videoUrls`. Default `false`. |
| `maxCommentsPerVideo` | integer | Top-level comments per video, in TikTok's order. Default 100; `0` = as many as TikTok returns. |
| `includeReplies` | boolean | Also fetch replies under each comment. Default `false`. |
| `maxRepliesPerComment` | integer | Default 10; `0` = all. |
| `proxyConfiguration` | object | Optional and off by default, because it is not needed. Apify datacenter proxies or your own proxy URLs can be used; residential proxies are not supported. |

At least one of `videoUrls` or `profiles` is required.

### Output

One row per video (`"type": "video"`) or profile (`"type": "profile"`). Items TikTok refuses (removed video, private or banned account) come back as a row with an `error` field and are not billed.

Video row (abridged):

```json
{
  "type": "video",
  "id": "7678609956152560916",
  "url": "https://www.tiktok.com/@selllestin/video/7678609956152560916",
  "description": "#cooking #thebear #wellness #chef",
  "hashtags": ["cooking", "thebear", "wellness", "chef"],
  "createdAt": "2026-08-27T06:48:25+00:00",
  "isImagePost": true,
  "plays": 137300,
  "likes": 21000,
  "comments": 203,
  "shares": 466,
  "saves": 2658,
  "reposts": 0,
  "authorUsername": "selllestin",
  "authorNickname": "Sellestin",
  "authorVerified": false,
  "authorFollowers": 52400,
  "authorHearts": 4800000,
  "musicTitle": "original sound",
  "musicAuthor": "filips",
  "musicIsOriginal": true,
  "locationCreated": "NL",
  "isAd": false,
  "scrapedAt": "2026-09-21T20:00:00+00:00"
}
```

Profile row (abridged):

```json
{
  "type": "profile",
  "username": "khaby.lame",
  "url": "https://www.tiktok.com/@khaby.lame",
  "nickname": "Khabane lame",
  "signature": "Se vuoi ridere sei nel posto giusto😎 If u wanna laugh u r in the right place😎",
  "bioLink": null,
  "verified": true,
  "privateAccount": false,
  "followers": 162988580,
  "following": 81,
  "hearts": 2680674378,
  "videos": 1353,
  "createdAt": "2016-08-10T21:22:34+00:00",
  "scrapedAt": "2026-09-21T20:00:00+00:00"
}
```

Comment row (abridged):

```json
{
  "type": "comment",
  "videoId": "7678609956152560916",
  "videoUrl": "https://www.tiktok.com/@selllestin/video/7678609956152560916",
  "commentId": "7679093892465885973",
  "parentCommentId": null,
  "isReply": false,
  "text": "...",
  "hasImage": false,
  "createdAt": "2026-08-28T10:46:29+00:00",
  "likes": 228,
  "replyCount": 2,
  "isPinned": false,
  "isLikedByCreator": true,
  "authorUsername": "diffgmg",
  "authorNickname": "ssz",
  "authorUrl": "https://www.tiktok.com/@diffgmg",
  "scrapedAt": "2026-09-22T20:00:00+00:00"
}
```

Sticker and image comments come back with an empty `text` and `hasImage: true`. TikTok's reported comment count includes replies and deleted comments, so the number you can collect is usually lower than the counter on the video.

`videoPlayUrl`, `videoDownloadUrl`, `musicPlayUrl` and image URLs are signed and expire after a few hours; download what you need right away.

### Pricing

Pay per event: one `video` event per video row and one `profile` event per profile row, plus a tiny actor-start fee. Error rows are free. Comments are free during their launch period; a per-comment price will be announced on this page with Apify's standard 14-day notice before it applies.

### Use cases

- Track performance of your own or competitors' posts over time (schedule the actor and diff the numbers)
- Influencer vetting: exact follower and like counts, verified and commerce flags, bio links
- Campaign reporting: feed the video URLs from a campaign, get the numbers in one sheet
- Enrich video URLs collected elsewhere with stats, music and hashtags
- Audience research and sentiment analysis from comments and replies

### Integrations

Run it from the Apify API, the JavaScript or Python client, the CLI, schedules, or as an MCP tool. Export to JSON, CSV, Excel, or push rows to Google Sheets, Make, Zapier or n8n.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("cycha/tiktok-scraper").call(run_input={
    "videoUrls": ["https://www.tiktok.com/@selllestin/video/7678609956152560916"],
    "profiles": ["@khaby.lame"],
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["type"], row.get("url"), row.get("plays") or row.get("followers"))
```

### FAQ

**Why are there no hashtag or search inputs anymore?** TikTok stopped serving those feeds to anything but logged-in, fingerprint-verified browsers. Earlier versions of this actor tried and returned nothing, which is worse than being honest about it.

**Are the numbers exact?** Profile counts come from TikTok's exact counters (`statsV2`). Video counts are what TikTok reports at scrape time; very large numbers may be rounded by TikTok itself.

**Photo posts?** Supported. `isImagePost` is `true` and `imageCount` tells you how many slides.

**Is it legal?** The actor reads publicly visible data. You are responsible for how you use it and for complying with TikTok's terms and local law.

### Feedback

Missing a field, hit a bug, or need an input this actor doesn't take yet? Open an issue on the actor's **Issues** tab. If the TikTok Video, Profile & Comments Scraper saved you time, a short review on the Store page helps other people find it.

### Related actors by the same developer

| Actor | What it does |
|---|---|
| [TikTok Transcript Scraper](https://apify.com/cycha/tiktok-transcript-scraper) | Transcripts of TikTok videos, in the spoken language or English |
| [YouTube Channel Scraper](https://apify.com/cycha/youtube-channel-scraper) | All videos and Shorts of a channel with stats |
| [YouTube Comments Scraper](https://apify.com/cycha/youtube-comments-scraper) | Comments and replies with video stats |
| [Google Trends Scraper](https://apify.com/cycha/google-trends-scraper) | Interest over time, related queries and regions for up to 500 keywords |
| [Amazon Scraper](https://apify.com/cycha/amazon-scraper) | Search results and product details in 17 countries |

# Actor input Schema

## `videoUrls` (type: `array`):

TikTok video or photo-post URLs (tiktok.com/@user/video/ID, vm.tiktok.com short links) or bare numeric video IDs. One dataset row with full stats per video.

## `profiles` (type: `array`):

Usernames (with or without @) or profile URLs. One dataset row with exact follower, like and video counts, bio and link per profile.

## `includeComments` (type: `boolean`):

Also scrape the comments of every video in 'Video URLs'. One row per comment (type=comment).

## `maxCommentsPerVideo` (type: `integer`):

Top-level comments per video, in TikTok's order. 0 = as many as TikTok returns.

## `includeReplies` (type: `boolean`):

Also fetch replies under each comment.

## `maxRepliesPerComment` (type: `integer`):

0 = all replies.

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

Optional, off by default and not needed. You can use Apify datacenter proxies or your own proxy URLs. Residential proxies are not supported and are replaced by datacenter proxies.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.tiktok.com/@selllestin/video/7678609956152560916"
  ],
  "profiles": [
    "@khaby.lame"
  ],
  "includeComments": false,
  "maxCommentsPerVideo": 100,
  "includeReplies": false,
  "maxRepliesPerComment": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per video (type=video) or profile (type=profile); failed items carry an error field.

# 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 = {
    "videoUrls": [
        "https://www.tiktok.com/@selllestin/video/7678609956152560916"
    ],
    "profiles": [
        "@khaby.lame"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cycha/tiktok-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 = {
    "videoUrls": ["https://www.tiktok.com/@selllestin/video/7678609956152560916"],
    "profiles": ["@khaby.lame"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("cycha/tiktok-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 '{
  "videoUrls": [
    "https://www.tiktok.com/@selllestin/video/7678609956152560916"
  ],
  "profiles": [
    "@khaby.lame"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call cycha/tiktok-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cycha/tiktok-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/UV8NNxfGts4hDdg9f/builds/O5U4ciHVDhm8dvccN/openapi.json
