WEIR

How to Export Twitter Followers to CSV with Python (2026)

Export Twitter followers to CSV with Python: the official X API at $0.010 per follower, or a REST endpoint with cursor paging, with real cost math for both.

By Tarun Khatri · · 7 min read

To export Twitter followers to CSV in 2026, page through a followers endpoint and write each account as a row. X's official API charges $0.010 per follower record and returns up to 1,000 per request. Hosted APIs such as Weir return about 70 per page and cost far less per record. This tutorial shows both in Python, explains which fields you get, and works out what 1,000 to 1 million followers cost on each, including the provider that is cheaper than ours.

Disclosure: Weir is our product. The official route is covered with its real prices, and so is a cheaper third-party option.

Before you export: public data, used responsibly

Only public accounts can be exported. A protected account's followers are visible only to the people it has approved. X's API won't return them, and neither will Weir, which returns a 404 for protected accounts.

A follower list is a list of people, so treat the CSV as personal data:

  • Follow X's terms. The official API comes with X's developer terms. Third-party APIs read public data without being X, and X's Terms of Service restrict scraping. What you do with the data is your responsibility.
  • Have a reason, and keep the minimum. Audience research or finding your own community is reasonable. Building contact lists for unsolicited messages or tracking individuals is not.
  • Check the privacy law that applies to you and to the people in the file, especially if you store the data or combine it with other sources. This isn't legal advice.

Key numbers (as of October 2026)

Route Accounts per request Price per follower record
Official X API Up to 1,000 $0.010 ($0.001 for your own followers)
TwitterAPI.io Up to 200 From $0.00001 (1 credit) at 200 per page
SocialData Not compared $0.0002 ($0.20 per 1,000 results)
Weir (ours) About 70 1 credit, plus 1 credit per request

A Weir credit costs $0.10 to $0.20 per 1,000 depending on the pack. There are also 5,000 free credits every month.

Option 1: the official X API

X's followers endpoint is GET /2/users/{id}/followers. It takes max_results up to 1,000 and a pagination_token, accepts an app-only bearer token, and is limited to 300 requests per 15 minutes per app (rate limits). On the pay-per-usage rate card, "Following/Followers: Read" costs $0.010 per resource, and a User read (the lookup that turns a username into an id) is another $0.010. Resources are deduplicated within a UTC day.

There is one big exception. Under Owned Reads, your app reading your own account's followers costs $0.001 per resource, a tenth of the normal price. If you're exporting your own audience, the official API is cheap and is the route to use.

With Tweepy:

import csv
import os
import tweepy

client = tweepy.Client(bearer_token=os.environ["X_BEARER_TOKEN"])
user = client.get_user(username="XDevelopers").data

FIELDS = ["id", "username", "name", "created_at", "followers_count", "following_count", "description"]

with open("followers.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerow(FIELDS)
    for follower in tweepy.Paginator(
        client.get_users_followers,
        user.id,
        max_results=1000,
        user_fields=["created_at", "description", "public_metrics"],
    ).flatten(limit=5000):  # a ceiling, so a big account can't run up the bill
        metrics = follower.public_metrics or {}
        writer.writerow([
            follower.id, follower.username, follower.name, follower.created_at,
            metrics.get("followers_count"), metrics.get("following_count"), follower.description,
        ])

Exporting 5,000 followers of someone else's account this way costs about $50.

Export Twitter followers to CSV with Weir

Weir's endpoint is GET /v1/x/users/{user}/followers. {user} is a username (with or without the @) or a numeric id, so you don't need a separate lookup. It returns followers most recent first, as X lists them. There's no limit parameter: X chooses the page size, about 70 accounts. You page with meta.nextCursor, which is null after the last page (reference).

Step 1: set up

Sign up (no card needed), create a key under API keys, then:

pip install requests
export WEIR_API_KEY="weir_live_..."

Step 2: look at one page

import os
import requests

API = "https://api.weirapp.io"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['WEIR_API_KEY']}"

r = session.get(f"{API}/v1/x/users/XDevelopers/followers", timeout=60)
r.raise_for_status()
page = r.json()
print(len(page["data"]), "accounts;", "credits charged:", r.headers["x-credits-charged"])

Each account has these fields, according to the API's schema. The example below is the illustrative one from the API reference, not a real person:

{
  "id": "1593274519387648000",
  "username": "example_dev",
  "name": "Example Developer",
  "description": "Building developer tools. Posts about APIs and data.",
  "url": "https://x.com/example_dev",
  "profileImageUrl": "https://pbs.twimg.com/profile_images/1593274519387648000/avatar_normal.jpg",
  "profileBannerUrl": "https://pbs.twimg.com/profile_banners/1593274519387648000/1700000000",
  "location": "Lisbon",
  "verified": true,
  "followersCount": 12840,
  "followingCount": 311,
  "statusesCount": 4210,
  "likeCount": 9876,
  "createdAt": "2022-11-17T15:04:05.000Z",
  "pinnedPostIds": ["1878432157392445440"],
  "protected": false
}

