# TikTok Profile Posts Scraper - Creator Feed Data (`khadinakbar/tiktok-profile-posts-scraper`) Actor

Scrape public TikTok profile posts with captions, engagement, media, hashtags, music, and creator metadata. Provider-backed, no cookies, MCP ready.

- **URL**: https://apify.com/khadinakbar/tiktok-profile-posts-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 post scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Scrape public TikTok profile posts from creator feeds with normalized, AI-agent-ready output. Give the actor one or more TikTok handles or profile URLs and it returns one dataset row per post with captions, engagement metrics, author metadata, music metadata, hashtags, cover URLs, direct play/download URLs when returned, and run-level provider diagnostics.

This actor is built for creator research, influencer discovery, social listening, competitive monitoring, content analysis, and workflow automation. It uses public-data provider APIs with ScrapeCreators as the recommended primary provider and SociaVault as fallback. It does not ask users for TikTok cookies, browser sessions, or account login.

### What This Actor Does

TikTok Profile Posts Scraper focuses on one job: profile in, creator posts out. It accepts handles such as `nike`, `@nike`, or full profile URLs such as `https://www.tiktok.com/@nike`. For each public creator feed, it paginates through recent or popular posts, normalizes the provider response, deduplicates post IDs across all inputs, and writes clean records to the default dataset.

The actor is narrower than a general TikTok scraper on purpose. It does not scrape keyword search, hashtag feeds, comments, followers, following lists, or one-off post URLs. That tighter scope makes it easier for humans and AI agents to choose the right tool when the task is specifically "get posts from these TikTok profiles."

### When To Use It

Use this actor when you already know the TikTok creators you want to analyze and need their public video history in a structured format.

Good fits include:

- Influencer research: collect recent posts, engagement counts, captions, sounds, and post dates from creator shortlists.
- Competitor tracking: monitor brand or competitor profile feeds and export new video metadata for analysis.
- Social listening: inspect what specific creators are posting without using TikTok cookies.
- Content research: mine captions, hashtags, music, and engagement metrics from creator feeds.
- Agency reporting: build CSV or JSON exports of posts from client, competitor, or campaign creator profiles.
- AI-agent workflows: let Claude, ChatGPT, Make, n8n, or Zapier fetch profile video rows through Apify MCP or API.

Do not use this actor for hashtag discovery, keyword search, single video details, TikTok comments, follower lists, or private TikTok data. Use a dedicated actor for those workflows.

### Input

The fastest test input is:

```json
{
  "profileHandles": ["stoolpresidente"],
  "maxPostsPerProfile": 10,
  "maxPagesPerProfile": 1,
  "maxTotalPosts": 50,
  "sortBy": "latest",
  "region": "US",
  "providerOrder": "scrapecreators-first",
  "includeRawData": false
}
```

#### Important Inputs

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `profileHandles` | array | required | TikTok handles, @handles, or full profile URLs. |
| `maxPostsPerProfile` | integer | `50` | Maximum posts saved from each profile. |
| `maxPagesPerProfile` | integer | `10` | Safety cap for provider pagination per profile. |
| `maxTotalPosts` | integer | `10000` | Whole-run billing and safety cap across all profiles. |
| `sortBy` | string | `latest` | Request `latest` or `popular` profile posts when supported. |
| `region` | string | `US` | Alpha-2 region code for provider requests. |
| `providerOrder` | string | `scrapecreators-first` | Provider fallback order. |
| `includeRawData` | boolean | `false` | Attach raw provider payloads for debugging. |

### Output

Each dataset item is one TikTok profile post. The output is intentionally flat so spreadsheet tools, BI systems, and AI agents can read it without navigating deeply nested TikTok payloads.

| Field | Description |
| --- | --- |
| `profileHandle` | Requested creator handle. |
| `videoId` | TikTok video ID. |
| `videoUrl` | Canonical TikTok video page URL when available. |
| `caption` | Caption or description text. |
| `createdAt` | Video publish timestamp in ISO format when returned. |
| `authorUsername` | Creator handle returned by TikTok. |
| `authorNickname` | Creator display name. |
| `authorVerified` | Whether the creator is verified. |
| `authorFollowerCount` | Creator follower count when returned. |
| `playCount` | Views or play count. |
| `likeCount` | Likes. |
| `commentCount` | Comments. |
| `shareCount` | Shares. |
| `collectCount` | Saves or collects. |
| `engagementRate` | Approximate engagement rate from likes, comments, shares, and views. |
| `coverUrl` | Static cover image URL. |
| `playUrl` | Direct signed TikTok play URL when returned. These URLs can expire. |
| `downloadUrl` | Direct signed TikTok download URL when returned. These URLs can expire. |
| `noWatermarkUrl` | No-watermark URL when TikTok and the provider return one. |
| `hashtags` | Hashtags attached to the video. |
| `mentions` | Mentioned TikTok handles from caption metadata. |
| `musicTitle` | TikTok sound or song title. |
| `musicAuthor` | Music artist or sound owner. |

The actor also writes `OUTPUT` and `RUN_SUMMARY` to the key-value store. These contain profile counts, provider status codes, provider errors, estimated PPE cost, providers used, and the final stop reason. This is useful when an automation needs to decide whether the run was empty, provider-blocked, or capped by billing settings.

