# TikTok Scraper: Profiles, Hashtags, Keywords & Videos (`thescrapelab/tiktok-scraper-2-0`) Actor

Scrape public TikTok profiles, hashtags, keyword search results, and video URLs to clean datasets with captions, transcripts when available, engagement metrics, hashtags, music, author data, media links, and quality signals for social listening, influencer research, and trend monitoring.

- **URL**: https://apify.com/thescrapelab/tiktok-scraper-2-0.md
- **Developed by:** [Inus Grobler](https://apify.com/thescrapelab) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 80 total users, 14 monthly users, 99.2% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.49 / 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/platform/actors/running/actors-in-store#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 Scraper for Profiles, Hashtags, Keywords, Videos & Transcripts

Scrape public TikTok profiles, hashtags, keyword search results, and individual video URLs into clean structured datasets. Use this TikTok profile scraper, TikTok hashtag scraper, TikTok keyword scraper, TikTok video scraper, and TikTok transcript scraper to collect video metadata, engagement counts, captions, transcripts when available, media links, hashtags, music data, and account context without building or maintaining your own TikTok data pipeline.

This Actor is built for teams that need TikTok data for trend tracking, influencer research, brand monitoring, social listening, content analysis, market research, AI enrichment, and analytics workflows. Results are written to an Apify dataset, so you can export TikTok data to JSON, CSV, Excel, XML, RSS, or connect it to your API, warehouse, dashboard, spreadsheet, CRM, or automation stack.

### What This TikTok Scraper Does

- Scrapes public videos from TikTok usernames, `@handles`, and profile URLs
- Enriches specific TikTok video URLs with available public metadata
- Discovers videos from TikTok keyword and hashtag searches
- Extracts captions, hashtags, music title, duration, timestamps, and author context
- Collects engagement metrics including views, likes, comment counts, shares, and saves when available
- Extracts subtitle transcript text when TikTok exposes transcript or caption metadata
- Falls back to cleaned caption text when a transcript track is not available
- Streams results to the dataset during the run to reduce memory usage on larger jobs
- Adds quality flags so downstream systems can separate complete rows from partial rows

This Actor does not scrape TikTok comment text, comment authors, replies, or comment threads. It only returns `comment_count` as a video-level metric.

### Best Use Cases

- Monitor TikTok accounts for new public videos
- Track hashtags, trends, products, brands, and creator niches
- Build influencer discovery and creator research datasets
- Enrich known TikTok video URLs with metrics, captions, media links, and metadata
- Feed TikTok video data into BI dashboards, spreadsheets, CRMs, or data warehouses
- Collect TikTok captions and available transcripts for content analysis or AI enrichment
- Schedule repeat runs for lightweight TikTok monitoring

### Who Uses This Actor

- Social listening teams tracking TikTok conversations, hashtags, and campaigns
- Brand and reputation monitoring teams watching products, events, competitors, and creators
- Influencer marketing teams researching creator activity, engagement, and content themes
- Market researchers collecting public TikTok videos for trend and audience analysis
- AI and data teams extracting captions and available transcripts for classification, search, and summarization
- Journalists, researchers, and analysts monitoring public narratives and emerging topics

### Popular Workflows

| Goal | Input to use | Typical output |
|---|---|---|
| Track TikTok hashtags | `keywords: ["#skincare", "#aitools"]` | Videos, captions, transcripts, metrics, authors, hashtags |
| Monitor creators | `users: ["tiktok", "khaby.lame"]` | Public videos, account context, engagement counts, captions |
| Enrich known videos | `urls: ["https://www.tiktok.com/@.../video/..."]` | One row per video with metadata, caption, transcript, media links |
| Build influencer lists | `keywords` first, then scrape discovered `users` | Creators, videos, engagement signals, content themes |
| Low-cost discovery | `keywords: ["ai tools"]` | Faster keyword results with cost-aware enrichment defaults |
| Full research export | `users`, `urls`, or `keywords` | Rich video rows for analysis, AI workflows, and databases |

### What You Get

| Data category | Example fields |
|---|---|
| Video identity | `video_id`, `video_url`, `source_input_url`, `search_keyword` |
| Text content | `caption_text`, `transcript`, `has_transcript`, `has_caption_text_fallback` |
| Engagement metrics | `play_count`, `like_count`, `comment_count`, `share_count`, `save_count` |
| Creator data | `author_username`, `author_id`, `account` |
| Discovery context | `hashtags`, `music_title`, `create_time`, `create_time_epoch` |
| Media data | `media_links`, direct playback URL when available, thumbnail links when available |
| Quality checks | `metadata_quality`, `missing_fields`, `transcript_detail` |

Use the output for TikTok trend monitoring, TikTok influencer research, TikTok hashtag tracking, TikTok social listening, competitor research, campaign reporting, content classification, and AI analysis pipelines.

### Simple Input

Provide any combination of `users`, `urls`, and `keywords`. The Actor assumes cost-aware defaults for enrichment depth, transcript discovery, continuation, output size, retries, delays, and fallbacks.

#### Scrape TikTok Users

```json
{
  "users": ["tiktok", "khaby.lame"],
  "maxItems": 20
}
```

#### Enrich TikTok Video URLs

```json
{
  "urls": [
    "https://www.tiktok.com/@tiktok/video/1234567890123456789"
  ],
  "maxItems": 10
}
```

#### Search TikTok Keywords Or Hashtags

```json
{
  "keywords": ["ai tools", "fitness tips", "#skincare"],
  "maxItems": 20
}
```

#### Combine Inputs In One Run

```json
{
  "users": ["tiktok"],
  "urls": ["https://www.tiktok.com/@tiktok/video/1234567890123456789"],
  "keywords": ["creator economy"],
  "maxItems": 10
}
```

### Input Reference

| Field | Type | Default | Description |
|---|---|---:|---|
| `users` | array\[string] | - | TikTok usernames, `@handles`, or profile URLs. |
| `urls` | array\[string] | - | TikTok video URLs to enrich directly. |
| `keywords` | array\[string] | - | TikTok keyword or hashtag searches. |
| `maxItems` | integer | `20` | Maximum videos per user or keyword, and maximum video URLs to process. The Actor caps this at `100` per user or keyword to avoid accidental runaway runs. |

Provide at least one of `users`, `urls`, or `keywords`.

Advanced scraping controls are intentionally defaulted and hidden from the normal input form. Existing API clients can still pass older advanced fields, but most users only need the four fields above.

### Dataset Output

Each dataset item is one TikTok video record. The output is designed for analysis, search indexing, enrichment, and automated workflows.

Common fields include:

- `video_id`
- `video_url`
- `caption_text`
- `transcript`
- `has_transcript`
- `has_caption_text_fallback`
- `create_time`
- `create_time_epoch`
- `author_username`
- `author_id`
- `hashtags`
- `play_count`
- `like_count`
- `comment_count`
- `share_count`
- `save_count`
- `duration_s`
- `music_title`
- `media_links`
- `account`
- `search_keyword`
- `metadata_quality`
- `missing_fields`

Example dataset item:

```json
{
  "video_id": "1234567890123456789",
  "video_url": "https://www.tiktok.com/@creator/video/1234567890123456789",
  "caption_text": "Example TikTok caption #trend",
  "transcript": "Transcript text when TikTok exposes captions or subtitles.",
  "has_transcript": true,
  "has_caption_text_fallback": false,
  "author_username": "creator",
  "hashtags": ["trend"],
  "play_count": 125000,
  "like_count": 8400,
  "comment_count": 320,
  "share_count": 180,
  "save_count": 95,
  "duration_s": 24,
  "music_title": "Original sound",
  "metadata_quality": "full",
  "missing_fields": []
}
```

### Transcript Handling

TikTok does not expose transcripts for every video. When transcript or subtitle metadata is available, the Actor returns it in `transcript` and marks `has_transcript` as `true`.

When no transcript track is available, the Actor uses cleaned caption text as a fallback and marks `has_caption_text_fallback` as `true`. Caption fallback is useful for search and classification, but it is not the same as a spoken-word transcript.

### Quality Signals

TikTok availability can vary by region, account, video type, and current platform behavior. To make the output easier to trust, each row includes quality fields:

- `metadata_quality`: `full`, `partial`, or `url_only`
- `missing_fields`: important fields that were not available for that row
- `transcript_detail`: transcript status and source details when available

These fields help you filter results before sending TikTok data into analytics, AI workflows, or databases.

### Run Summary

Every run stores an `OUTPUT_SUMMARY` record in the default key-value store. Useful fields include:

- `status`
- `videos_scraped`
- `videos_with_transcript`
- `videos_with_caption_text_fallback`
- `metadata_quality_counts`
- `dataset_items_pushed`
- `dataset_push_batches`
- `streaming_enabled`
- `memory_peak_mb`
- `health`

### Performance, Cost, And Scaling

Rows are streamed to the dataset after each user, video URL, or keyword is processed. This keeps memory usage lower than holding the full run output until the end.

For best results:

- Start with a small `maxItems` value when testing a new query
- Use `urls` when you already know the exact TikTok videos to enrich
- Use `users` for account monitoring
- Use `keywords` for discovery, trends, hashtags, and topic research
- Schedule repeat runs for ongoing monitoring instead of running very large one-off jobs
- Put multiple users in one run when possible. The Actor processes and streams each user separately, so batching small accounts reduces fixed actor-start overhead without holding all results in memory.
- For lower-cost keyword discovery, start with small `maxItems` values, then scrape discovered authors with `users`
- For lower-cost user monitoring, use `users` and schedule repeat runs instead of one very large run
- Direct signed playback URLs and deeper enrichment are off by default to keep rows smaller and runs cheaper
- If pay-per-event pricing is enabled, keyword searches charge the custom `keyword-search-started` event once per keyword before discovery begins.

The Actor defaults to 1024 MB memory and a 2 hour timeout, with 512 MB suitable for many user and URL runs. Use 2048 MB only for heavier keyword searches or unusually large mixed runs. Keyword search depends on TikTok browser pages and can be slower or more variable than user and URL scraping.

### Pricing

Apify platform usage depends on runtime, memory, storage writes, and network transfer. This Actor is designed for pay-per-event pricing when monetized, with one dataset item representing one useful TikTok video result. A small keyword-search start event can also be used if keyword discovery remains materially more expensive than profile or URL scraping.

Recommended simple pricing:

- Charge per successful dataset result.
- Keep platform usage included in the event price for simple billing.
- Use `compact` output and the default 1024 MB memory for the best cost-to-result balance.
- Offer lower per-result rates for higher monthly tiers only after checking current run costs.

Exact pricing can change with Apify platform prices and TikTok availability, so check the latest Store pricing before running large jobs.

### Troubleshooting

| Problem | What to try |
|---|---|
| No results for a user | Confirm the profile is public and the username is correct. Try a lower `maxItems` first. |
| Keyword search is slow | Lower `maxItems` or scrape known users instead. |
| Missing transcript text | TikTok does not expose transcripts for every video. Use `caption_text` or rows marked `has_caption_text_fallback`. |
| Missing account profile fields | User runs prioritize video rows and cost. Some profile fields can be sparse. |
| Large rows or exports | Keep `maxItems` focused and split very large exports into several runs. |
| Run hits timeout | Split the input into smaller runs, lower `maxItems`, or use user/profile scraping instead of broad keyword discovery. |

### API Usage

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "users": ["tiktok"],
    "keywords": ["ai tools"],
    "maxItems": 5,
}

