TikTok Followers & Following Scraper: TikTok Followers List avatar

TikTok Followers & Following Scraper: TikTok Followers List

Pricing

from $1.00 / 1,000 follower or following accounts

Go to Apify Store
TikTok Followers & Following Scraper: TikTok Followers List

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

Hyperbach

Maintained by Community

Actor stats

0

Bookmarked

13

Total users

4

Monthly active users

3 hours ago

Last modified

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) and followers_shown (as the app shows it), with counts_precision saying which you got, plus user_id and sec_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 its position in 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 onlyNew a 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). includeProfileDetails adds 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):

fieldmeaning
row_typeuser (one follower or following account) or account (one per input: the target's record, its status and each list's verdict; free).
relationOn user rows: follower (follows of_username) or following (of_username follows them).
of_user_idThe account whose list this row comes from (its numeric user id, as a string).
of_usernameThat account's handle.
inputWhat you gave in accounts, verbatim.
positionThe 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_atWhen the row was read (UTC).
user_idTikTok's numeric user id of the listed account, as a string. Stable across renames.
sec_uidTikTok's secUid of the listed account, the id its own APIs take.
usernameThe listed account's handle, without @.
nicknameThe listed account's display name.
bioThe listed account's profile text; empty when it has none, and on a private account (TikTok does not show it).
bio_emailsE-mail addresses found in the bio text (a regex; a @mention is not one). Empty when none.
bio_phonesPhone numbers found in the bio text (8 to 15 digits). Empty when none.
bio_linksURLs and bare domains found in the bio text. Empty when none.
profile_urlhttps://www.tiktok.com/@
avatar_urlThe avatar at 1080 px (an expiring TikTok link).
avatar_medium_urlThe avatar at 720 px.
avatar_thumb_urlThe avatar at 100 px.
verifiedTikTok's verified badge on the listed account.
private_accountThe listed account is private.
followersThe listed account's followers, exact (TikTok's statsV2); on an account row, the target's exact follower count.
followingAccounts followed, exact.
likesLikes received (hearts), exact.
videosThe account's video count.
friendsMutual follows.
followers_shownFollowers as the app rounds them (4,200,000 for 4,242,144).
following_shownFollowing as the app shows it.
likes_shownLikes as the app rounds them.
videos_shownVideos as the app shows them.
counts_precisionexact (TikTok's exact counts) or as_shown (only the rounded ones were served).
followed_afterThe 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_beforeThe follow happened at or before this time (UTC): the previous page's cursor, or the read time on the newest page.
follow_window_secondsfollowed_before minus followed_after: how precisely the follow time is known (about 30 follows wide).
comment_settingeveryone, friends or nobody (the listed account's setting); null on a private account (TikTok does not show it).
duet_settingeveryone, friends or nobody; null on a private account.
stitch_settingeveryone, friends or nobody; null on a private account.
download_settingeveryone, friends or nobody.
liked_publicThe listed account shows the videos it liked.
tt_sellerThe listed account sells on TikTok Shop.
profile_detail_statusWith 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_atWhen the account was created (UTC): on user rows with includeProfileDetails, and on account rows.
languageThe account's language as TikTok records it (user rows with includeProfileDetails; account rows).
bio_linkThe link set in the profile; null when none (user rows with includeProfileDetails; account rows).
business_categoryThe category of a business account ("Shopping & Retail"); user rows with includeProfileDetails; account rows.
is_organizationTikTok marks the account as an organization (user rows with includeProfileDetails; account rows).
is_liveThe account was live when its page was read (user rows with includeProfileDetails; account rows).
has_storyThe account had a story up when its page was read (user rows with includeProfileDetails; account rows).
read_countryThe country the row was read from (US). TikTok serves one list whatever the reader's country.
run_tagrunTag, copied onto every row.
statusOn 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_detailWhy an account is not ok, in words, with TikTok's own status code.
following_visibilityOn account rows: public, private or friends, as the account's page announces its following list.
followers_statusOn 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_requestedmaxFollowersPerAccount for this run; null = to the end TikTok serves.
followers_deliveredFollower rows this run delivered for the account (after the filters and the caps).
followers_positionsList positions walked (30 a page). Rows TikTok dropped from a page count as positions, not as rows.
followers_coverageCOMPLETE (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_atThe follow time of the last row the walk reached (UTC): on a SOURCE-LIMIT list, where TikTok's window ends.
followers_noteHow the followers list went, in words: positions against TikTok's count, where and why it stopped, rows the filters left out.
following_statusOn account rows: ok, hidden (the account hides whom it follows), private, empty, refused, error, or not_read.
following_requestedmaxFollowingPerAccount for this run; null = the whole list TikTok serves.
following_deliveredFollowing rows this run delivered for the account.
following_positionsList positions walked (30 a page).
following_coverageCOMPLETE, SOURCE-LIMIT, CAPPED, NEW-ONLY, SINCE or PARTIAL, as for followers_coverage.
following_oldest_follow_atThe follow time of the last row the walk reached (UTC).
following_noteHow the following list went, in words.
only_newThe run had onlyNew on (account rows).
secondsSeconds 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,000FreeStarterScaleBusiness
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 accounts with lists: followers and a cap per account. Rows come newest first with position, 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: following reads 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 with following_status: hidden; the account row's following_visibility says 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: true and 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; give stateStoreName to 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. includeProfileDetails adds 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 — followedAfter stops 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

fieldtypedefaultwhat it does
accountsarray[]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.
listsfollowers / following / both"followers"Which list of each account to read: its followers, the accounts it follows, or both. Each row says which (relation).
maxFollowersPerAccountinteger0How 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.
maxFollowingPerAccountinteger0How 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.
followedAfterstringOnly 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).
onlyNewbooleanfalseDeliver 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.
stateStoreNamestringThe 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.
minFollowersinteger0Deliver 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.
maxFollowersinteger0Deliver only listed accounts with at most this many followers; 0 = no filter.
verifiedOnlybooleanfalseDeliver only listed accounts with TikTok's verified badge.
withEmailOnlybooleanfalseDeliver only listed accounts whose bio carries an e-mail address (bio_emails). Extraction from the bio text only; no contact finding.
bioKeywordsarray[]Deliver only listed accounts whose bio, name or handle contains one of these words (case-insensitive). Empty = no filter.
includeProfileDetailsbooleanfalseRead 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.
maxItemsinteger0Stop 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.
runTagstringA label copied onto every row (run_tag), to tell runs apart in a shared dataset.
resumeFromRunIdstringThe 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 ERROR holds 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 ApifyClient
client = 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

apify@hyperbach.com

This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.