# TikTok Profile Scraper (Engagement Rate & Brand Deals) (`locaihost/tiktok-creators`) Actor

Scrape TikTok creator profiles plus their recent public videos into one row each: followers, likes, engagement rate, median views, posting cadence, top hashtags and brand-deal share. Same formula for every creator. Not-found accounts are free. No login. $30 per 1,000 creator reports.

- **URL**: https://apify.com/locaihost/tiktok-creators.md
- **Developed by:** [locaihost data](https://apify.com/locaihost) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $16.50 / 1,000 creator reports

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?

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 Profile Scraper (Engagement Rate & Brand Deals)

Vet TikTok creators before you book them: give it handles or profile URLs and get one row per creator with the public profile plus engagement rate, median views, posting cadence, top hashtags and brand-deal share from their recent public videos, as JSON, CSV or Excel. No login, no cookies.

- **Vet influencers before a campaign:** is the engagement real, is the creator still posting, and how much of their feed is already sponsored?
- **Compare a shortlist side by side:** every creator is measured with the same formulas, so two creators' numbers mean the same thing.
- **Re-check a roster every month:** follower growth, cadence and paid-deal share for the creators you already work with.
- **Feed an influencer platform or an AI agent:** one list of handles in, the same columns out for every creator.

### Quick start

Paste this into the **JSON** tab of the input and click **Start**:

```json
{"handles": ["khaby.lame", "@duolingo", "https://www.tiktok.com/@nba"]}
```

You get 3 creator reports in about a minute (creators are checked in parallel, so 6 creators take about as long as 3). Handles, `@handles`, profile URLs and video URLs all work; the same creator listed twice is fetched and charged once.

### What data can I get?

| Group | Fields |
|---|---|
| Status | `status`, `statusMessage`, `reportType`, `videosStatus`, `input` |
| Profile | `handle`, `nickname`, `bio`, `bioLink`, `bioLinkUrl`, `verified`, `profileUrl`, `userId`, `secUid`, `language`, `createdAt`, `avatarUrl` + `avatarUrlExpiresAt` |
| Account type | `isBusinessAccount`, `businessCategory`, `isTikTokShopSeller`, `isOrganization` |
| Counts | `followerCount`, `followingCount`, `heartCount` (total likes), `videoCount`, `countsExact` |
| Analytics | `analytics.engagementRate`, `engagementRatePerFollower`, `medianViews`, `avgViews`, `viewsPerFollower`, `postingCadencePerWeek`, `daysSinceLastPost`, `brandDealRate`, `brandDealVideoIds`, `topHashtags`, `lifetimeLikesPerVideo`, `lifetimeLikesPerFollower`, `videosAnalyzed`, `windowStart`, `windowEnd` |
| Recent videos | `recentVideos[]`: `url`, `createdAt`, `description` (caption), `views`, `likes`, `comments`, `shares`, `saves`, `durationSec`, `hashtags`, `paidPartnership`, `isAd` |

How the analytics are worked out:

| Field | What it means |
|---|---|
| `engagementRate` | (likes + comments + shares) ÷ views over the analysed videos, weighted by views. Saves are not counted |
| `engagementRatePerFollower` | Average interactions per video ÷ followers |
| `medianViews`, `avgViews` | Typical views per video. The median isn't skewed by one viral post |
| `viewsPerFollower` | Median views ÷ followers: does the audience actually see the posts? |
| `postingCadencePerWeek` | Videos per week from the oldest analysed video to now, never over less than one week |
| `brandDealRate` | Share of posts with TikTok's "Paid partnership" label, TikTok's ad flag, or a disclosure hashtag such as #ad, #sponsored or #brandpartner |
| `topHashtags` | The hashtags used most, with how many videos use each |

Pinned videos are left out of every number: they are a showcase and can be years old.

One real row (run on 2026-10-18, shortened; `recentVideos` holds the 30 videos behind the numbers):

```json
{
  "handle": "duolingo",
  "status": "ok",
  "reportType": "creator-report",
  "profileUrl": "https://www.tiktok.com/@duolingo",
  "nickname": "Duolingo",
  "bioLinkUrl": "https://duolingo.com/",
  "verified": true,
  "isOrganization": true,
  "isBusinessAccount": true,
  "businessCategory": "Shopping & Retail",
  "followerCount": 18266486,
  "heartCount": 505437895,
  "videoCount": 1203,
  "countsExact": true,
  "videosStatus": "included",
  "analytics": {
    "videosAnalyzed": 30,
    "engagementRate": 0.170582,
    "medianViews": 618950,
    "viewsPerFollower": 0.033884,
    "postingCadencePerWeek": 5.62,
    "daysSinceLastPost": 4.5,
    "brandDealRate": 0,
    "topHashtags": [{"tag": "le_sserafim", "videos": 4}, {"tag": "duolingo", "videos": 1}]
  },
  "recentVideos": [{"url": "https://www.tiktok.com/@duolingo/video/7696211706317409550", "createdAt": "2026-10-13T17:52:19.000Z", "views": 2200000, "likes": 444600, "comments": 7012, "shares": 81000, "saves": 49960, "durationSec": 12, "paidPartnership": false}]
}
```

Every creator you list gets a row, and `status` says what happened:

| `status` | Meaning | Charged |
|---|---|---|
| `ok` | Profile read (`reportType` says whether as a creator report or a profile) | Yes |
| `not-found` | No account uses this handle (or it was renamed) | No |
| `private` | Private account. The row carries nothing else about it | No |
| `unavailable` | Banned, restricted or deactivated | No |
| `blocked` | TikTok blocked the request, even after switching proxy. Try again later | No |
| `error` | The page couldn't be read | No |

The dataset has two views (**Creators** and **Recent videos**) and exports to JSON, CSV, Excel or HTML. The run's `SUMMARY` record counts creators by status.

### How much does it cost?

You pay per creator returned. There is no charge for Apify platform usage on top, and the residential proxy TikTok's video list needs is included.

| Row | Free and Starter | Scale | Business |
|---|---|---|---|
| Creator report (profile + analytics + recent videos) | $30 per 1,000 | $22.50 per 1,000 | $16.50 per 1,000 |
| Creator profile (profile only) | $3 per 1,000 | $2.25 per 1,000 | $1.65 per 1,000 |

Plus $0.00005 per run start. **Apify's free $5 monthly credit covers about 160 creator reports** (or about 1,600 profile-only rows). Free-plan runs return up to **25 creators per run** (only charged creators count); any paid Apify plan removes the cap.

A row is charged as a profile, not a report, when you turn `includeVideos` off or when TikTok doesn't show that creator's videos (`videosStatus` says why). Example: 200 creators, of which 185 come back as reports, 10 as profiles and 5 not found, cost 185 × $0.03 + 10 × $0.003 = **$5.58** at the Starter price.

**What's free:** not-found, private, unavailable, blocked and unreadable creators, repeats of a creator already in the list, entries that aren't a TikTok handle, creators skipped by `onlyNew`, and creators not started before the run's time limit or your spending limit. To cap a run's spend, set **Maximum cost per run** in the run options: the run stops cleanly and says how many creators were left.

### Limits, stated up front

- **Logged-out view only.** The Actor sees what any visitor without an account sees. TikTok hides some posts from logged-out visitors, so a creator's video list can be incomplete and the analytics cover the public posts only.
- **Counts are what TikTok shows publicly.** Profile counts are exact when TikTok sends exact numbers (`countsExact: true`). Per-video views, likes, comments and shares come rounded by TikTok above 10,000 (for example 2,200,000); saves are exact. Videos posted in the last few hours are still collecting views.
- **Up to 60 videos per creator** (`maxVideosPerCreator`, 30 by default). 30 covers about a month for a creator who posts daily.
- **No audience demographics, follower lists, comments or contact details.** Those need a login or belong to other people.
- **The paid-deal share is a signal, not an audit.** Undisclosed deals can't be detected. On brand accounts TikTok's ad flag marks the brand's own promoted posts, so it isn't counted there.
- **Short links** (vm.tiktok.com/…) aren't supported. Open them and paste the profile URL.
- **Speed:** creators run up to 6 at a time at the default 4 GB memory (fewer at lower memory). A creator report usually takes 20 to 60 seconds, depending on how quickly TikTok hands over the video list. Near the run's time limit the Actor stops starting new creators and ends cleanly with what it has.
- TikTok can change its site at any time. When it does, rows say so and nothing is charged for them.

**Privacy.** Public creator data only. The Actor never logs in, never uses cookies or accounts, and never asks you for one. Email addresses and phone numbers are removed from bios, names and captions before anything is stored, and a bio link that is a phone or email (WhatsApp, `mailto:`) is dropped. Private accounts get no data at all.

### Only new since last run, and schedules

Turn on `onlyNew` in a saved task and the Actor skips creators that task has already returned and charged, so a growing list only vets (and charges for) the new names. Skipped creators cost nothing. It's off by default, so a normal run always returns everyone. To re-check a roster on a timetable, set up a schedule under **Schedules** in Apify Console.

### Integrations: API, n8n, Make and AI agents

**API.** Run it and get the rows back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/locaihost~tiktok-creators/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"handles": ["khaby.lame", "@duolingo"]}'
```

Apify's API clients for Python and JavaScript work the same way.

**n8n, Make, Zapier, Google Sheets, Slack, webhooks.** Apify's built-in integrations send each run's dataset wherever you need it.

**AI agents (MCP).** Add this Actor to Claude, Cursor or any MCP client with `https://mcp.apify.com/?tools=locaihost/tiktok-creators`, then ask something like *"Which of these 10 creators has the highest engagement rate and the fewest sponsored posts?"*