actor = client.actor("thescrapelab/tiktok-scraper-2-0")
run = actor.call(run_input=run_input)

dataset = client.dataset(run["defaultDatasetId"])
for item in dataset.iterate_items():
    print(item["video_url"], item.get("play_count"), item.get("transcript"))
```

#### HTTP

```bash
curl -sS -X POST \
  "https://api.apify.com/v2/acts/thescrapelab~tiktok-scraper-2-0/run-sync-get-dataset-items?format=json&clean=true" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["ai tools"],
    "maxItems": 5
  }'
```

### Notes And Limitations

- The Actor collects public TikTok data that is available during the run.
- Some videos, accounts, or search results can be unavailable because of region, age restrictions, login challenges, or TikTok platform changes.
- Transcript tracks are only returned when TikTok exposes caption or subtitle metadata.
- Direct media URLs can be signed and short-lived. Store stable `video_url` values for long-term references.
- This Actor is not affiliated with TikTok.

### FAQ

#### Can I scrape TikTok profiles?

Yes. Provide usernames, `@handles`, or profile URLs in `users`. The Actor returns public video rows and available account context.

#### Can I scrape TikTok hashtags or keyword searches?

Yes. Provide terms in `keywords`, including hashtags such as `#skincare`. Keyword search uses browser discovery and can be slower than profile scraping.

