# TikTok Profile Scraper | Followers, Likes, Bio | $0.35 / 1K (`hridayrungta/tiktok-profile-scraper`) Actor

TikTok API alternative for profile data: followers, following, likes, videos, bio, verified, plus engagement ratios, creator tier and follower-change tracking. No login. $0.35 per 1,000 profiles. Does not list videos or comments.

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

## Pricing

from $0.20 / 1,000 profile scrapeds

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 data API alternative.** Paste TikTok usernames, @handles or profile links and get one clean, flat row per creator: follower count, following, total likes, video count, bio, verified flag, account age and simple ratios for vetting influencers. Turn on change tracking and a schedule to watch follower growth over time. No login, no cookies, no browser. **$0.35 per 1,000 profiles on the Free plan** (cheaper on paid plans, see Pricing).

### TikTok analytics and follower count data for creator vetting

Use it when you need numbers, not videos:

- **TikTok follower count** for a list of creators, in a spreadsheet-ready table
- **TikTok influencer data** for outreach lists: tier (nano to mega), bio, bio link, verified, organization and shop-seller flags
- **TikTok analytics ratios** to compare creators: likes per video, likes per follower, followers per video, follower-to-following ratio, account age
- **TikTok user data for lead lists**: bio text and bio link next to the audience size
- **Follower tracking** on a schedule: followers, likes and video count change since the previous run
- **A TikTok API alternative** for public profile stats, with no developer approval process

Every number comes from the public profile page. Nothing is estimated or invented.

### What data you get

| Group | Fields |
|---|---|
| Identity | `username`, `url`, `nickname`, `bio`, `bioLink`, `language`, `userId`, `secUid`, `avatarUrl` |
| Flags | `verified`, `privateAccount`, `isOrganization`, `isShopSeller` |
| Counts | `followers`, `following`, `likes`, `videos`, `friends` |
| Account dates | `accountCreatedAt`, `nicknameChangedAt`, `accountAgeDays` |
| Ratios (computed) | `likesPerVideo`, `likesPerFollower`, `followersPerVideo`, `followRatio`, `estimatedTier` |
| Change tracking (optional) | `followersChange`, `likesChange`, `videosChange`, `previousScrapedAt` |
| Run info | `status`, `input`, `scrapedAt` |

The output is flat, so it exports cleanly to CSV, Excel, Google Sheets or JSON. Profiles that are private, deleted, not found or blocked get a row with a `status` and are **never charged**.

#### How the ratios are calculated

These are simple ratios of the counts on the page. They are **not TikTok's own engagement metric**.

- `likesPerVideo` = likes / videos
- `likesPerFollower` = likes / followers
- `followersPerVideo` = followers / videos
- `followRatio` = followers / following
- `accountAgeDays` = whole days since `accountCreatedAt`
- `estimatedTier` = a follower bucket: `nano` (under 10k), `micro` (10k to 100k), `mid` (100k to 500k), `macro` (500k to 1M), `mega` (1M and up)

A ratio is empty (`null`) when it cannot be computed, for example likes per video for an account with zero videos.

### Input

| Field | Type | What it does |
|---|---|---|
| `profiles` | list | Usernames (`nasa`), @usernames (`@nasa`), profile URLs (`https://www.tiktok.com/@nasa`) or TikTok short links (`vm.tiktok.com/...`, `tiktok.com/t/...`). Duplicates are removed and the first occurrence is kept. |
| `maxItems` | number | Cost cap: process at most this many profiles. Default 100. |
| `compareWithPreviousRun` | true/false | Adds the four change columns by comparing with the counts saved at the previous run. Default off. |
| `historyStoreName` | text | Name of the key-value store that keeps the previous counts. Default `tiktok-profile-history`. Use one name per monitored list. |
| `maxConcurrency` | number | Parallel page fetches, 1 to 10. Default 5. |
| `useProxyFallback` | true/false | Retry refused pages on fresh Apify datacenter proxy sessions. Default on, no extra price. |

Short links are followed to their destination without downloading the page. If the link leads to a profile or a video, the creator's profile is scraped. A link that does not resolve gets an `invalid-link` row, which is not charged.

Example input:

```json
{
  "profiles": ["nasa", "@khaby.lame", "https://www.tiktok.com/@mrbeast"],
  "compareWithPreviousRun": true,
  "historyStoreName": "my-creator-watchlist"
}
```

### Output example

A real row from a run with change tracking on (`avatarUrl` and `secUid` shortened here):