### FAQ

#### How much does it cost to scrape TikTok creator profiles?

On the Free and Starter plans, $30 per 1,000 creator reports ($22.50 on Scale, $16.50 on Business) and $3 per 1,000 profiles ($2.25 on Scale, $1.65 on Business). Not-found and private accounts are free. Apify's free $5 monthly credit covers about 160 creator reports.

#### Can I use it through the API or from Python?

Yes. Use the `run-sync-get-dataset-items` call above, or Apify's Python and JavaScript clients. Every run's data is also available as JSON, CSV or Excel from its dataset.

#### Can I use it from an AI agent?

Yes. Through the Apify MCP server (`https://mcp.apify.com/?tools=locaihost/tiktok-creators`) any MCP client can call it with a list of handles and read the rows back.

#### Is it legal to scrape TikTok profiles?

The Actor reads only what TikTok shows to anyone who is not logged in: public profiles and public videos. It never logs in, skips private accounts and never collects follower lists, commenters, email addresses or phone numbers. TikTok's own terms restrict automated access, so check that your use fits them and the data-protection rules that apply to you. You are responsible for how you use the results.

#### Why are some fields empty?

`private`, `not-found` and other non-`ok` rows carry only the status and the reason. When TikTok doesn't show a creator's videos, the row has the profile but no `analytics` or `recentVideos`, and `videosStatus` says why. `bioLink` and `businessCategory` are empty when the creator hasn't set them.

