# TikTok Posts Scraper (`scrapeforge/tiktok-posts`) Actor

Scrape TikTok posts, video metadata, and engagement data from profiles, hashtags, or keyword searches. Fast bulk extraction with sorting, date filters, and region targeting. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/scrapeforge/tiktok-posts.md
- **Developed by:** [ScrapeForge](https://apify.com/scrapeforge) (community)
- **Categories:** Social media, Videos, Automation
- **Features:** Limited permissions
- **Stats:** 2,248 total users, 258 monthly users, 100.0% runs succeeded, 17 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.30 / 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.

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 Posts Scraper

A fast and reliable TikTok scraper that extracts posts, video metadata, and engagement data from profiles, hashtags, and keyword searches. Collect thousands of TikTok posts with full details — including video stats, author info, captions, hashtags, and music data. Export to JSON, CSV, or Excel with no coding required.

### Use cases

- **Social media monitoring** — Track brand mentions, competitor content, and trending topics across TikTok
- **Influencer research** — Evaluate creator performance by analyzing post frequency, engagement rates, and content themes
- **Trend analysis** — Discover emerging hashtags, sounds, and content formats before they peak
- **Market research** — Understand audience interests and content preferences in any niche or region
- **Academic research** — Collect structured TikTok datasets for social media studies and NLP projects
- **Content strategy** — Identify top-performing post formats, optimal posting patterns, and high-engagement topics
- **Competitor benchmarking** — Compare engagement metrics, posting cadence, and content mix across competing accounts

### Features

- **Multiple scraping modes** — Scrape by profile, hashtag, keyword search, or paste any TikTok URL directly
- **Smart URL detection** — Paste video, profile, hashtag, search, or music URLs and the Actor auto-detects the type
- **Flexible sorting** — Sort results by latest, most popular, relevance, most liked, or date posted
- **Date filters** — Filter keyword searches by time range (yesterday, this week, this month, up to all time)
- **Region targeting** — Specify a country code to get region-specific content results
- **Rich output data** — Every post includes video metadata, engagement metrics, author profile, hashtags, music info, and more
- **Scalable** — Scrape from 1 to 10,000 posts per run with configurable limits per profile or search
- **Fast extraction** — Bulk data retrieval with efficient pagination, no browser emulation needed

### Input

| Field | Description | Default |
|-------|-------------|---------|
| **Start URLs** | Paste TikTok URLs directly (video, profile, hashtag, search, music). Overrides Scrape Mode when provided. | — |
| **Scrape Mode** | Choose `profiles`, `hashtag`, or `keyword` | `profiles` |
| **TikTok Profiles** | List of usernames to scrape (without @) | — |
| **Hashtag** | Hashtag to search (without #) | — |
| **Search Keyword** | Keyword or phrase to search | — |
| **Max Results** | Maximum posts to return (hashtag/keyword modes) | `50` |
| **Max Results Per Profile** | Maximum posts per profile | `30` |
| **Sort By** | Sort order: `latest`, `popular`, `relevance`, `most-liked`, `date-posted` | — |
| **Date Posted Filter** | Time range filter for keyword searches | — |
| **Region** | 2-letter country code (e.g., `US`, `GB`, `FR`) for region-specific results | — |

#### Input examples

**Scrape posts from specific profiles:**

```json
{
    "scrapeMode": "profiles",
    "profiles": ["charlidamelio", "khaby.lame"],
    "maxResultsPerProfile": 50,
    "sortBy": "popular"
}
```

**Search by hashtag:**

```json
{
    "scrapeMode": "hashtag",
    "hashtag": "fyp",
    "maxResults": 100
}
```

**Keyword search with filters:**

```json
{
    "scrapeMode": "keyword",
    "keyword": "cooking recipes",
    "maxResults": 200,
    "sortBy": "most-liked",
    "datePosted": "this-month",
    "region": "US"
}
```

**Paste URLs directly:**

```json
{
    "startUrls": [
        "https://www.tiktok.com/@charlidamelio",
        "https://www.tiktok.com/tag/fyp",
        "https://www.tiktok.com/search?q=cooking"
    ]
}
```

### Output

Each post in the output dataset includes:

- **Video details** — ID, description/caption, creation timestamp, duration, dimensions, cover images, download URLs
- **Engagement metrics** — plays, likes, comments, shares, saves, and reposts count
- **Author info** — username, display name, avatar, verified status, follower/following counts, bio
- **Hashtags** — All hashtags used in the post
- **Music/sound** — Title, author, album, duration, and cover image of the audio used
- **Additional metadata** — Region, language, content warnings, and original sound flags

#### Output example

```json
{
    "id": "7345678901234567890",
    "text": "This is a sample TikTok caption #fyp #viral",
    "createTime": 1709251200,
    "createTimeISO": "2024-03-01T00:00:00.000Z",
    "authorMeta": {
        "id": "123456789",
        "name": "username",
        "nickName": "Display Name",
        "verified": true,
        "fans": 150000000,
        "heart": 2000000000
    },
    "videoMeta": {
        "duration": 15,
        "width": 1080,
        "height": 1920
    },
    "diggCount": 5000000,
    "shareCount": 100000,
    "playCount": 50000000,
    "commentCount": 75000,
    "hashtags": [
        { "name": "fyp" },
        { "name": "viral" }
    ],
    "musicMeta": {
        "musicName": "Original Sound",
        "musicAuthor": "username"
    }
}
```

### FAQ

**How many posts can I scrape per run?**
You can scrape up to 10,000 posts per run for hashtag and keyword searches, and up to 5,000 posts per profile. Adjust the Max Results settings to control volume and cost.

**Can I scrape multiple profiles in a single run?**
Yes. Add as many usernames as you need to the Profiles list. Each profile is scraped independently with its own results limit.

**What URL formats are supported?**
The Actor accepts standard TikTok URLs for videos, profiles, hashtags, search queries, and music/sound pages. Short URLs (vm.tiktok.com) are also supported.

**How does region targeting work?**
Set a 2-letter country code (ISO 3166-1) in the Region field. This influences which content TikTok returns, similar to browsing from that country.

**Is the output compatible with other TikTok scrapers?**
Yes. The output schema is designed to be compatible with popular TikTok scraper formats, making it easy to switch or combine data sources without changing your pipeline.

**Can I schedule recurring scrapes?**
Yes. Use Apify's built-in scheduler to run the Actor on a daily, weekly, or custom schedule. Combined with Apify integrations, you can automatically push results to Google Sheets, Slack, webhooks, or any API.

### Usage limits for free tier users

To keep the service sustainable, accounts on the **Apify Free plan** have the following limits when running this actor:

- **Up to 50 posts per run** — any higher value in `Max Results` or `Max Results Per Profile` is automatically reduced.
- **1 source per run** — only the first entry in `Start URLs` or `TikTok Profiles` is processed. (`Hashtag` and `Search Keyword` modes already accept a single value.)
- **1 run per 24 hours** — a second run launched within 24 hours of the previous one finishes immediately with a status message explaining when to retry.

When a limit is reached, the run finishes gracefully (no error) and the status message explains what happened.

**Paid plans** (Starter / Bronze and above) are not subject to these per-actor limits. To remove the restrictions, upgrade your Apify plan at <https://console.apify.com/billing>.

### Disclaimer

This Actor is an unofficial tool and is not affiliated with, endorsed by, or sponsored by TikTok or ByteDance Ltd. All product names, trademarks, and registered trademarks are the property of their respective owners. Use this Actor responsibly and in compliance with TikTok's Terms of Service.

# Actor input Schema

## `startUrls` (type: `array`):

Paste TikTok URLs and get results immediately. Video, User, Search, Tag, and Music URLs are supported. When provided, Scrape Mode is ignored. Free Apify plans are limited to 1 URL per run.

## `scrapeMode` (type: `string`):

Choose what type of TikTok data to scrape.

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

List of TikTok usernames to scrape (without @). Required when Scrape Mode is 'profiles'. Free Apify plans are limited to 1 profile per run.

## `hashtag` (type: `string`):

Hashtag to search for (without #). Required when Scrape Mode is 'hashtag'.

## `keyword` (type: `string`):

Keyword or phrase to search. Required when Scrape Mode is 'keyword'.

## `maxResults` (type: `integer`):

Maximum total number of posts to return (for hashtag and keyword modes). Free Apify plans are capped at 50.

## `maxResultsPerProfile` (type: `integer`):

Maximum number of posts per profile (for profiles mode). Free Apify plans are capped at 50.

## `sortBy` (type: `string`):

Sort order. For profiles: 'latest' or 'popular'. For keyword search: 'relevance', 'most-liked', or 'date-posted'.

## `datePosted` (type: `string`):

Filter by date (keyword search mode only).

## `region` (type: `string`):

2-letter country code for proxy region (e.g., US, GB, FR). Affects which content is returned.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.tiktok.com/@charlidamelio",
    "https://www.tiktok.com/@khaby.lame/video/7345678901234567890",
    "https://www.tiktok.com/tag/fyp",
    "https://www.tiktok.com/search?q=cooking"
  ],
  "scrapeMode": "profiles",
  "profiles": [
    "charlidamelio",
    "khaby.lame"
  ],
  "hashtag": "fyp",
  "keyword": "cooking recipes",
  "maxResults": 50,
  "maxResultsPerProfile": 30,
  "region": "US"
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeforge/tiktok-posts").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapeforge/tiktok-posts").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 '{}' |
apify call scrapeforge/tiktok-posts --silent --output-dataset

```

## MCP server setup

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

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/wVJo1lJBw0WIxslPI/builds/UqUwNkCoIRe211YHM/openapi.json
