# TikTok Scraper - Profiles, Hashtags, Search, Videos at Scale (`convertfleetdotonline/tiktok-scraper`) Actor

Bulk-scrape TikTok by hashtag, profile, search, or URL via the Apify API. Extract videos, view counts, likes, comments, shares, hashtags, music info, and author details at scale.

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

## Pricing

$1.00 / 1,000 video scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## TikTok Scraper - Profiles, Hashtags, Search & URLs at Scale

**Bulk-scrape TikTok by hashtag, profile, search query, or direct URL.** Get videos with view counts, likes, comments, shares, hashtags, music info, and author data — all without an API key, login, or third-party token.

### What this TikTok Scraper does

Choose one of four modes and the actor returns a clean stream of TikTok data:

- **Hashtag mode** — pass `#fyp`, `#smallbusiness`, `#crypto` and get the top videos for each
- **Profile mode** — pass usernames and get the latest videos from each, with profile metadata
- **Search mode** — pass free-form queries (e.g. "iphone unboxing") and get search results
- **URLs mode** — pass any mix of TikTok URLs (videos, profiles, hashtag pages) and let the actor route automatically

For profiles you can filter by date range, sort by latest or popular, and exclude pinned videos.

### Why use this TikTok Scraper?

- **No TikTok API key** — works on the public web pages
- **Four scrape modes in one actor** — hashtag, profile, search, URLs
- **Date filtering** — scrape only videos from a specific window
- **Rich metrics** — views, likes, comments, shares, follower counts
- **Bulk-friendly** — pass arrays of hashtags / usernames / queries
- **Author + music metadata** — perfect for influencer marketing & creator discovery

### Use cases

- **Influencer discovery** — find rising creators in any niche
- **Hashtag research** — see what's trending on `#fyp` right now
- **Competitor analysis** — track competitor profile output and engagement
- **Trend monitoring** — capture viral content as it's happening
- **Brand mentions** — search for your brand and pull every mention
- **Music / audio research** — see which sounds are powering top videos
- **Affiliate marketing** — find product-review videos in your niche

### Input