#### How is the engagement rate calculated?

Likes, comments and shares summed over the analysed videos, divided by their total views. A video with ten times the views carries ten times the weight, and pinned videos are left out.

### More from locaihost data

- [TikTok Trends Scraper](https://apify.com/locaihost/tiktok-trends): trending hashtags, videos and top ads by country, to find creators worth vetting.
- [TikTok Shop Product Scraper](https://apify.com/locaihost/tiktok-shop): products, prices and sales from TikTok Shop searches and categories.
- [Google Trends Scraper](https://apify.com/locaihost/google-trends): check whether a creator's topic is growing before you commit a budget.

### Did it help?

If this saved you time, a quick rating on the Store helps other people find it.

### Support

Something not working, or a field you need? Open an issue on the **Issues** tab: we answer issues within 24 hours.

# Changelog

This Actor's version history is a separate document: https://apify.com/locaihost/tiktok-creators/changelog.md

# Actor input Schema

## `handles` (type: `array`):

Handles or profile URLs, in any form TikTok shows them: "khaby.lame", "@duolingo", "https://www.tiktok.com/@nba", or a video URL. Each creator becomes one row. Repeats are fetched and charged once. Short links (vm.tiktok.com/…) are not supported: open them and paste the profile URL.

## `includeVideos` (type: `boolean`):

Read each creator's recent public videos and add engagement rate, median views, posting cadence, top hashtags and brand-deal share. A row with videos is charged as a creator report; turn this off for cheaper, faster profile-only rows.

## `maxVideosPerCreator` (type: `integer`):

The newest this many public videos (pinned videos are left out). 30 covers about a month for a creator who posts daily.

## `onlyNew` (type: `boolean`):

Skip creators this saved task already returned (and charged) in an earlier run, so a growing list only vets the additions. Off by default, so every run returns every creator.

## `proxyConfiguration` (type: `object`):

Apify Proxy by default. Profile-only rows start on datacenter proxies and switch to residential only if TikTok blocks them. Videos always load through residential proxies (included in the price), because TikTok refuses the video list to datacenter IPs.

## Actor input object example

```json
{
  "handles": [
    "khaby.lame",
    "@duolingo",
    "https://www.tiktok.com/@nba"
  ],
  "includeVideos": true,
  "maxVideosPerCreator": 30,
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `creators` (type: `string`):

One record per creator: status, profile counts, bio link, and the analytics block from recent videos.

## `summary` (type: `string`):

Creators returned, not found and blocked, proxy tier used, field-drift check and measured cost.

# 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 = {
    "handles": [
        "khaby.lame",
        "@duolingo",
        "https://www.tiktok.com/@nba"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("locaihost/tiktok-creators").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 = {
    "handles": [
        "khaby.lame",
        "@duolingo",
        "https://www.tiktok.com/@nba",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("locaihost/tiktok-creators").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 '{
  "handles": [
    "khaby.lame",
    "@duolingo",
    "https://www.tiktok.com/@nba"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call locaihost/tiktok-creators --silent --output-dataset

```

## MCP server setup

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

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/JVGG4BLF5kQMmXQH5/builds/Bfg4W0QraDlxrxLQC/openapi.json