```json
{
  "status": "ok",
  "username": "nasa",
  "url": "https://www.tiktok.com/@nasa",
  "nickname": "NASA",
  "bio": "Making the seemingly impossible, possible.✨",
  "bioLink": "science.nasa.gov/feature/artemis-ii-preliminary-lunar-science-report",
  "verified": true,
  "privateAccount": false,
  "isOrganization": true,
  "isShopSeller": false,
  "language": "en",
  "accountCreatedAt": "2026-07-20T15:55:49.000Z",
  "nicknameChangedAt": "2026-07-20T15:58:00.000Z",
  "followers": 2149942,
  "following": 23,
  "likes": 11466530,
  "videos": 62,
  "friends": 17,
  "likesPerVideo": 184944.03,
  "likesPerFollower": 5.333,
  "followersPerVideo": 34676.48,
  "followRatio": 93475.74,
  "accountAgeDays": 102,
  "estimatedTier": "mega",
  "userId": "7664638705177150477",
  "secUid": "MS4wLjABAAAAU9BRVzC8oCaeg…",
  "avatarUrl": "https://p19-common-sign.tiktokcdn-us.com/…",
  "followersChange": 0,
  "likesChange": 7,
  "videosChange": 0,
  "previousScrapedAt": "2026-10-31T15:32:41.717Z",
  "scrapedAt": "2026-10-31T15:33:05.883Z"
}
```

### Pricing

Pay per result. A profile is charged only when it comes back with data.

| Plan | Per 1,000 profiles |
|---|---|
| Free | $0.35 |
| Bronze | $0.30 |
| Silver | $0.25 |
| Gold and above | $0.20 |

Plus a one-time **$0.0002 start fee** per run on every plan.

Worked examples on the Free plan:

- 100 profiles: $0.0002 + 100 x $0.00035 = about $0.035
- 1,000 profiles: about $0.35
- 10,000 profiles: about $3.50
- Daily follower tracking of 500 creators: about $0.175 per day, roughly $5.30 per month

Private, deleted and not-found profiles are free. A list full of invalid names stops after a few misses, so a bad list costs almost nothing. Set `maxItems` or Apify's maximum cost per run to cap spending. Platform usage is included in the price above.

### Integrations and scheduling

Recurring runs are what this Actor is built for. Create an **Apify Schedule** (hourly, daily or weekly), keep `compareWithPreviousRun` on, and every run adds how much each creator grew or shrank since the last one.

**Follower tracking setup, 5 minutes:**

1. Open the Actor, enter your creator list and turn on **Compare with previous run**.
2. Set a **History store name** for this list, for example `my-creator-watchlist`.
3. Run once. This run creates the baseline, so the change columns are empty.
4. Click **Schedule** and choose daily or weekly.
5. From the second run on, read `followersChange`, `likesChange` and `videosChange` in the **Change tracking** table view.

Send the results anywhere:

- **Google Sheets**: Apify's Google Sheets integration appends each run
- **Make, n8n and Zapier**: trigger a scenario when a run finishes, then read the dataset
- **Webhooks**: Apify calls your URL on run success, for example to alert you when `followersChange` passes a threshold
- **API**: `GET /v2/datasets/{id}/items?format=csv` returns the table as CSV

The history is one record in a key-value store in your own Apify account. Runs that share the same store name share the same history.

### Tutorial: build a creator shortlist

1. Paste 50 to 500 usernames or profile links into **Profiles**.
2. Run the Actor and open the **Creator vetting** view.
3. Sort by `estimatedTier` or `followers` to pick the size you need.
4. Check `likesPerVideo` and `likesPerFollower` to spot accounts whose total likes are very low for their size.
5. Check `accountAgeDays` and `videos` to separate new accounts from established ones.
6. Export as CSV and add the shortlist to your outreach sheet.

### FAQ

#### Why not the official TikTok API?

TikTok's official APIs are built for apps that act on behalf of logged-in users, and they require developer approval, app review and user authorization. For reading public stats of any creator you name, an approval process is a poor fit. This Actor reads the same public profile page anyone can open in a browser. It has no relationship with TikTok and is not endorsed by it.

#### What is the best TikTok follower count API alternative?

For follower counts, likes and video counts of named profiles, this Actor costs less per profile than the clockworks and abe Actors on the Store (their Free-plan prices are $3 and $5 per 1,000 results), while apidojo charges a flat $0.30. If you also need profile video lists or comments, use one of the alternatives, which cost more per result.