```json
{
    "mode": "hashtag",
    "hashtags": ["fyp", "smallbusiness"],
    "maxVideos": 50
}
````

Profile-mode example:

```json
{
    "mode": "profiles",
    "usernames": ["khaby.lame", "charlidamelio"],
    "profileSort": "latest",
    "excludePinned": true,
    "dateAfter": "2024-01-01",
    "maxVideos": 100
}
```

Search-mode example:

```json
{
    "mode": "search",
    "queries": ["iphone 15 unboxing", "best running shoes 2024"],
    "maxVideos": 30
}
```

URLs-mode example:

```json
{
    "mode": "urls",
    "urls": [
        "https://www.tiktok.com/@khaby.lame",
        "https://www.tiktok.com/@user/video/7000000000000000000",
        "https://www.tiktok.com/tag/fyp"
    ],
    "maxVideos": 50
}
```

### Output

Each video record:

```json
{
    "type": "video",
    "id": "7000000000000000000",
    "description": "Caption with #hashtags",
    "author": "username",
    "author_name": "Display Name",
    "author_followers": 12000000,
    "likes": 1500000,
    "views": 25000000,
    "comments": 8500,
    "shares": 42000,
    "created_at": 1735689600,
    "url": "https://www.tiktok.com/@username/video/7000000000000000000",
    "hashtags": ["fyp", "viral"],
    "music": "Original Sound - username",
    "cover": "https://p16-…tiktokcdn.com/…"
}
```

Profile records (only in `profiles` mode) have `type: "profile"` and contain follower count, bio, avatar URL, and total likes.

### How it works

The actor uses Playwright (with stealth) to load TikTok pages exactly the way the official TikTok web client does. It extracts the `SIGI_STATE` and `__NEXT_DATA__` JSON blobs embedded in the HTML — TikTok's own internal state — and normalises them to a clean record schema. No reverse-engineered private APIs, no fragile DOM scraping.

### Cost & speed

A 20-video hashtag scrape completes in 8–15 seconds. A 100-video profile scrape completes in 25–45 seconds. Memory usage is ~1 GB due to Chromium.

### Related actors

- **TikTok Video Downloader** — get direct MP4 / MP3 URLs
- **YouTube Channel Scraper** — bulk video metadata for YouTube
- **Twitter / X Scraper** — bulk tweet scraping
- **Reddit Scraper** — bulk Reddit post / comment / community scraping

### FAQ

**Q: Do I need a TikTok account?**
No.

**Q: Can I scrape private accounts?**
No. Only public videos and profiles.

**Q: Why are some `views` fields null?**
TikTok occasionally omits the play count in profile-list responses. Pass the video URL through the actor again (URLs mode) to get the full stat block.

**Q: Does this work for live streams?**
Live streams don't appear in the standard SIGI\_STATE; only on-demand videos are returned.

**Q: How do I avoid hitting TikTok's anti-bot defenses?**
The actor already uses stealth mode and a realistic user agent. For very large batches, run in smaller chunks (e.g. 100 videos per run) rather than 1,000+ in one go.

# Actor input Schema

## `mode` (type: `string`):

What to scrape: by hashtag, by profile, by search query, or by direct URL.

## `hashtags` (type: `array`):

(Used when mode=hashtag) List of hashtags without the # symbol.

## `usernames` (type: `array`):

(Used when mode=profiles) List of TikTok usernames without the @ symbol.

## `queries` (type: `array`):

(Used when mode=search) List of free-form search queries.

## `urls` (type: `array`):

(Used when mode=urls) List of TikTok URLs - profiles, videos, or hashtag pages.

## `maxVideos` (type: `integer`):

Maximum total videos to return.

## `profileSort` (type: `string`):

(profiles mode) Sort videos by latest or popular.

## `excludePinned` (type: `boolean`):

(profiles mode) Skip pinned videos.

## `dateAfter` (type: `string`):

(profiles mode) Only include videos uploaded on or after this date.

## `dateBefore` (type: `string`):

(profiles mode) Only include videos uploaded on or before this date.

## `scrapeRelated` (type: `boolean`):

Also fetch related-video lists for each scraped TikTok video.

## `scrapeComments` (type: `boolean`):

Also fetch comments for each scraped TikTok video.

## `maxComments` (type: `integer`):

Maximum number of comments (including replies) to fetch per video.

## `maxToplevelComments` (type: `integer`):

Maximum number of top-level comments per video.

## `maxReplies` (type: `integer`):

Maximum number of replies fetched per top-level comment.

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

Routes Playwright through Apify Proxy. TikTok serves empty pages to datacenter IPs — residential is required.

## Actor input object example

```json
{
  "mode": "hashtag",
  "hashtags": [
    "fyp"
  ],
  "usernames": [],
  "queries": [],
  "urls": [],
  "maxVideos": 20,
  "profileSort": "latest",
  "excludePinned": false,
  "scrapeRelated": false,
  "scrapeComments": false,
  "maxComments": 10,
  "maxToplevelComments": 10,
  "maxReplies": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "hashtags": [
        "fyp"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("convertfleetdotonline/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 = {
    "hashtags": ["fyp"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "hashtags": [
    "fyp"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call convertfleetdotonline/tiktok-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=convertfleetdotonline/tiktok-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Scraper - Profiles, Hashtags, Search, Videos at Scale",
        "description": "Bulk-scrape TikTok by hashtag, profile, search, or URL via the Apify API. Extract videos, view counts, likes, comments, shares, hashtags, music info, and author details at scale.",
        "version": "0.1",
        "x-build-id": "IQDiRCQP84iwSYlS7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/convertfleetdotonline~tiktok-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-convertfleetdotonline-tiktok-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/convertfleetdotonline~tiktok-scraper/runs": {
            "post": {
                "operationId": "runs-sync-convertfleetdotonline-tiktok-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/convertfleetdotonline~tiktok-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-convertfleetdotonline-tiktok-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Scrape mode",
                        "enum": [
                            "hashtag",
                            "profiles",
                            "search",
                            "urls"
                        ],
                        "type": "string",
                        "description": "What to scrape: by hashtag, by profile, by search query, or by direct URL.",
                        "default": "hashtag"
                    },
                    "hashtags": {
                        "title": "Hashtags",
                        "type": "array",
                        "description": "(Used when mode=hashtag) List of hashtags without the # symbol.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "usernames": {
                        "title": "Usernames",
                        "type": "array",
                        "description": "(Used when mode=profiles) List of TikTok usernames without the @ symbol.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "queries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "(Used when mode=search) List of free-form search queries.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "urls": {
                        "title": "Direct URLs",
                        "type": "array",
                        "description": "(Used when mode=urls) List of TikTok URLs - profiles, videos, or hashtag pages.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxVideos": {
                        "title": "Max videos",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum total videos to return.",
                        "default": 20
                    },
                    "profileSort": {
                        "title": "Profile sort order",
                        "enum": [
                            "latest",
                            "popular"
                        ],
                        "type": "string",
                        "description": "(profiles mode) Sort videos by latest or popular.",
                        "default": "latest"
                    },
                    "excludePinned": {
                        "title": "Exclude pinned videos",
                        "type": "boolean",
                        "description": "(profiles mode) Skip pinned videos.",
                        "default": false
                    },
                    "dateAfter": {
                        "title": "Date after (YYYY-MM-DD)",
                        "type": "string",
                        "description": "(profiles mode) Only include videos uploaded on or after this date."
                    },
                    "dateBefore": {
                        "title": "Date before (YYYY-MM-DD)",
                        "type": "string",
                        "description": "(profiles mode) Only include videos uploaded on or before this date."
                    },
                    "scrapeRelated": {
                        "title": "Scrape related videos",
                        "type": "boolean",
                        "description": "Also fetch related-video lists for each scraped TikTok video.",
                        "default": false
                    },
                    "scrapeComments": {
                        "title": "Scrape comments",
                        "type": "boolean",
                        "description": "Also fetch comments for each scraped TikTok video.",
                        "default": false
                    },
                    "maxComments": {
                        "title": "Max comments per video",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of comments (including replies) to fetch per video.",
                        "default": 10
                    },
                    "maxToplevelComments": {
                        "title": "Max top-level comments",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of top-level comments per video.",
                        "default": 10
                    },
                    "maxReplies": {
                        "title": "Max replies per comment",
                        "minimum": 0,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of replies fetched per top-level comment.",
                        "default": 5
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Routes Playwright through Apify Proxy. TikTok serves empty pages to datacenter IPs — residential is required.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