#### Does this scrape TikTok comments?

No. It returns video-level `comment_count`, but it does not scrape comment text, comment authors, replies, or comment threads.

#### Can I get TikTok transcripts?

The Actor returns transcript text when TikTok exposes captions or subtitles. If no transcript is available, it can use cleaned caption text as a fallback.

#### What is the cheapest way to monitor TikTok accounts?

Use `users`, keep `maxItems` focused, and schedule repeat runs instead of one very large run. The Actor already defaults the cost controls for this workflow.

# Actor input Schema

## `users` (type: `array`):

TikTok usernames, @handles, or profile URLs to scrape for public videos.

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

Specific TikTok video URLs to enrich with available public metadata.

## `keywords` (type: `array`):

TikTok keyword or hashtag searches, such as a brand, topic, product, creator niche, or #hashtag.

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

Maximum videos to return per user and maximum video URLs to process. Keyword discovery uses a safe shared budget of up to 5 video pages per run to prevent browser timeouts; split larger keyword lists across runs.

## Actor input object example

```json
{
  "urls": [
    "https://www.tiktok.com/@khaby.lame/video/7623088450576633119"
  ],
  "maxItems": 1
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Enriched TikTok video rows for users, video URLs, keywords, and hashtags. Rows include video\_id, video\_url, caption\_text, transcript, engagement counts, media links, and quality metadata.

## `datasetItemsCleanJson` (type: `string`):

TikTok dataset items as clean JSON for analytics, dashboards, automations, and API integrations.

## `outputSummary` (type: `string`):

Run summary stored in OUTPUT\_SUMMARY. Includes status, item counts, transcript counts, metadata quality, streaming stats, memory peak, and continuation state key.

## `continuationState` (type: `string`):

Default continuation checkpoint record in key-value store (only used when continuationStateKey is CONTINUATION\_STATE).

## `runApi` (type: `string`):

Direct API link for this run.

# 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 = {
    "urls": [
        "https://www.tiktok.com/@khaby.lame/video/7623088450576633119"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thescrapelab/tiktok-scraper-2-0").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 = { "urls": ["https://www.tiktok.com/@khaby.lame/video/7623088450576633119"] }

# Run the Actor and wait for it to finish
run = client.actor("thescrapelab/tiktok-scraper-2-0").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 '{
  "urls": [
    "https://www.tiktok.com/@khaby.lame/video/7623088450576633119"
  ]
}' |
apify call thescrapelab/tiktok-scraper-2-0 --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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