Build a Twitter Follower Tracker That Actually Catches Unfollows
Build a Twitter Follower Tracker That Actually Catches Unfollows
Your follower count went from 4,102 to 4,098.
Four people left. X won't tell you who. It won't tell you when. And by tomorrow, three new followers will have arrived and the number will read 4,101 again — as if nothing happened.
That gap is why follower trackers exist. Most of them handle it badly.
This is how to build one that works, and the one design decision that determines whether it catches anything at all.
Why the count alone is useless
X gives you followers_count on any profile. It's a single number, updated live, and it hides everything you'd actually want to know.
Consider a day where you gain 12 followers and lose 12. Your count doesn't move. As far as any count-based tracker is concerned, nothing happened — while in reality 24 relationships changed, and the 12 who left might have been the 12 who mattered.
The count tells you the net. Tracking requires the set.
Getting that set out of X is the part that takes work — we expose it as one call if you'd rather start from the diff logic.
That single distinction is what separates a tracker that works from one that reports a flat line while your audience churns underneath it.
The design decision that matters
To know who unfollowed, you need to compare two snapshots of your follower list — yesterday's and today's. Set arithmetic does the rest:
new followers = today − yesterday
unfollowers = yesterday − today
Simple. The part people get wrong is what you store in each snapshot.
The instinct is to store the whole profile — name, bio, avatar, follower count, the lot. It feels thorough. It's also the reason most home-grown trackers get slow and expensive within a month.
You don't need the profile to detect a change. You need the identity. Store IDs; look up profiles only for the handful of accounts that actually changed.
For a 50,000-follower account, that's the difference between storing 50,000 full profiles daily and storing 50,000 integers. And on the fetch side, the lightweight endpoint is cheaper per call than the full one — a saving that compounds every single day you run the job.
Working code
Two steps: pull the current follower set, then diff it against the last run.
Step 1 — fetch the follower list
import requests
BASE = "https://api.socialapi.tech"
KEY = "your_api_key"
def get_followers(username):
"""Return the full set of follower IDs, following pagination to the end."""
ids, cursor = set(), None
while True:
params = {"username": username, "limit": 200}
if cursor:
params["cursor"] = cursor
r = requests.get(
f"{BASE}/v1/user/followers_ids",
params=params,
headers={"X-API-Key": KEY},
timeout=60,
)
r.raise_for_status()
body = r.json()
for row in body["data"]:
ids.add(row["id"])
cursor = body.get("meta", {}).get("next_cursor")
if not cursor:
break
return ids
Note followers_ids rather than followers — it returns {id, username} only, which is all the diff needs.
The pagination detail that bites people: stop when next_cursor is null, not when a page returns fewer rows than you asked for. Short pages happen mid-list and don't mean you've reached the end. Treat a short page as terminal and you'll silently truncate the list — which then shows up as a phantom wave of unfollowers on the next run.
Step 2 — diff against yesterday
import json, pathlib
def track(username):
snapshot = pathlib.Path(f"{username}_followers.json")
current = get_followers(username)
if not snapshot.exists():
# First run — nothing to compare against yet.
snapshot.write_text(json.dumps(sorted(current)))
print(f"Baseline saved: {len(current)} followers")
return
previous = set(json.loads(snapshot.read_text()))
gained = current - previous
lost = previous - current
print(f"+{len(gained)} new, -{len(lost)} unfollowed")
for uid in lost:
print(f" unfollowed: {uid}")
snapshot.write_text(json.dumps(sorted(current)))
That's the whole tracker. Run it daily and you have a complete history of who arrived and who left.
Step 3 — turn IDs back into people
The diff gives you IDs. To show names, look up only the accounts that changed:
def describe(user_ids):
"""Resolve a handful of IDs to profiles. Only call this for the diff."""
r = requests.get(
f"{BASE}/v1/batch/user_info",
params={"ids": ",".join(str(i) for i in user_ids)},
headers={"X-API-Key": KEY},
timeout=60,
)
return r.json()["data"]
If 4 people unfollowed, this is one request for 4 profiles — not 50,000.
Batch lookups like this are exactly what our batch endpoint is for — one call, many IDs.
What a good tracker records
Once the diff works, the interesting part is what you keep:
Timing. Unfollows cluster. If eleven people leave within an hour of a particular post, that's a signal about the post, not about your audience generally.
Who, not how many. Losing a 200-follower account and losing a 200,000-follower account are different events. Store follower counts at the moment of the diff and you can weight them.
Direction changes. Someone who follows, unfollows, then follows again is behaving differently from a one-time departure. Only a set-based tracker can see this at all.
Mutuals. Cross-reference your follower set against your following set and you get mutual-follow status for free — the same two lists, one extra set operation.
How often should it run?
Daily is the right default for most accounts, for a reason that isn't obvious: X's follower list is not perfectly ordered or perfectly consistent moment to moment. Poll it every five minutes and you'll see accounts appear and disappear that never actually followed or unfollowed you. Those are artefacts, and they'll fill your log with false alarms.
A daily snapshot is far enough apart that the list has settled. If you need finer granularity, run hourly but require an account to be missing from two consecutive snapshots before you call it an unfollow. That one rule eliminates nearly all the noise.
For very large accounts, watch your pagination cost: 50,000 followers at 200 per page is 250 requests per run. Daily is fine. Every five minutes is 72,000 requests a day for information that hasn't changed.
Tracking accounts that aren't yours
Everything above works on any public account, not just your own. You're reading a public follower list either way — the code doesn't change, only the username.
This is the more common commercial use: watching who starts following a competitor, spotting when an industry figure follows a new startup, catching the moment a set of accounts converges on someone.
⚠️ One boundary worth stating plainly: this only works on public accounts. Protected accounts don't expose their follower lists, to you or to anyone, and no API can change that. If a tool claims otherwise, it's either wrong or doing something you don't want to be part of.
Questions people ask
Can I see exactly who unfollowed me on Twitter? Not from X directly — it deliberately doesn't surface this. You get it by comparing your own follower snapshots over time, which is what the code above does.
Does X notify someone when I check their followers? No. Reading a public follower list is not a visible action, and generates no notification.
How do I track followers and unfollowers on Twitter automatically? Run the diff script on a schedule — cron, a GitHub Action, a Lambda on a timer. Any of them works; the script is the same.
Can I see who stopped following me if I didn't track before? No. Unfollows are only detectable by comparison, so you need a baseline. Today's snapshot becomes tomorrow's baseline — the sooner you start, the sooner it's useful.
How do I check who someone is following? Same approach with the following endpoint instead of followers. The diff logic is identical.
What's a follower checker for Twitter? Usually a hosted version of the above — it stores snapshots for you and shows the diff in a UI. Building it yourself takes an afternoon and you keep the history.
Can I track follower count over time?
Yes, and it's a by-product: len(current) on every run gives you the time series. The set is what's expensive to reconstruct after the fact — the count you can always recompute from it.
How many followers can I track? Bounded by pagination, not by any hard cap. 200 per page, so a 100,000-follower account is 500 requests per snapshot.
Does this work for finding targeted followers? Yes — pull the follower list of an account whose audience matches your target, and you have a list of people already interested in that topic. Filter by follower count or bio keywords from there.
Why does my tracker show unfollows that didn't happen?
Almost always truncated pagination. If a run ends early, every follower it missed looks like an unfollow. Check that you're following next_cursor to null rather than stopping on a short page.
Can I see who viewed my profile? No. X doesn't expose profile views to anyone, and there's no API for it. Any tool claiming to show you this is fabricating it.
Does unfollowing show up if they follow back later? Yes, if you're storing sets rather than counts — you'll see them leave, then reappear. A count-based tracker shows nothing at all.
How do I find who has the most followers on Twitter?
That's a different question — it needs a ranked list rather than a diff. You'd pull profiles for a candidate set and sort by followers_count.
Is there a free way to do this? The code is free; the data isn't. You need some source of follower lists, and X's own API charges per read. Whichever route you take, budget for the pagination.
How do I check who unfollowed me on X (not Twitter)? Identical — X and Twitter are the same platform and the same data. Nothing about the approach changed with the rename.
Can I track followers for multiple accounts at once? Yes. The script takes a username, so loop over a list. Keep one snapshot file per account and the diffs stay independent.
What if someone gets suspended rather than unfollowing?
They vanish from the list, so a plain diff reports it as an unfollow. If the distinction matters, look up the IDs in your lost set — a suspended account won't resolve to a live profile.
How do I check a Twitter follower count? It comes on the profile. ★One call returns it for any public account★, yours or anyone else's.
Is there a live follower count for Twitter? Poll the profile on an interval. ★"Live" is your polling frequency★ — no endpoint pushes count changes to you.
How do I see follower count history? ★Only if you recorded it.★ The platform stores no history for you — a count is a reading, not a series.
Can I get historical follower counts? Not retroactively. ★This is the asymmetry behind the whole page: capturing forward is trivial, reconstructing backward is impossible.★
How do I graph follower growth? Store a daily reading and plot the series. ★A single number has nothing to compare against.★
What is a follower counter? A profile read on a loop. ★Every one of them works this way★, whatever the interface suggests.
How do I track follower statistics over time? Sample at a fixed interval and store each sample. ★The interval must stay constant★ or the series measures your scheduling.
Can I see who stopped following me? Only by diffing snapshots — ★there is no unfollow notification and no unfollower list★.
Can I search my followers? Retrieve the list and filter locally. ★No server-side search across your followers exists.★
How do I analyse my followers? Pull the list with full profiles, then segment by follower count, bio, or activity — spotting inactive ones.
Does the follower count include inactive accounts? Yes. ★The count is a count★ — it says nothing about how many are real or active.
Why does my follower count fluctuate? Ordinary churn plus periodic platform removals. ★Small daily movement is normal and not worth reacting to.★
What is Twitter follower tracking? Recording the count and list on a schedule. ★The platform stores no history, so tracking is something you do, not something you fetch.★
Is there a follower statistics tool? Any tool storing daily snapshots. ★None can show you history from before you started.★
Can I get follower count history? ★Only what you recorded.★ There is no historical series to request — this is the asymmetry behind the whole page.
Can I see historical follower counts for another account? Same answer — ★if you tracked them, yes; retroactively, no★.
How do I graph follower growth? Store a daily reading and plot the series. ★A single number has nothing to compare against.★
What is a follower counter? A profile read on a loop. ★Every one works this way★, whatever the interface implies.
Do follower counts fluctuate daily? ★Yes, and small movement is normal★ — churn plus periodic platform removals.
How do I measure follower growth rate? Difference between snapshots, divided by days. ★Requires at least two readings.★
Can I get follower demographics? Only what is public on each follower's profile — ★bio, location text, follower count★. Nothing inferred.
How do I sort followers by their follower count? Retrieve the list with full profiles and sort locally. ★No server-side sorting exists.★
How often should I snapshot? ★Daily is plenty, and the interval must stay constant★ — changing it corrupts your own trend line.
If you'd rather skip the plumbing
The tracker logic above is maybe forty lines. The part that takes real time is everything underneath it — pagination that doesn't truncate, retries that distinguish a rate limit from a transient failure, and keeping it all running unattended.
That's what our API handles. One endpoint, a flat price per call, no rate limit of your own to manage. The lightweight followers_ids endpoint costs less per call than the full profile version, which matters when you're paginating through six figures of followers daily.
Two things we don't bill for: requests we reject before they leave us — a malformed parameter, say — and errors on our side. You can check that yourself by sending a deliberately broken request and watching your balance stay put.
Related reading: what to do when X returns a rate limit error · how to remove a follower without blocking them.