# 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
- **Stats:** 1,164 total users, 186 monthly users, 99.6% runs succeeded, 9 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/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 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("💾 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 '{}' |
apify call scrapeforge/tiktok-posts --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Posts Scraper",
        "description": "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.",
        "version": "0.1",
        "x-build-id": "T5MeGrm1FsxCzsmaH"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapeforge~tiktok-posts/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapeforge-tiktok-posts",
                "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/scrapeforge~tiktok-posts/runs": {
            "post": {
                "operationId": "runs-sync-scrapeforge-tiktok-posts",
                "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/scrapeforge~tiktok-posts/run-sync": {
            "post": {
                "operationId": "run-sync-scrapeforge-tiktok-posts",
                "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",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "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.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "scrapeMode": {
                        "title": "Scrape Mode",
                        "enum": [
                            "profiles",
                            "hashtag",
                            "keyword"
                        ],
                        "type": "string",
                        "description": "Choose what type of TikTok data to scrape.",
                        "default": "profiles"
                    },
                    "profiles": {
                        "title": "TikTok Profiles",
                        "type": "array",
                        "description": "List of TikTok usernames to scrape (without @). Required when Scrape Mode is 'profiles'. Free Apify plans are limited to 1 profile per run.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "hashtag": {
                        "title": "Hashtag",
                        "type": "string",
                        "description": "Hashtag to search for (without #). Required when Scrape Mode is 'hashtag'."
                    },
                    "keyword": {
                        "title": "Search Keyword",
                        "type": "string",
                        "description": "Keyword or phrase to search. Required when Scrape Mode is 'keyword'."
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum total number of posts to return (for hashtag and keyword modes). Free Apify plans are capped at 50.",
                        "default": 50
                    },
                    "maxResultsPerProfile": {
                        "title": "Max Results Per Profile",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of posts per profile (for profiles mode). Free Apify plans are capped at 50.",
                        "default": 30
                    },
                    "sortBy": {
                        "title": "Sort By",
                        "enum": [
                            "latest",
                            "popular",
                            "relevance",
                            "most-liked",
                            "date-posted"
                        ],
                        "type": "string",
                        "description": "Sort order. For profiles: 'latest' or 'popular'. For keyword search: 'relevance', 'most-liked', or 'date-posted'."
                    },
                    "datePosted": {
                        "title": "Date Posted Filter",
                        "enum": [
                            "yesterday",
                            "this-week",
                            "this-month",
                            "last-3-months",
                            "last-6-months",
                            "all-time"
                        ],
                        "type": "string",
                        "description": "Filter by date (keyword search mode only)."
                    },
                    "region": {
                        "title": "Region",
                        "type": "string",
                        "description": "2-letter country code for proxy region (e.g., US, GB, FR). Affects which content is returned."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
