# TikTok Profile, Hashtag, Search, Video & Trending Scraper (`abotapi/tiktok-scraper`) Actor

Scrape TikTok without login. Extract profiles, bios, follower stats and videos; search by hashtag or keyword; scrape individual videos with full engagement stats and comments; or collect posts from the current trending feed.

- **URL**: https://apify.com/abotapi/tiktok-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 9 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 Profile, Hashtag, Search, Video & Trending Scraper

Pull structured data from TikTok without logging in. Give it usernames to get profile info plus their videos, hashtags or keywords to get matching videos, direct video links to get full stats plus comments, or run it with no input at all to get the current trending feed. Clean JSON out, four independent modes, one actor.

### Why this scraper

- Four modes in one actor: profile, hashtag/keyword search, video plus comments, and trending, so you do not need separate tools for each job.
- Profile mode returns the full public profile (bio, avatar, follower/following/heart/video counts, verified flag) plus a paginated list of that account's videos.
- Search mode accepts a plain keyword or a hashtag (start the term with #) and returns matching videos either way.
- Video mode returns full video stats (plays, likes, comments, shares, saves), music info, hashtags used, duration and cover images, plus paginated comments (text, author, likes, reply count, timestamp).
- Trending mode needs no input at all: run it as-is to pull the current trending feed.
- No video, thumbnail, avatar or music file downloads; this actor returns metadata and cover image URLs only, keeping runs fast and cheap.
- Simple output limit: one "Max results" number per mode (videos for profile/search/trending, comments for video mode); leave it at 0 to walk until the feed itself ends.

### Data you get

> Sample shape: values are illustrative placeholders, not from a live profile, video or comment.

#### Profile record

| Field | Example |
| --- | --- |
| recordType | "profile" |
| uniqueId | "samplecreator" |
| nickname | "Sample Creator" |
| signature | "Sample bio text goes here" |
| avatarUrl | "https://p16-sign-va.tiktokcdn.com/sample-avatar.jpeg" |
| followerCount | 125000 |
| followingCount | 340 |
| heartCount | 2400000 |
| videoCount | 210 |
| verified | false |
| privateAccount | false |
| region | "US" |
| bioLink | "https://example.com" |
| url | "https://www.tiktok.com/@samplecreator" |
| scrapedAt | "2026-01-01T00:00:00.000Z" |

#### Video record

| Field | Example |
| --- | --- |
| recordType | "video" |
| id | "7000000000000000000" |
| url | "https://www.tiktok.com/@samplecreator/video/7000000000000000000" |
| desc | "Sample video caption #sample" |
| authorUsername | "samplecreator" |
| authorNickname | "Sample Creator" |
| duration | 18 |
| width | 1080 |
| height | 1920 |
| playCount | 500000 |
| diggCount | 42000 |
| commentCount | 610 |
| shareCount | 1200 |
| collectCount | 3300 |
| musicTitle | "Sample Sound" |
| musicAuthor | "Sample Artist" |
| hashtags | \["sample", "fyp"] |
| coverUrl | "https://p16-sign-va.tiktokcdn.com/sample-cover.jpeg" |
| createTimeIso | "2026-01-01T00:00:00.000Z" |
| sourceMode | "search" |

#### Comment record

| Field | Example |
| --- | --- |
| recordType | "comment" |
| commentId | "7100000000000000000" |
| videoId | "7000000000000000000" |
| text | "Sample comment text" |
| authorUsername | "samplecommenter" |
| authorNickname | "Sample Commenter" |
| diggCount | 24 |
| replyCommentTotal | 2 |
| createTimeIso | "2026-01-01T00:00:00.000Z" |

### How to use

Profile mode:

```json
{
  "mode": "profile",
  "usernames": ["samplecreator", "@anothercreator"],
  "maxItems": 20
}
```

Hashtag or keyword search:

```json
{
  "mode": "search",
  "queries": ["#fyp", "cooking tutorial"],
  "maxItems": 20
}
```

Video plus comments:

```json
{
  "mode": "video",
  "videoUrls": ["https://www.tiktok.com/@samplecreator/video/7000000000000000000"],
  "fetchComments": true,
  "maxItems": 20
}
```

Trending feed, no input needed beyond the mode:

```json
{
  "mode": "trending",
  "maxItems": 20
}
```

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| mode | string | "profile" | profile, search, video or trending |
| usernames | array of strings | \[] | Usernames or profile URLs; profile mode only |
| queries | array of strings | \[] | Hashtags (start with #) or keywords; search mode only |
| videoUrls | array of strings | \[] | Direct video URLs; video mode only |
| fetchComments | boolean | true | Fetch comments for each video; video mode only |
| maxItems | integer | 20 | Videos per username/query/trending run, or comments per video. 0 = unlimited |
| proxy | object | Apify Residential | Proxy configuration |
| mcpConnectors | array | \[] | Optional MCP connectors to also send results to (see below) |
| notionParentPageUrl | string | - | Notion parent page id/url, only used with the Notion connector |
| maxNotifyListings | integer | 50 | Cap on items sent to each connector per run |

### Output example

```json
{
  "recordType": "video",
  "sourceMode": "profile",
  "id": "7000000000000000000",
  "url": "https://www.tiktok.com/@samplecreator/video/7000000000000000000",
  "desc": "Sample video caption #sample",
  "createTime": 1700000000,
  "createTimeIso": "2026-01-01T00:00:00.000Z",
  "authorUsername": "samplecreator",
  "authorNickname": "Sample Creator",
  "authorSecUid": "MS4wSample0000000000000000000000000000000000000000000",
  "duration": 18,
  "width": 1080,
  "height": 1920,
  "playCount": 500000,
  "diggCount": 42000,
  "commentCount": 610,
  "shareCount": 1200,
  "collectCount": 3300,
  "musicId": "7000000000000000001",
  "musicTitle": "Sample Sound",
  "musicAuthor": "Sample Artist",
  "hashtags": ["sample", "fyp"],
  "coverUrl": "https://p16-sign-va.tiktokcdn.com/sample-cover.jpeg",
  "dynamicCoverUrl": "https://p16-sign-va.tiktokcdn.com/sample-dyncover.jpeg",
  "originCoverUrl": "https://p16-sign-va.tiktokcdn.com/sample-origcover.jpeg",
  "region": "US",
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

### Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use through Model Context Protocol connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the input. Notion gets a rich page per item; other connectors get a best-effort write or a digest message. The connector receives a condensed, human-readable summary per item (title plus key fields), not the full JSON; the complete record always stays in the dataset. Leave the field empty to skip this entirely, it never changes the dataset output.

### How a run reports its result

An empty dataset is never reported as a plain success, so a scheduled run cannot fail quietly.

- **Failed run (the run turns red).** No records were collected and at least one target could not be read, or loaded without carrying any usable data. The status message says which of the two happened and how many targets it affected.
- **Partial run (the run stays green, with a warning status message).** Some records were collected but at least one target was missed, so the dataset is incomplete for that input.
- **Empty result (the run stays green).** Every target was reached and simply matched nothing, for example a keyword search with no results. The status message says so explicitly.
- **Clean run (the run stays green).** Every target was reached and returned data.

A target is retried several times before it counts as missed.

### Known limitations

- Short share links (vm.tiktok.com, vt.tiktok.com) are not resolved in video mode; paste the full @username/video/id link.
- The trending feed endpoint may change its exact parameters over time; if a run returns 0 trending items, please report it so the mapping can be refreshed.
- Only public profiles, videos and comments are returned. Private accounts and disabled comment sections return no data for that field.

# Actor input Schema

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

profile: usernames or profile URLs -> profile info + their videos. search: hashtags or keywords -> matching videos. video: direct video URLs -> full video stats + comments. trending: current trending feed, no input needed.

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

One or more TikTok usernames (with or without @) or full profile URLs. Only used when mode = profile.

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

One or more search terms. Start a term with # to search that hashtag (e.g. "#fyp"); anything else is treated as a keyword search. Only used when mode = search.

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

One or more direct TikTok video URLs (https://www.tiktok.com/@user/video/1234567890). Only used when mode = video.

## `fetchComments` (type: `boolean`):

On (default): also fetch comments for each video (text, author, likes, reply count, timestamp), paginated up to the output limit below. Off: video record only, no comments. Only used when mode = video.

## `maxItems` (type: `integer`):

profile mode: max videos per username. search mode: max videos per hashtag/keyword. video mode: max comments per video. trending mode: max videos from the feed. 0 = unlimited (walks until the feed itself ends).

## `proxy` (type: `object`):

Use Apify Residential. Leave the country empty for best results; the actor rotates across residential exits automatically.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify → Settings → API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write/digest. Leave empty to skip; never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "profile",
  "usernames": [
    "tiktok"
  ],
  "queries": [
    "#fyp"
  ],
  "videoUrls": [
    "https://www.tiktok.com/@tiktok/video/7673909736131038495"
  ],
  "fetchComments": true,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

# 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 = {
    "mode": "profile",
    "usernames": [
        "tiktok"
    ],
    "queries": [
        "#fyp"
    ],
    "videoUrls": [
        "https://www.tiktok.com/@tiktok/video/7673909736131038495"
    ],
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/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 = {
    "mode": "profile",
    "usernames": ["tiktok"],
    "queries": ["#fyp"],
    "videoUrls": ["https://www.tiktok.com/@tiktok/video/7673909736131038495"],
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/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 '{
  "mode": "profile",
  "usernames": [
    "tiktok"
  ],
  "queries": [
    "#fyp"
  ],
  "videoUrls": [
    "https://www.tiktok.com/@tiktok/video/7673909736131038495"
  ],
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call abotapi/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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