TikTok Followers & Following Scraper: TikTok Followers List
Pricing
from $1.00 / 1,000 follower or following accounts
TikTok Followers & Following Scraper: TikTok Followers List
TikTok followers scraper and following scraper: export the followers list and following list of any TikTok account, one row per follower with exact follower count, user id, secUid, bio, verified flag and follow time window. Newest first up to 10,000; only new followers on a schedule. No login.
Pricing
from $1.00 / 1,000 follower or following accounts
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
13
Total users
4
Monthly active users
3 hours ago
Last modified
Categories
Share
The followers and following lists of any TikTok account, newest first, one row per listed account with its exact follower count — 4,242,144, not 4,200,000 — its user id, secUid, bio, verified and private flags, and the window it followed in. Give handles, profile URLs, user ids, secUids or share links; ask for followers, following or both, with a cap per list. TikTok serves about the newest 10,000 followers of an account to a logged-out reader (of a few large accounts, one page of 50): every list ends with a verdict that says whether it ended at TikTok's window, at your cap, or at the list's end. Run it on a schedule with onlyNew and get only the followers that came since the last run — 0 rows and $0 when none did. Accounts that do not exist, are private or hide a list come back as a typed row, free. No login, no cookies, proxies handled for you.
Why this scraper, not the other TikTok followers actors
- Exact counts on every listed account. TikTok's list carries each follower's exact follower, following, like and video counts next to the rounded ones the app shows. The lane leader returns the rounded ones and no secUid; here every row has
followers(exact) andfollowers_shown(as the app shows it), withcounts_precisionsaying which you got, plususer_idandsec_uid. - The follow time, for free. TikTok's page cursor is the follow second of the page's last row, so every row carries the window it was followed in (
followed_after,followed_before, about 30 follows wide) and itspositionin the list (1 = newest), at no extra cost: the walk reads only the 30-row pages. - Honest about the end of the list. Logged out, TikTok serves about the newest 10,000 followers of an account and nothing older (measured on accounts from 143,000 to 143,000,000 followers); of a few large accounts it serves one page of 50 of each list, whatever is asked (gymshark, adidas and bbcnews of 31 brands we tried). Every list ends with a verdict: COMPLETE (TikTok said the list ended), SOURCE-LIMIT (TikTok's window, with the oldest follow time reached), CAPPED (your cap), NEW-ONLY or SINCE. Never a short dataset that looks whole.
- Only the new followers since the last run. With
onlyNewa scheduled run reads from the newest follower down to the last run's read time (two minutes past it, for the follows TikTok shows late), skips every follower an earlier run delivered and delivers only the ones that came since, newest first; none came, 0 rows and nothing charged. Inside TikTok's window that is every new follower of an account that gains fewer than 10,000 between runs (fewer than 50 on the few accounts TikTok serves one page of). - Exact caps, free misses. 2 asked = 2 delivered and charged. An account that does not exist, is private, or hides its following list gives one typed account row with TikTok's own status code, free. Filters (min / max followers, verified only, an e-mail in the bio, bio keywords) run before the bill: a row left out is not charged. Ready-made: TikTok creators that brands follow, with an e-mail in the bio.
- Fast and plain. The lists are read over plain HTTP, logged out, no browser: a 10,000-row list in about 2.5 minutes, a 2 + 2 run in a few seconds. Both lists of an account and several accounts are read side by side.
- Contacts from the bio, settings, and more on request. Each row has the e-mails, phone numbers and links found in the bio, the listed account's comment / duet / stitch / download settings and its TikTok Shop flag (TikTok shows no bio and no comment, duet or stitch setting of a private account).
includeProfileDetailsadds the created date, language, bio link and business category from each listed account's own page. Ready-made: TikTok followers with account created date and language.
Who it's for
- Influencer marketing teams and agencies — see who follows a creator and whom a creator follows, with exact counts per listed account, to vet audiences and find look-alike creators.
- Brands and growth teams — watch a competitor's or your own account on a schedule and get only the new followers of each day, with the window each one followed in.
- Lead generation and outreach — the followers of an account in a niche, filtered to verified accounts, a follower range or an e-mail in the bio, with the contacts extracted.
- Researchers and data teams — newest-first lists with positions, follow-time windows, stable ids (user id, secUid) and an honest end-of-list verdict, ready to join across runs.
Quick start
The newest 1,000 followers of an account
{"accounts": ["notionhq"],"maxFollowersPerAccount": 1000}
Followers and following of several accounts
{"accounts": ["notionhq","figma","https://www.tiktok.com/@duolingo"],"lists": "both","maxFollowersPerAccount": 500,"maxFollowingPerAccount": 500}
Everything TikTok serves (about the newest 10,000)
{"accounts": ["notionhq"],"lists": "followers"}
Only new followers since the last run (schedule it)
{"accounts": ["notionhq"],"onlyNew": true}
Verified followers with 10,000+ followers and an e-mail in the bio
{"accounts": ["notionhq"],"verifiedOnly": true,"minFollowers": 10000,"withEmailOnly": true}
Output
One row per follower or following account (row_type user), and one free row per input account with its record, its status and each list's verdict (row_type account):
| field | meaning |
|---|---|
row_type | user (one follower or following account) or account (one per input: the target's record, its status and each list's verdict; free). |
relation | On user rows: follower (follows of_username) or following (of_username follows them). |
of_user_id | The account whose list this row comes from (its numeric user id, as a string). |
of_username | That account's handle. |
input | What you gave in accounts, verbatim. |
position | The row's place in the list, 1 = the newest follower (or the most recent follow). Positions are counted 30 a page, so an account TikTok dropped from a page leaves a gap at the page's end. |
scraped_at | When the row was read (UTC). |
user_id | TikTok's numeric user id of the listed account, as a string. Stable across renames. |
sec_uid | TikTok's secUid of the listed account, the id its own APIs take. |
username | The listed account's handle, without @. |
nickname | The listed account's display name. |
bio | The listed account's profile text; empty when it has none, and on a private account (TikTok does not show it). |
bio_emails | E-mail addresses found in the bio text (a regex; a @mention is not one). Empty when none. |
bio_phones | Phone numbers found in the bio text (8 to 15 digits). Empty when none. |
bio_links | URLs and bare domains found in the bio text. Empty when none. |
profile_url | https://www.tiktok.com/@ |
avatar_url | The avatar at 1080 px (an expiring TikTok link). |
avatar_medium_url | The avatar at 720 px. |
avatar_thumb_url | The avatar at 100 px. |
verified | TikTok's verified badge on the listed account. |
private_account | The listed account is private. |
followers | The listed account's followers, exact (TikTok's statsV2); on an account row, the target's exact follower count. |
following | Accounts followed, exact. |
likes | Likes received (hearts), exact. |
videos | The account's video count. |
friends | Mutual follows. |
followers_shown | Followers as the app rounds them (4,200,000 for 4,242,144). |
following_shown | Following as the app shows it. |
likes_shown | Likes as the app rounds them. |
videos_shown | Videos as the app shows them. |
counts_precision | exact (TikTok's exact counts) or as_shown (only the rounded ones were served). |
followed_after | The follow happened at or after this time (UTC): the follow-time window's start, from TikTok's page cursor (the follow second of the page's last row). |
followed_before | The follow happened at or before this time (UTC): the previous page's cursor, or the read time on the newest page. |
follow_window_seconds | followed_before minus followed_after: how precisely the follow time is known (about 30 follows wide). |
comment_setting | everyone, friends or nobody (the listed account's setting); null on a private account (TikTok does not show it). |
duet_setting | everyone, friends or nobody; null on a private account. |
stitch_setting | everyone, friends or nobody; null on a private account. |
download_setting | everyone, friends or nobody. |
liked_public | The listed account shows the videos it liked. |
tt_seller | The listed account sells on TikTok Shop. |
profile_detail_status | With includeProfileDetails: ok when the listed account's own page was read (created_at, language, bio_link, business_category, is_organization filled), else why not (not_found, failed). Null when the add-on is off. |
created_at | When the account was created (UTC): on user rows with includeProfileDetails, and on account rows. |
language | The account's language as TikTok records it (user rows with includeProfileDetails; account rows). |
bio_link | The link set in the profile; null when none (user rows with includeProfileDetails; account rows). |
business_category | The category of a business account ("Shopping & Retail"); user rows with includeProfileDetails; account rows. |
is_organization | TikTok marks the account as an organization (user rows with includeProfileDetails; account rows). |
is_live | The account was live when its page was read (user rows with includeProfileDetails; account rows). |
has_story | The account had a story up when its page was read (user rows with includeProfileDetails; account rows). |
read_country | The country the row was read from (US). TikTok serves one list whatever the reader's country. |
run_tag | runTag, copied onto every row. |
status | On account rows: ok, private (counts shown, lists not public), not_found (no such account: the handle is free, or the account was banned or deleted), region_restricted, unavailable (withheld by TikTok), duplicate (the same account as another input), invalid_input (the entry is not a TikTok account), not_read (the run stopped before it) or failed. |
status_detail | Why an account is not ok, in words, with TikTok's own status code. |
following_visibility | On account rows: public, private or friends, as the account's page announces its following list. |
followers_status | On account rows: ok, hidden (TikTok does not show the list), private (a private account), empty, refused (TikTok refused a page on three exits), error, or not_read. |
followers_requested | maxFollowersPerAccount for this run; null = to the end TikTok serves. |
followers_delivered | Follower rows this run delivered for the account (after the filters and the caps). |
followers_positions | List positions walked (30 a page). Rows TikTok dropped from a page count as positions, not as rows. |
followers_coverage | COMPLETE (TikTok said the list ended), SOURCE-LIMIT (TikTok ended the list far short of its own count: at its newest-10,000 window, or after one page of 50 on a few large accounts; followers_oldest_follow_at says where), CAPPED (your cap, maxItems or your maximum charge), NEW-ONLY (stopped at the last run's read time), SINCE (stopped at followedAfter), PARTIAL (a page was refused; the rows before it are delivered). |
followers_oldest_follow_at | The follow time of the last row the walk reached (UTC): on a SOURCE-LIMIT list, where TikTok's window ends. |
followers_note | How the followers list went, in words: positions against TikTok's count, where and why it stopped, rows the filters left out. |
following_status | On account rows: ok, hidden (the account hides whom it follows), private, empty, refused, error, or not_read. |
following_requested | maxFollowingPerAccount for this run; null = the whole list TikTok serves. |
following_delivered | Following rows this run delivered for the account. |
following_positions | List positions walked (30 a page). |
following_coverage | COMPLETE, SOURCE-LIMIT, CAPPED, NEW-ONLY, SINCE or PARTIAL, as for followers_coverage. |
following_oldest_follow_at | The follow time of the last row the walk reached (UTC). |
following_note | How the following list went, in words. |
only_new | The run had onlyNew on (account rows). |
seconds | Seconds the account's lists took to read. |
Example record:
{"row_type": "user","relation": "follower","of_user_id": "6907114026586719238","of_username": "notionhq","input": "notionhq","position": 5,"scraped_at": "2026-10-07T19:47:39Z","user_id": "7657579195245970454","sec_uid": "MS4wLjABAAAA-2250ZO2rmnd4Q8KUIcKEcS7v-SmTrusBjwZyuuYjbmh3V8nXK4rTTpEK0zPzlvP","username": "vista.webdesign","nickname": "VISTA","bio": "Nous transformons vos idées en sites qui convertissent\n🚀 Landing pages & sites web premium & performants\n📩 Collab : vista.smma@gmail.com","bio_emails": ["vista.smma@gmail.com"],"bio_phones": [],"bio_links": [],"profile_url": "https://www.tiktok.com/@vista.webdesign","avatar_url": "https://p19-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/d0f1b50db2469f75fb45aa2c521e2419~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=3aad59aa&x-expires=1791572400&x-signature=HObJWxIyt4MY75ib%2F%2FkLbuFJZIo%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5","avatar_medium_url": "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/d0f1b50db2469f75fb45aa2c521e2419~tplv-tiktokx-cropcenter:720:720.jpeg?dr=9640&refresh_token=00fb8a11&x-expires=1791572400&x-signature=qPxOjbWzhEcQtIKanISrOLd39sY%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5","avatar_thumb_url": "https://p16-common-sign.tiktokcdn-us.com/tos-maliva-avt-0068/d0f1b50db2469f75fb45aa2c521e2419~tplv-tiktokx-cropcenter:100:100.jpeg?dr=9640&refresh_token=904674ff&x-expires=1791572400&x-signature=YHVm51sSX5U1PunZUx7X0xgO83c%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5","verified": false,"private_account": false,"followers": 1,"following": 5,"likes": 2,"videos": 1,"friends": 0,"followers_shown": 1,"following_shown": 5,"likes_shown": 2,"videos_shown": 1,"counts_precision": "exact","followed_after": "2026-10-06T02:50:47Z","followed_before": "2026-10-07T19:47:38Z","follow_window_seconds": 147411,"comment_setting": "everyone","duet_setting": "everyone","stitch_setting": "everyone","download_setting": "everyone","liked_public": false,"tt_seller": false,"profile_detail_status": null,"created_at": null,"language": null,"bio_link": null,"business_category": null,"is_organization": null,"is_live": null,"has_story": null,"read_country": "US","run_tag": "a-c1-c2","status": null,"status_detail": null,"following_visibility": null,"followers_status": null,"followers_requested": null,"followers_delivered": null,"followers_positions": null,"followers_coverage": null,"followers_oldest_follow_at": null,"followers_note": null,"following_status": null,"following_requested": null,"following_delivered": null,"following_positions": null,"following_coverage": null,"following_oldest_follow_at": null,"following_note": null,"only_new": null,"seconds": null}
Pricing
Pay only for the follower and following rows a run delivers, with no start fee and no platform usage billed to you. Prices fall with your Apify plan.
| per 1,000 | Free | Starter | Scale | Business |
|---|---|---|---|---|
Follower or following account (user) | $2.00 | $1.70 | $1.40 | $1.00 |
Profile details on that row (profile_detail) | +$1.00 | +$0.85 | +$0.70 | +$0.50 |
A follower or following row is $2.00 per 1,000 rows on the Free plan and $1.00 on Business: a full list of TikTok's newest 10,000 followers is $20.00 on Free. The + fee is charged only on a row that carries the thing: with includeProfileDetails, a row that carries the listed account's own profile page ($1.00 per 1,000 such rows on the Free plan); a page TikTok did not serve is said on the row and not charged. Free: the account row of every input (its record, its status and each list's verdict), accounts that do not exist, are private or hide a list, rows the filters leave out, a run with onlyNew that finds nothing new (0 rows, $0), and a run that failed before its first row. maxItems and the caps per list are exact; before the first request the log says the most the run can cost at your plan's prices. Enterprise plans have their own rates — the Actor's Pricing tab shows the price for your plan.
Usage patterns
- Audience lists — Give the accounts in
accountswithlists: followersand a cap per account. Rows come newest first withposition, the exact counts of each follower, and the window it followed in. The account row says how far TikTok's window reaches (followers_coverage,followers_oldest_follow_at). Ready-made: Export the newest 1,000 TikTok followers of an account. - Whom an account follows —
lists: followingreads the whole following list (TikTok serves it to its end, except one page of 50 on a few large accounts: the account row says SOURCE-LIMIT). Accounts that hide the list give a free account row withfollowing_status: hidden; the account row'sfollowing_visibilitysays it before any list is read. Ready-made: Check which TikTok accounts hide their following list. - New followers on a schedule — Save a task with
onlyNew: trueand run it hourly or daily: each run delivers only the followers that came since the previous run, nothing when none did. The memory is per account and list, keyed by the user id, so the same account given as a handle, a URL or an id meets its memory; givestateStoreNameto keep two tasks on the same account apart. With a cap per run, the followers the cap left out come in the next run. The first run is the baseline and delivers the whole list up to your cap. Ready-made: Monitor new TikTok followers daily: only the new ones. - Lead lists — Filters run before the bill:
minFollowers/maxFollowers(exact counts),verifiedOnly,withEmailOnly,bioKeywords. A row left out costs nothing and does not count against the caps.includeProfileDetailsadds each listed account's created date, language, bio link and business category from its own page, charged per row. Ready-made: Find TikTok followers by bio keyword: marketers, founders, SEO. - A window in time —
followedAfterstops a list at a date (or a span such as 30 days). TikTok gives a follow-time window per page, not a second per row, so the last page delivered may hold up to 30 rows older than the date; the account row says so (followers_coverage: SINCE). Ready-made: TikTok followers of the last 7 days.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
accounts | array | [] | TikTok accounts, one per line, in any form: a handle (notionhq or @notionhq), a profile URL, a video or photo URL (its author's lists are read), a numeric user id, a secUid, or a share link (vm.tiktok.com/…). Handles are case-insensitive; an account named twice is read once. |
lists | followers / following / both | "followers" | Which list of each account to read: its followers, the accounts it follows, or both. Each row says which (relation). |
maxFollowersPerAccount | integer | 0 | How many of each account's followers to deliver, newest first; 0 = everything TikTok serves (about the newest 10,000, of a few large accounts 50; then the list ends: the account row says SOURCE-LIMIT and the oldest follow time reached). Exact: 2 asked = 2 delivered and charged. |
maxFollowingPerAccount | integer | 0 | How many of the accounts each account follows to deliver, newest first; 0 = the whole list TikTok serves (to its end; one page of 50 on a few large accounts). Accounts that hide their following list give a free row that says so. |
followedAfter | string | Only the rows followed on or after this date: 2026-10-01, or a span back from the run's start such as 3 days (72 hours), 2 weeks, 6 months (UTC). TikTok gives each page a follow-time window, not a second per row, so the last page delivered may hold up to 30 rows older than the date (the account row says so). | |
onlyNew | boolean | false | Deliver only the followers (or following) that appeared since the last run of the same task, newest first, and nothing when none did (0 rows, $0). The first run with this on delivers the whole list as the baseline. The memory is kept per account and list (by the user id) under stateStoreName, or under one default memory of your Apify account. Inside TikTok's window (the newest ≈ 10,000; 50 on a few large accounts) a scheduled run catches every new follower of an account that gains fewer than that between runs. |
stateStoreName | string | The name of the memory onlyNew uses between runs (per account and list, keyed by the user id, so a renamed account or another form of it keeps its memory). Empty = one default memory for your Apify account; give a name to keep two tasks on the same account apart. | |
minFollowers | integer | 0 | Deliver only listed accounts with at least this many followers (exact count); 0 = no filter. Rows left out are not charged and do not count against the caps. |
maxFollowers | integer | 0 | Deliver only listed accounts with at most this many followers; 0 = no filter. |
verifiedOnly | boolean | false | Deliver only listed accounts with TikTok's verified badge. |
withEmailOnly | boolean | false | Deliver only listed accounts whose bio carries an e-mail address (bio_emails). Extraction from the bio text only; no contact finding. |
bioKeywords | array | [] | Deliver only listed accounts whose bio, name or handle contains one of these words (case-insensitive). Empty = no filter. |
includeProfileDetails | boolean | false | Read each delivered account's own profile page too (one request per row) for its created date, language, bio link, business category and organization flag. Charged per row as a profile_detail event, besides the row. TikTok shows no region to a logged-out reader, so none is given. |
maxItems | integer | 0 | Stop after this many charged rows across all accounts and lists; 0 = no limit. Free rows (the account rows, misses) do not count. The run also stops inside your maximum charge and says so. |
runTag | string | A label copied onto every row (run_tag), to tell runs apart in a shared dataset. | |
resumeFromRunId | string | The id of an earlier run of this actor with the same input that stopped before the end: this run reads only the accounts and pages it had not finished, and delivers nothing twice. |
Errors
A run does not fail because of your input. When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends Succeeded, charges nothing, and says what to change:
- the status message starts with
INPUT REJECTED; - the dataset holds one row,
{"error": true, "code": "…", "message": "…"}, and no results; - the key-value store record
ERRORholds the same object.
From code, check error on the first row before reading results.
An account that does not exist, is private or hides a list is not an error: it gets one free account row with the reason, and the run goes on with the others. A run that ends Failed is a fault on our side, never your input; it charges nothing, and we are alerted.
FAQ
How far back does a followers list go?
Logged out, TikTok serves about the newest 10,000 followers of an account and then says the list ended; nothing older can be reached by any cursor (we tried every date back to the account's creation on two accounts). How far back that is depends on the account: a day on an account that gains 10,000 a day, more than a year on a slower one. The account row's followers_oldest_follow_at says where the window ended; followers_coverage says SOURCE-LIMIT. A few large accounts get one page of 50 of each list, whatever cursor, page size or country is asked (gymshark, adidas and bbcnews of 31 brands we tried in October 2026); their account row says SOURCE-LIMIT and "only 50 positions". A following list has no 10,000 window: it is served to its end, except on those accounts.
What are followed_after and followed_before?
TikTok's list cursor is the follow time, to the second, of the last row of each page of 30. So every row's follow time is known to lie at or after the cursor of its own page and at or before the cursor of the page before it (the read time for the newest page). follow_window_seconds is the width of that window. The exact second per row is not delivered.
Why are there fewer rows than positions on some lists?
TikTok pages its lists 30 positions at a time and drops rows it does not serve (deactivated accounts, for one), so a page can carry 18 to 30 rows. Positions count the page slots; rows are what was served. A following list of an old account can return about 93% of its count this way, and the verdict is still COMPLETE when TikTok said the list ended.
What happens with private, missing or hidden accounts?
They cost nothing. A private account gives one account row with status private and its counts; a handle nobody has gives not_found; an account that hides whom it follows gives following_status hidden with TikTok's status code 10222. The other accounts in the run are read as usual.
Does onlyNew detect unfollows?
Not in this version: it delivers the followers that came since the last run. Unfollows need a full re-read of a list and a diff; ask us if you need it.
What is never charged?
The account rows; accounts that do not exist, are private or hide a list; rows the filters leave out; a run with onlyNew that finds nothing new; and a run that failed before its first row.
Can I get a follower's region, e-mail or Instagram?
TikTok does not show a region to a logged-out reader (actors that output one invent it). E-mails, phone numbers and links are extracted from the bio text when the account put them there (bio_emails, bio_phones, bio_links); no contact finding beyond that. Linked Instagram or YouTube ids are not on TikTok's web record.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/tiktok-followers-scraper').call({"accounts": ["notionhq"], "maxFollowersPerAccount": 1000});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/tiktok-followers-scraper').call(run_input={'accounts': ['notionhq'], 'maxFollowersPerAccount': 1000})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/tiktok-followers-scraper --input '{"accounts": ["notionhq"], "maxFollowersPerAccount": 1000}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~tiktok-followers-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"accounts": ["notionhq"], "maxFollowersPerAccount": 1000}'
Support
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.