description and location can be null. id is a string, so keep it as one.

Step 3: page through everything and write the CSV

import csv
import time

FIELDS = [
    "id", "username", "name", "description", "location", "verified",
    "followersCount", "followingCount", "statusesCount", "createdAt", "url",
]


def export_followers(user: str, path: str, max_pages: int = 50) -> int:
    cursor, pages, seen = None, 0, set()

    with open(path, "w", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=FIELDS, extrasaction="ignore")
        writer.writeheader()

        while pages < max_pages:
            params = {"cursor": cursor} if cursor else {}
            r = session.get(f"{API}/v1/x/users/{user}/followers", params=params, timeout=60)

            if r.status_code == 429:  # too fast: wait as told, then retry the same page
                time.sleep(int(r.headers.get("Retry-After", "10")))
                continue
            if r.status_code == 402:  # out of credits: retrying won't help
                raise SystemExit("Out of credits; add some under Billing and run again.")
            r.raise_for_status()  # 404: the account doesn't exist or is protected

            page = r.json()
            for account in page["data"]:
                if account["id"] not in seen:  # cheap guard against overlap between pages
                    seen.add(account["id"])
                    writer.writerow(account)
            file.flush()  # keep what you have if the run stops halfway
            pages += 1

            cursor = page["meta"]["nextCursor"]
            if not cursor:
                break

    return len(seen)


count = export_followers("XDevelopers", "followers.csv", max_pages=15)
print(f"wrote {count} followers")

What this loop does:

  • max_pages caps the cost. Fifteen pages is roughly 1,050 accounts. Raise it once you've seen the first file.
  • It sends the cursor back unchanged, on the same path. A cursor from a different request is rejected with a 400 (pagination).
  • It treats 429 and 402 differently. A 429 clears after Retry-After. A 402 means the account is out of credits, and only a top-up fixes it.
  • It flushes after every page, so an interrupted run still leaves a usable CSV.

If you open the file in Excel, long ids will be shown in scientific notation. That's only how Excel displays them; the CSV keeps every digit. Import the id column as text if you need to see it.

How fast it runs

The followers endpoint counts as 3 requests against your per-minute limit. On the free tier (30 a minute) that's 10 pages, about 700 accounts, a minute, so 10,000 followers take around 15 minutes. After any purchase, Tier 1 allows 120 a minute, or about 2,800 accounts a minute (billing). The official API is faster for big exports: 300 requests of 1,000 accounts each per 15 minutes.

We haven't tested a complete walk of an account with millions of followers. For very large accounts, run a few pages first and check the results before committing to a full export.

What it costs

Weir charges 1 credit per account returned (the x.user_result rate in our billing table) plus a 1-credit minimum per successful call. The first page also bills one 2-credit profile lookup to resolve the username, but later pages don't. A full page of about 70 is therefore about 71 credits, and N followers cost about N + N/70 + 2 credits.

Followers Weir credits Weir, $5 pack ($0.20/1K) Weir, $1,000 pack ($0.10/1K) Official X API TwitterAPI.io (200/page) SocialData
1,000 1,017 Free (in monthly grant) Free $10 $0.01 $0.20
10,000 10,145 $2.03 $1.01 $100 $0.10 $2.00
100,000 101,431 $20.29 $10.14 $1,000 $1.00 $20.00
1,000,000 1,014,288 $202.86 $101.43 $10,000 $10.00 $200.00

How the other columns are worked out: the official API is $0.010 × N, before the extra $0.010 user lookup. TwitterAPI.io charges 1 credit per follower when a page returns 200, and its minimum of 15 credits is $0.00015, so a credit is $0.00001. SocialData is $0.20 per 1,000 results. The 5,000 free Weir credits a month cover about 4,900 followers.

For bulk follower exports, TwitterAPI.io is the cheapest by a wide margin: ten to twenty times cheaper than us, depending on which of our packs you compare. If follower graphs are your main job, use it. Weir makes sense if follower exports are a side task next to search, timelines, Reddit data or monitors that you already run through one key. The official API makes sense if you need X's own terms, or if you're exporting your own followers at the $0.001 Owned Reads rate.

Doing this with Weir

Create a free account, set WEIR_API_KEY, and run the script. The first 15 pages fit inside the monthly free credits. The getXUserFollowers reference documents every field, and /v1/x/users/{user}/following works the same way for the accounts a user follows. For posts instead of people, see how to get tweets with Python. For a fuller comparison of providers, see Twitter API alternatives.

Sources