Export Twitter (X) Following List — API Tutorial
Exporting a Twitter (X) account's full following list is one of the classic API workflows — analytics workflows, backup for account owners, competitive-intel / audience analysis, following-graph research. This tutorial walks the exact call + pagination pattern + honest cost per provider.
Pricing references URL-cited to each provider.
Two API paths — same shape, different pricing
twitterapi.io /twitter/user/followings — cursor-paginated. Returns the accounts the target user follows. Per twitterapi.io/pricing: $0.00001-$0.00003 per follower entry (tiered by page-size — larger pages cheaper per entry).
X official /2/users/{id}/following — same data, cursor-paginated. Per docs.x.com/x-api/getting-started/pricing: $0.005 per user in the returned page.
Cost ratio at typical page-sizes: 150-500× cheaper on twitterapi.io for the same data. Choice depends mostly on whether you're already authenticated to X's Developer Console.
Runnable — twitterapi.io export to JSONL
Auth via X-API-Key header. Cursor loops until exhausted.
import os, requests, json
from pathlib import Path
HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"
def export_following(handle: str, out_path: str = None):
if out_path is None: out_path = f"{handle}_following.jsonl"
Path(out_path).parent.mkdir(exist_ok=True, parents=True) if Path(out_path).parent != Path('.') else None
following, cursor = 0, None
with open(out_path, "w") as f:
for _ in range(200): # safety cap; 200 pages × 5000 = 1M following
params = {"userName": handle, "count": 5000}
if cursor: params["cursor"] = cursor
r = requests.get(f"{BASE}/twitter/user/followings", headers=HEADERS, params=params, timeout=30)
r.raise_for_status()
resp = r.json()
for user in resp.get("data", []):
f.write(json.dumps(user) + "\n")
following += 1
cursor = resp.get("next_cursor")
if not cursor: break
return following
n = export_following("nasa")
print(f"exported {n} following to nasa_following.jsonl")
# Cost: at ~$0.00002 per entry mid-tier ~= n × $0.00002Convert to CSV for spreadsheet analysis
JSONL is great for storage; CSV is what most analysts open. Simple conversion:
import json, csv
def jsonl_to_csv(jsonl_path: str, csv_path: str):
with open(jsonl_path) as jf, open(csv_path, "w") as cf:
writer = csv.DictWriter(cf, fieldnames=["userName", "name", "followers_count", "following_count", "verified", "description"])
writer.writeheader()
for line in jf:
u = json.loads(line)
writer.writerow({
"userName": u.get("userName", ""),
"name": u.get("name", ""),
"followers_count": u.get("followers_count", 0),
"following_count": u.get("following_count", 0),
"verified": u.get("verified", False),
"description": (u.get("description", "") or "").replace("\n", " ")[:200],
})
jsonl_to_csv("nasa_following.jsonl", "nasa_following.csv")Side-by-side — 2 API paths
Per-entry cost derived from published pricing pages. Page-size affects twitterapi.io pricing tier.
Two practical observations: (a) larger page size (5000) on twitterapi.io reduces per-entry cost tier — use 5000 unless you have a specific reason not to; (b) at any meaningful volume the cost delta is single-digit-cent vs single-digit-dollar; 150-500× compounds.
Common export workflows
Account backup (owners): periodic backup of your own following list. Useful before major cleanup or account changes.
Growth tracking: snapshot following list over time — new-follows and unfollows over days/weeks visible as diffs.
Competitive intel: export a competitor's following list to see who they engage with — signals partnerships, hiring targets, industry connections.
Network analysis: export multiple accounts' following lists → construct a follow-graph → cluster analysis / influence-map.
Audience-list discovery: export a high-signal account in your niche → their following list is a curated audience of similar accounts worth engaging.
What the response includes
Each entry in the response is a user object with:
userName: @handle for the followed account.
name: display name.
followers_count: their follower count (useful for filtering by size).
following_count: how many they follow (proxy for account behavior — high-follow accounts differ from low-follow).
verified: verification flag.
description: bio text (often useful for topic-clustering).
created_at: account age (useful to filter out new / bot accounts).
profile_image_url: avatar URL.
# Practical example: bulk export following lists for multi-account competitive analysis.
import os, requests, json, csv
from pathlib import Path
from collections import Counter
HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"
OUT_DIR = Path("following_exports")
OUT_DIR.mkdir(exist_ok=True)
def export_one(handle: str):
following, cursor = [], None
for _ in range(200):
params = {"userName": handle, "count": 5000}
if cursor: params["cursor"] = cursor
r = requests.get(f"{BASE}/twitter/user/followings", headers=HEADERS, params=params, timeout=30)
r.raise_for_status()
resp = r.json()
following.extend(resp.get("data", []))
cursor = resp.get("next_cursor")
if not cursor: break
return following
COMPETITORS = ["competitor_a", "competitor_b", "competitor_c"]
following_map = {}
for h in COMPETITORS:
following_map[h] = export_one(h)
with open(OUT_DIR / f"{h}.jsonl", "w") as f:
for u in following_map[h]:
f.write(json.dumps(u) + "\n")
print(f" {h}: exported {len(following_map[h])} following")
# Cross-reference: accounts followed by 2+ competitors = high-signal targets
all_followed = Counter()
for h, following in following_map.items():
for u in following:
all_followed[u.get("userName", "")] += 1
common = [(h, c) for h, c in all_followed.items() if c >= 2]
print(f"\nAccounts followed by 2+ competitors: {len(common)}")
# Cost per twitterapi.io/pricing:
# 3 accounts × ~2000 following avg × ~$0.00002 = ~$0.12 total
# X official equivalent: ~$30 (150x delta)Questions readers ask
Can I export another account's following list without following them?
Yes — public account following lists are visible via the API regardless of your follow relationship. Only fully-private accounts gate this data.
Rate limits during large export?
twitterapi.io per-key throughput accommodates thousands of requests/hour. For very large exports (accounts following 10K+ accounts), pace across hours rather than bursting. Batch of 5000 per page keeps request count low.
What if the account has recently unfollowed people?
The endpoint returns the current state. Real-time — unfollows since last export won't appear. For diff analysis (who unfollowed / new-follows), snapshot periodically + compare.
Can I get order of following (who they followed first)?
Cursor pagination returns in reverse-chronological (most recent follow first). Persistent across pagination but not documented as a stable ordering guarantee — treat as approximate.
Does exporting following count toward my quota?
Each returned entry counts. 1000 following = 1000 entries billed at the per-entry rate. Larger page sizes (5000) put you in the cheaper tier.
Can I export the reverse — accounts that follow this account?
Yes — that's /twitter/user/followers (same pattern, reversed direction). See /blog/twitter-follower-tracking-api-guide for that workflow.
Continue
- Twitter (X) API — cluster hub
- Twitter (X) follower tracking API guide
- Twitter (X) follower count API tutorial
- Twitter (X) data collection API developer guide
- 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