Social Media Follower Count Tracker - 8 Networks, Change Alerts avatar

Social Media Follower Count Tracker - 8 Networks, Change Alerts

Pricing

from $3.65 / 1,000 account row returneds

Go to Apify Store
Social Media Follower Count Tracker - 8 Networks, Change Alerts

Social Media Follower Count Tracker - 8 Networks, Change Alerts

For growth teams and agencies: follower, subscriber and member counts for TikTok, YouTube, Twitch, Telegram, Bluesky, Snapchat, GitHub and Discord in one table, with an isRounded column on every row. Five of the eight publish an exact figure. Monitoring returns an account only when its count moves.

Pricing

from $3.65 / 1,000 account row returneds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

For growth teams and agencies: one row per account with followerCount, followerLabel, isRounded, roundingPrecision, followingCount, postCount, displayName, profileUrl and the account id the network itself reports, across TikTok, YouTube, Twitch, Telegram, Bluesky, Snapchat, GitHub and Discord. Measured on 2026-09-23: TikTok @nasa 1,568,256 followers, Twitch shroud 11,293,227 followers, Bluesky bsky.app 35,003,658 followers, GitHub torvalds 324,766 followers, Discord python 431,725 members. Put your whole watchlist in one list, get one table back, and in monitoring mode get a row only for the accounts whose count actually moved.

Export as JSON, CSV or Excel.

Unofficial. Public data only. Not affiliated with, endorsed by or connected to TikTok, YouTube, Twitch, Telegram, Bluesky, Snapchat, GitHub or Discord.

The eight networks, and how exact each number is

Every row carries isRounded and roundingPrecision, because three of the eight networks do not publish an exact figure and no scraper can make them. Hiding that is how a "tracker" reports "no change" for weeks while an account grows.

NetworkThe count is calledMeasured 2026-09-23isRoundedroundingPrecisionWhere it comes from
TikTokfollowers1,568,256 (@nasa)false1the exact figure on the profile page
YouTubesubscribers21,300,000 (@mkbhd)true100000"21.3M subscribers" - three significant figures
Twitchfollowers11,293,227 (shroud)false1the channel page's own structured data
Telegramsubscribers10,671,626 (durov)false1the full digits on the profile page
Blueskyfollowers35,003,658 (bsky.app)false1the public API
Snapchatsubscribers4,060,100 (fcbarcelona)true100rounded to the nearest hundred
GitHubfollowers324,766 (torvalds)false1the official public REST API
Discordmembers431,725 (python)truenullDiscord's own approximate_member_count

Details behind the three rounded ones:

  • YouTube publishes only a rounded subscriber count. Below 1,000 it is exact ("726 subscribers"); above that it is three significant figures. roundingPrecision says how coarse: 21.3M rounds to the nearest 100,000, 6.58M to the nearest 10,000.
  • Snapchat rounds to the nearest hundred. In a 28-account sample on 2026-09-14, all 17 accounts that showed a count were multiples of 100. A subscriberCount of "0" on Snapchat means "not shown", not "zero subscribers", so those accounts come back as a free no-public-count row instead of a zero.
  • Discord names the field approximate_member_count itself, and the answer carries Cache-Control: public, max-age=300, so a server's count can be up to five minutes old.

On Twitch the number comes from the ProfilePage block of the channel page's JSON-LD, the same data Twitch publishes for search engines. All five channels measured on 2026-09-23 carried it, including channels that were not live at the time. Channels that do not exist answer 200 with a shell page that has no such block, and are reported as no-such-account rather than as zero followers.

On TikTok the page publishes an exact figure and a rounded one. The exact one is used for followerCount; the rounded one is kept in followerCountText so you can see both. On 14 accounts measured on 2026-09-06 the two differed on 11, by up to 41,519 followers.