### Pricing

This actor uses pay per event:

| Event | Price | When charged |
| --- | ---: | --- |
| `apify-actor-start` | `$0.00005` | Once per run, scaled by memory. |
| `post-scraped` | `$0.0015` | Each validated TikTok profile post row persisted. |

A 10-video test run costs about `$0.01505` before Apify platform usage costs. A 100-video run costs about `$0.15005`.

### Provider Strategy

TikTok's public web surface is heavily protected and changes often, so this actor uses provider-backed public-data endpoints instead of fragile browser scraping. The default chain is:

1. ScrapeCreators
2. SociaVault

You can force one provider with `scrapecreators-only` or `sociavault-only` for testing. If the actor owner has not configured at least one provider key, the run exits with a clear diagnostic message instead of failing with a stack trace.

### Limits

- Only public TikTok profile video data is supported.
- Direct TikTok CDN URLs may expire. Download important media promptly.
- No-watermark URLs are returned only when TikTok and the provider expose them.
- Ordering can vary by provider and TikTok freshness.
- Results can differ by region.
- Private, deleted, restricted, or login-only posts are not covered.

### API Example

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/tiktok-profile-posts-scraper').call({
  profileHandles: ['stoolpresidente', 'nike'],
  maxPostsPerProfile: 20,
  maxPagesPerProfile: 2,
  sortBy: 'latest',
  region: 'US'
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

### Legal

This actor is intended for scraping publicly available TikTok data. You are responsible for using the output in compliance with applicable laws, platform terms, privacy obligations, and content rights. Do not use this actor to collect private data, bypass access controls, or republish copyrighted media without permission.

# Actor input Schema

## `profileHandles` (type: `array`):

Use this when you want posts from one or more public TikTok creator profiles. Accepts handles like nike, @nike, or full URLs like https://www.tiktok.com/@nike. Defaults to the prefilled example for testing. Not for keyword, hashtag, comment, or single-video scraping.

## `providerOrder` (type: `string`):

Use this to choose which public-data provider is tried first. ScrapeCreators is the recommended primary and SociaVault is the fallback. Defaults to ScrapeCreators first. Not a browser mode and does not use TikTok cookies.

## `maxPostsPerProfile` (type: `integer`):

Use this to cap how many posts are saved from each creator profile. Accepts integers from 1 to 10000. Defaults to 50 and the prefill is 10 for quick tests. This is the main per-profile billing guard.

## `maxPagesPerProfile` (type: `integer`):

Use this as a safety cap for provider pagination on each creator feed. Accepts integers from 1 to 500. Defaults to 10 and the prefill is 1 for fast quality checks. Not a result limit by itself.

## `maxTotalPosts` (type: `integer`):

Use this to cap the whole run across all profile inputs. Accepts integers from 1 to 50000. Defaults to 10000 and the prefill is 50. This prevents accidental overbilling on large creator batches.

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

Use this to request a provider-supported creator feed order. Accepted values are latest and popular. Defaults to latest. Not all providers return identical ordering for the same profile.

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

Use this to localize provider requests with an alpha-2 country code. Example values are US, GB, FR, or PH. Defaults to US. This is not a language filter and does not translate captions.

## `trim` (type: `boolean`):

Use this to request smaller provider payloads when supported. The normalized dataset fields stay the same. Defaults to true for speed and lower memory use. Turn it off only when debugging with Include Raw Provider Data.

## `includeRawData` (type: `boolean`):

Use this when you need the original provider response attached to each dataset row. It helps debug field drift or build custom parsers. Defaults to false. Not recommended for AI-agent runs because raw payloads are large.

## Actor input object example

```json
{
  "profileHandles": [
    "stoolpresidente"
  ],
  "providerOrder": "scrapecreators-first",
  "maxPostsPerProfile": 10,
  "maxPagesPerProfile": 1,
  "maxTotalPosts": 50,
  "sortBy": "latest",
  "region": "US",
  "trim": true,
  "includeRawData": false
}
```

# Actor output Schema

## `output` (type: `string`):

Stable machine-readable outcome, item count, charged events, and warnings.

## `results` (type: `string`):

Normalized TikTok profile post records with captions, metrics, media URLs, music, author, and source metadata.

## `runSummary` (type: `string`):

Run-level summary with provider diagnostics, counts, billing counters, and stop reason.

# 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 = {
    "profileHandles": [
        "stoolpresidente"
    ],
    "maxPostsPerProfile": 10,
    "maxPagesPerProfile": 1,
    "maxTotalPosts": 50,
    "region": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/tiktok-profile-posts-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 = {
    "profileHandles": ["stoolpresidente"],
    "maxPostsPerProfile": 10,
    "maxPagesPerProfile": 1,
    "maxTotalPosts": 50,
    "region": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/tiktok-profile-posts-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 '{
  "profileHandles": [
    "stoolpresidente"
  ],
  "maxPostsPerProfile": 10,
  "maxPagesPerProfile": 1,
  "maxTotalPosts": 50,
  "region": "US"
}' |
apify call khadinakbar/tiktok-profile-posts-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/3hl8NX0mDAdpwhly3/builds/g3kSEHXfw5vm6Wd8B/openapi.json
