Twitter (X) Historical Follower Count — API Guide
'How many followers did this account have 6 months ago?' comes up all the time — PR retro-tracking, crypto influence historians, academic longitudinal studies. Frustratingly, neither X's own API nor any third-party lookup service exposes historical follower counts directly. The counts you see today are today's counts.
The good news: reconstructing history is possible with two workable approaches. This guide walks both — your-own-snapshot path (best for future queries you'd like to answer) and Wayback-Machine path (best for retroactive answers to questions you didn't anticipate).
Why X doesn't expose historical follower counts
The X follower count is a live metric — the API reads current-state data from X's user object. There's no follower_count_at(timestamp) endpoint on either X official (/2/users/by/username) or third-party mirrors.
The Basic-tier X API returns the current public_metrics.followers_count field per docs.x.com/x-api/users/lookup/introduction. Same for twitterapi.io's /twitter/user/info endpoint — current-only.
This is intentional on X's side — historical timeseries would require them to store snapshots at scale, which is data storage cost + a data-selling opportunity they've chosen to route through their Enterprise DataStream product (not a general-audience API).
Path 1 — your own snapshot store
For any account you want to track going forward, start snapshotting NOW. Simple daily cron pulls current followers_count via /twitter/user/info and appends to a CSV or database row. After 30 days you have a queryable timeseries.
Cost per snapshot: $0.00018 per twitterapi.io/pricing. Nightly snapshot of 30 accounts = ~$0.005/day = ~$0.16/month. Trivially affordable to snapshot hundreds of accounts.
For accounts you wish you'd started tracking earlier, skip to Path 2.
import os, requests, csv
from pathlib import Path
from datetime import datetime, timezone
HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"
def snapshot(handles: list[str], out_csv: str = "follower_snapshots.csv"):
now = datetime.now(timezone.utc).isoformat()
first_write = not Path(out_csv).exists()
with open(out_csv, "a") as f:
w = csv.writer(f)
if first_write:
w.writerow(["captured_at", "handle", "followers_count", "following_count", "verified"])
for h in handles:
r = requests.get(f"{BASE}/twitter/user/info", headers=HEADERS, params={"userName": h}, timeout=10)
if r.status_code == 404:
w.writerow([now, h, "", "", "NOT_FOUND"]); continue
r.raise_for_status()
u = r.json()
w.writerow([now, h, u.get("followers_count", 0), u.get("following_count", 0), u.get("verified", False)])
print(f" @{h}: {u.get('followers_count', 0):,} followers")
# Nightly cron: python this_script.py
WATCHLIST = ["vitalik", "elonmusk", "jack", "balajis", "naval"]
snapshot(WATCHLIST)
# Cost per twitterapi.io/pricing:
# len(WATCHLIST) × $0.00018 per snapshot
# Nightly × 30 watchlist × 30 days = ~$0.16/monthPath 2 — Wayback Machine reconstruction
The Internet Archive's Wayback Machine (web.archive.org) has crawled twitter.com profile pages millions of times. Historical follower counts can often be recovered by parsing the archived HTML.
Coverage varies wildly by account popularity — celebrities like @elonmusk have hundreds of snapshots per year; typical accounts might have 1-5 snapshots total (or zero).
The Wayback API returns a list of snapshot timestamps for a URL; the CDX API lets you query by date range. Parse the archived HTML with a simple selector on the follower-count element (the twitter.com layout has changed multiple times, so the selector is layout-version-dependent).
Reliability: best for high-profile accounts + rough date ranges. Not suitable for precise daily-granular reconstruction of typical accounts.
# Wayback Machine historical follower reconstruction (best-effort)
import requests, re
from datetime import date
def find_wayback_snapshots(handle: str, year: int) -> list[str]:
url = f"http://web.archive.org/cdx/search/cdx"
params = {
"url": f"twitter.com/{handle}",
"from": f"{year}0101", "to": f"{year}1231",
"limit": 100, "output": "json",
}
r = requests.get(url, params=params, timeout=30)
r.raise_for_status()
rows = r.json()[1:] # first row is header
return [f"http://web.archive.org/web/{row[1]}/https://twitter.com/{handle}" for row in rows]
def parse_follower_count(archive_url: str) -> int | None:
r = requests.get(archive_url, timeout=30)
if r.status_code != 200: return None
# Old-layout selector — for other layout versions, adjust the regex
# Format varies: '1,234 Followers' or 'Followers: 1234' etc.
m = re.search(r'(\d[\d,]*)\s*Followers', r.text)
if not m: return None
return int(m.group(1).replace(",", ""))
# Example: reconstruct @vitalik follower trajectory across 2020
snaps = find_wayback_snapshots("vitalik", 2020)
print(f"found {len(snaps)} 2020 archive snapshots for @vitalik")
for url in snaps[:5]:
count = parse_follower_count(url)
if count:
print(f" {url[-40:]}: {count:,} followers")
# Free but rate-limited (Wayback Machine soft-throttles heavy scrapers)Alternative — X official historical (Enterprise only)
X's Enterprise tier includes historical user metrics via DataStream + Historical Search products — but only on custom contracts starting around $42,000/month per docs.x.com/x-api/enterprise/getting-started.
Not a practical alternative for most workflows. Included only for completeness — if your organization is already on Enterprise for other reasons, ask your X account manager whether historical user snapshots are in your contract scope.
Comparison — 3 historical-follower paths
Practical rule: start Path 1 snapshotting today for any account you might want to query later; use Path 2 for retro queries; forget Path 3 unless you have Enterprise budget.
Common analytics workflows on historical follower data
Influence velocity: follower growth rate over time — spot which content drove step-changes.
Cohort comparison: line-chart 10 accounts in the same niche + rank by growth rate.
Event-driven analysis: did the account gain/lose followers around a specific launch, controversy, or campaign?
Bot-cull detection: sudden follower drops around X's periodic spam sweeps are visible in the timeseries.
Crypto influence historian: reconstruct which crypto influencer had which reach at which market moment — quant strategy feature engineering.
PR retrospective: 6 months after a launch, ask 'did our announcement move follower needle for accounts that engaged'.
# Complete workflow: snapshot 10 accounts nightly + weekly diff report.
import os, requests, csv, json
from pathlib import Path
from datetime import datetime, timezone, timedelta
from collections import defaultdict
HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"
CSV = Path("follower_history.csv")
def snapshot_all(handles: list[str]):
now = datetime.now(timezone.utc).isoformat()
first = not CSV.exists()
with open(CSV, "a") as f:
w = csv.writer(f)
if first: w.writerow(["captured_at", "handle", "followers_count"])
for h in handles:
r = requests.get(f"{BASE}/twitter/user/info", headers=HEADERS, params={"userName": h}, timeout=10)
if r.status_code == 404:
w.writerow([now, h, ""]); continue
r.raise_for_status()
u = r.json()
w.writerow([now, h, u.get("followers_count", 0)])
def weekly_diff():
# Read CSV, compute delta between latest snapshot and snapshot ~7 days ago per handle
rows = list(csv.DictReader(open(CSV))) if CSV.exists() else []
by_handle = defaultdict(list)
for r in rows:
by_handle[r["handle"]].append((r["captured_at"], int(r["followers_count"] or 0)))
print("weekly follower deltas:")
for handle, snaps in by_handle.items():
snaps.sort()
if len(snaps) < 2: continue
latest = snaps[-1]
week_ago_target = datetime.fromisoformat(latest[0]) - timedelta(days=7)
prior = min(snaps, key=lambda s: abs(datetime.fromisoformat(s[0]) - week_ago_target))
delta = latest[1] - prior[1]
pct = 100 * delta / max(prior[1], 1)
print(f" @{handle}: {prior[1]:,} → {latest[1]:,} ({delta:+,} {pct:+.2f}%)")
WATCHLIST = ["vitalik", "elonmusk", "jack", "balajis", "naval", "cz_binance", "saylor", "paulg", "garrytan", "pmarca"]
snapshot_all(WATCHLIST) # nightly cron
# weekly_diff() # weekly cron
# Cost per twitterapi.io/pricing:
# 10 accounts × $0.00018 = $0.0018/night = $0.054/month totalQuestions readers ask
Can I get the follower count as of a specific past date directly?
No — neither X official nor twitterapi.io expose historical timestamps for follower counts. Only current-state. This is why the snapshot-forward-in-time pattern is the standard workflow.
How reliable is Wayback Machine for follower counts?
Depends heavily on account popularity. @elonmusk / @vitalik have hundreds of snapshots per year. Typical accounts might have 0-5 total across all years. Coverage is not queryable-guaranteed.
What's the granularity limit of snapshot storage?
Practical minimum is 1 snapshot per day per account. Sub-daily (hourly) works but adds cost + rarely provides meaningful signal for follower counts (which don't change minute-by-minute for typical accounts).
Do I need to snapshot when a follower change spike happens?
Daily cron catches step-changes at day-granularity. For minute-granular event capture (viral moment, spam wave), pair snapshotting with a real-time trigger — e.g. sudden mention-count spike triggers an immediate follower snapshot outside the cron cycle.
Can I reconstruct historical following-count too (same pattern)?
Yes — same /twitter/user/info endpoint returns following_count alongside followers_count. Snapshot both in the same call, no additional cost.
Does X's 'Sensitive Media' / 'suspended' state affect historical snapshots?
Live-query on a suspended account returns 404. If the account had been snapshotted before suspension, your historical records still work. Post-suspension follower count changes obviously can't be captured.
Any ToS concern with periodic snapshotting?
twitterapi.io + X official API are both explicitly designed for polling public metrics. No ToS issue for reasonable-volume periodic snapshots (daily-ish). Only concern would be aggressive minute-level polling of thousands of accounts — that's what streaming/webhooks endpoints are for.
Continue
- twitterapi.io — pricing
- X API — pricing (docs.x.com)
- X — user lookup introduction
- X — Enterprise API tier (DataStream historical)
- Twitter (X) API — cluster hub
- Twitter (X) follower count API (live)
- Twitter (X) follower tracking API guide
- Twitter (X) historical data + archive API
- Twitter (X) username lookup API reference
- twitterapi.io pricing
Stop reading. Start building.
Starter credits cover real testing on real data. Google sign-in, no card, no application queue.
Get an API key