What is not here, and why

  • Instagram, Facebook, LinkedIn and Threads are not included. Instagram's profile API answered 429 on every attempt from a datacenter address on 2026-09-23, which means the number is only reachable by routing around a rate limit through residential addresses - this Actor does not do that. Threads' public profile page returned 200 but contained no follower count at all. If those four networks are what you need, this Actor is the wrong one; say so before you run it rather than after.
  • Twitch is read only from the channel page. Twitch's private GraphQL endpoint gql.twitch.tv has a robots.txt two lines long that reads User-agent: * / Disallow: /, so this Actor never touches it, and the official Helix API needs OAuth. The channel page www.twitch.tv/<login> is allowed by robots.txt and carries the follower count in its structured data, so that is the only Twitch address requested. Reserved paths that are not channels (stream, search, login, videos, directory ...) are rejected before any request is made.
  • Blocks, challenge pages and rate limits are never worked around. A challenge page is not solved and the same address is not swapped for another one; the account comes back as a free row saying what happened. An Apify proxy is used for exactly one case: a request that did not reach the network at all (a connection failure).
  • No login, no tokens, no cookies. The only headers sent are a browser User-Agent, an Accept, Accept-Encoding: identity and Accept-Language.

Input

accounts takes one mixed list for all eight networks. Paste a profile URL, or write network:handle:

{
"accounts": [
"tiktok:@nasa",
"https://www.youtube.com/@mkbhd",
"https://www.twitch.tv/shroud",
"telegram:durov",
"https://bsky.app/profile/bsky.app",
"snapchat:fcbarcelona",
"https://github.com/torvalds",
"discord:python"
]
}

A bare handle with no network (nasa) is rejected with a free row, because the same name exists on several networks and guessing would return an account you did not ask for. If you would rather use bare handles, put them in the per-network list instead: tiktokAccounts, youtubeChannels, twitchChannels, telegramChannels, blueskyAccounts, snapchatAccounts, githubAccounts, discordInvites. The two styles can be mixed in one run.

Other settings: maxAccounts (cap on charged rows when monitoring is off), monitoringMode, monitorOn, resetMonitoringState, useProxy.

What each network accepts:

  • TikTok - @nasa, nasa, https://www.tiktok.com/@nasa. Tag, music, search and embed URLs are rejected with a free row: robots.txt does not allow them.
  • YouTube - @MrBeast, a channel id UCX6OQ3DkcsbYNE6H8uQQuVA, or a channel URL. Old /user/ and /c/ URLs are rejected with a free row, because resolving them needs a redirect this Actor does not follow.
  • Twitch - shroud, @shroud, https://www.twitch.tv/shroud. Paths that are reserved by Twitch rather than channel names (stream, search, login, videos, directory ...) are rejected with a free row, because robots.txt disallows them.
  • Telegram - durov, @durov, https://t.me/durov. Private invite links (t.me/+..., t.me/joinchat/...) are rejected: they publish no count. If you paste a /s/ preview link the profile page is read instead, because the preview page rounds to three significant figures and the profile page does not.
  • Bluesky - bsky.app, a DID, or a profile URL.
  • Snapchat - fcbarcelona, @fcbarcelona, https://www.snapchat.com/add/nfl. Handles are lower-cased first, because Snapchat redirects uppercase ones.
  • GitHub - torvalds or https://github.com/torvalds. Repository URLs are rejected. Organizations work and come back with accountType: "Organization".
  • Discord - a server named by an invite: python, discord.gg/python, https://discord.com/invite/python. Invite codes are case sensitive and are sent exactly as typed. discord.com/channels/... URLs are not invites and are rejected.

Output

One row per account, the same columns on all eight networks:

{
"network": "github",
"status": "ok",
"scrapedAt": "2026-09-23T06:00:00.000Z",
"inputAccount": "github:torvalds",
"accountId": "1024025",
"handle": "torvalds",
"profileUrl": "https://github.com/torvalds",
"displayName": "Linus Torvalds",
"description": null,
"followerCount": 324766,
"followerLabel": "followers",
"followerCountText": null,
"isRounded": false,
"roundingPrecision": 1,
"followingCount": 0,
"postCount": 12,
"likeCount": null,
"totalViews": null,
"onlineCount": null,
"accountType": "User",
"country": null,
"countNoun": null,
"isVerified": null,
"isPrivate": null,
"accountCreatedAt": "2011-09-03T15:26:22.000Z",
"handleMatchesInput": null,
"change": null,
"isFirstCheck": null,
"previousCheckedAt": null,
"previousFollowerCount": null,
"followerCountChange": null,
"previousFollowingCount": null,
"previousPostCount": null
}