#### How do I calculate TikTok engagement rate honestly?

The standard engagement rate is (likes + comments + shares) / views, measured per video. That needs per-video numbers, which this Actor does not return. `likesPerFollower` here divides lifetime likes by current followers, so one old viral video can inflate it for years. Treat the ratios as a quick screening tool and measure real engagement on a creator's recent videos before you pay for a partnership.

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

This Actor reads only public profile pages, with no login. Public data is generally lawful to collect, but rules differ by country and by use. Personal data such as names and bios can fall under privacy law like GDPR. TikTok's terms of service also restrict automated access. You are responsible for how you use the data. This is not legal advice.

#### Are the counts exact?

The numbers are what TikTok shows on the public profile at that moment. Counts of live accounts move every few seconds, so two runs a minute apart can differ by a few units. `accountCreatedAt` is the creation time TikTok includes in the page data.

#### What can this Actor not do?

- It cannot list a profile's videos
- It cannot scrape followers or following lists
- It cannot scrape comments
- It cannot search by hashtag or keyword
- It cannot read private accounts

TikTok only serves those through signed, app-style requests, and this Actor does not forge signatures or log in. Rows for profiles it cannot read are marked `private`, `not-found`, `unavailable` or `blocked`.

### Honest limits

- Only public profile counts and details. No videos, comments, follower lists or search.
- If TikTok refuses many requests in a row, the run stops early and unreadable rows are not charged.
- Ratios are simple arithmetic on lifetime totals, not an engagement score.
- Change tracking compares with the last run that used the same history store name. A parallel run with the same store can overwrite another's snapshot for the same username.
- The first tracked run has empty change columns because there is nothing to compare with.

### Related Actors

- [TikTok Profile & Video Data Scraper](https://apify.com/hridayrungta/tiktok-profile-video-scraper): profile stats plus single-video stats by URL, from the same author
- [TikTok Video Scraper](https://apify.com/hridayrungta/tiktok-video-scraper): video data, from the same author
- [TikTok Scraper by clockworks](https://apify.com/clockworks/tiktok-scraper): videos, comments, hashtags and search at a higher price per result
- [TikTok Profile Scraper by clockworks](https://apify.com/clockworks/tiktok-profile-scraper): profiles with their video lists
- [TikTok Profile Scraper by apidojo](https://apify.com/apidojo/tiktok-profile-scraper): another profile scraper with flat pricing

# Actor input Schema

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

TikTok usernames (nasa), @usernames (@nasa), profile URLs (https://www.tiktok.com/@nasa) or short links (https://vm.tiktok.com/...), one per line. Duplicates are removed, first occurrence kept. One row per profile. This Actor cannot list a profile's videos (see the README).

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

Cost cap: the run processes at most this many profiles from your list.

## `compareWithPreviousRun` (type: `boolean`):

Adds followersChange, likesChange, videosChange and previousScrapedAt by comparing with the last counts this Actor saved for each username. Best used with an Apify Schedule. The first run only creates the baseline (change columns are empty).

## `historyStoreName` (type: `string`):

Name of the key-value store (in your account) that keeps the last follower, likes and video counts per username for change tracking. Use a different name per list you monitor. Only used when 'Compare with previous run' is on.

## `maxConcurrency` (type: `integer`):

How many profile pages are fetched at the same time. 5 is a safe default.

## `useProxyFallback` (type: `boolean`):

Pages are fetched directly first. If TikTok refuses the request, it is retried on up to two fresh Apify datacenter proxy sessions (no extra price per request).

## Actor input object example

```json
{
  "profiles": [
    "nasa",
    "khaby.lame"
  ],
  "maxItems": 10,
  "compareWithPreviousRun": false,
  "historyStoreName": "tiktok-profile-history",
  "maxConcurrency": 5,
  "useProxyFallback": true
}
```

# 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 = {
    "profiles": [
        "nasa",
        "khaby.lame"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("hridayrungta/tiktok-profile-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 = {
    "profiles": [
        "nasa",
        "khaby.lame",
    ],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("hridayrungta/tiktok-profile-scraper").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 '{
  "profiles": [
    "nasa",
    "khaby.lame"
  ],
  "maxItems": 10
}' |
apify call hridayrungta/tiktok-profile-scraper --silent --output-dataset

```

## MCP server setup

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

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/GMWRHoOybBYI5bpZt/builds/lu8fHC8y3Iiake0SW/openapi.json