accountId is the identifier the network itself reports - TikTok's numeric user id, YouTube's UC... channel id, Bluesky's DID, GitHub's numeric id, Discord's server id, and the account's own handle where the network publishes no id (Telegram). Two different handles that lead to the same account are returned once and charged once, matched on that id. Monitoring is remembered per network + accountId. On TikTok, YouTube, Bluesky, Snapchat, GitHub and Discord that id is a number or a DID the network assigns, so renaming an account does not restart its history. On Telegram and Twitch the account id is the handle itself - neither network publishes a stable numeric id on the page this Actor is allowed to read - so if one of those accounts is renamed it is treated as a new account and comes back once as first-check.

handleMatchesInput is the mis-attribution check. On YouTube it is true only when the About panel names the same channel id as the page's own canonical link - a page carries several other channels' subscriber counts in its recommendation rail, and reading the first one found returns a different channel's number. If they disagree the row is not returned at all.

Columns that a network does not publish are null, never 0.

Free rows (never charged)

statusWhat it means
no-such-accountthe network returned no public account for that handle. A handle that never existed, one that was renamed and one that was removed all give the same answer, so the row does not claim which
no-public-countthe account exists but the network publishes no count for it. A count of zero is not assumed
blockeda block, a challenge page or an empty response. Not retried from another address, and the account is not reported as gone
rate-limitedthe network asked this run to slow down. Not worked around
unreadablethe response could not be read, or was a redirect this Actor does not follow. Nothing is guessed
invalid-inputnot a handle or profile URL this Actor can use, so nothing was requested
duplicate-accounta second entry pointing at an account already returned in this run
no-changemonitoring mode, and nothing in the list moved
not-checkedmaxAccounts or the 1,000-per-run cap stopped before the end of the list
budget-reachedthe run's maximum total charge stopped it early, with the count of what was left

Pricing

  • profile-returned - $5.00 per 1,000 rows, charged only for rows with status: "ok". Every free row above costs nothing.
  • profile-checked - $0.30 per 1,000 checks, charged in monitoring mode for each account actually read, changed or not. There is no start fee.

Outside monitoring mode only profile-returned applies, so 200 accounts in one run is $1.00.

In monitoring mode, every account checked costs the check fee, changed or not - that is what pays for the polling - and only the accounts that moved also cost a row. 50 accounts every hour = 36,000 checks a month = $10.80, plus $5.00 per 1,000 change rows. On the same schedule an Actor that charges a full row every time would bill 36,000 rows = $180.00.

The Actor reads only as many accounts as the run's maximum total charge can pay for with a check and a row each, so a low limit never spends the whole budget on check fees and returns nothing.

Monitoring mode

Turn monitoringMode on and run on a schedule. The first run returns every account once to set the baseline (change: "first-check"). After that an account comes back only when its watched count changed, with previousFollowerCount, previousCheckedAt and followerCountChange filled in and change set to followers-up or followers-down.

monitorOn decides what counts as a change. follower-count (the default) watches the follower count only. any-count also returns an account when its following count or post count changed, which returns far more rows.

Two honest limits:

  • On the three networks that publish a rounded count, a small move is invisible. A YouTube channel at 21.3M has to gain about 50,000 subscribers before the published number changes. TikTok, Twitch, Telegram, Bluesky and GitHub do not have this problem. This is a property of what those networks publish, not of this Actor.
  • Counts are remembered per account, not per list. Do not put the same account in two schedules that can run at the same time; Apify's key-value store has no atomic update, so two runs finishing within milliseconds of each other can overwrite one another's records. The Actor re-reads and merges before writing, and warns in the log if it could not confirm its own records afterwards, but it cannot make this impossible.

resetMonitoringState clears every remembered count. Turn it off again after that one run - while it is on, every run starts from scratch and charges a full row for every account instead of only the ones that changed.

Limits

  • 1,000 accounts per run. Beyond that a free not-checked row says how many were left.
  • Requests to the same network are spaced out; requests to different networks are not, because they are different servers.
  • GitHub allows 60 unauthenticated requests per hour from one address. This Actor does not work around that: when GitHub says the allowance is used up, the remaining GitHub accounts come back as free rate-limited rows naming the time it resets, and the other seven networks carry on normally.
  • If a network rate-limits this run, no further accounts on that network are requested in that run.