Get an X account's followers with Python, Node.js and cURL

Read the accounts that follow an X account, newest first, and count how many are verified and how many have 1,000 or more followers. Each page holds as many accounts as X returns, so each page is charged by its size.

It is one call to GET /v1/x/users/{user}/followers, which costs 1 credit a request, plus 2 per profile and 1 per account. Every snippet below ran against the live API on 27 October 2026, and the output is what the Python printed.

Set your key first. Create one at https://weirapp.io/dashboard/keys; every account gets 5,000 free credits a month.

export WEIR_API_KEY=weir_live_...

Python

import os

import requests

response = requests.get(
    "https://api.weirapp.io/v1/x/users/XDevelopers/followers",
    headers={"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
    timeout=60,
)
response.raise_for_status()
page = response.json()

accounts = page["data"]
print(len(accounts), "followers on this page")
print(sum(1 for account in accounts if account["verified"]), "of them verified")
print(sum(1 for account in accounts if account["followersCount"] >= 1000), "with 1,000+ followers")
print("credits charged:", response.headers["X-Credits-Charged"])

Node.js

// Node.js 18 or later, as an ES module (save as example.mjs).
const response = await fetch("https://api.weirapp.io/v1/x/users/XDevelopers/followers", {
  headers: { Authorization: `Bearer ${process.env.WEIR_API_KEY}` },
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
const page = await response.json();

const accounts = page.data;
console.log(accounts.length, "followers on this page");
console.log(accounts.filter((account) => account.verified).length, "of them verified");
console.log(
  accounts.filter((account) => account.followersCount >= 1000).length,
  "with 1,000+ followers",
);
console.log("credits charged:", response.headers.get("x-credits-charged"));

cURL

curl --request GET \
  --url 'https://api.weirapp.io/v1/x/users/XDevelopers/followers' \
  --header "Authorization: Bearer $WEIR_API_KEY"

Output

70 followers on this page
38 of them verified
24 with 1,000+ followers
credits charged: 73

The next page

A page ends with meta.nextCursor. Send it back as cursor, with every other parameter unchanged, until it is null. Each page is its own request and is charged as one.

import os

import requests

headers = {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"}
cursor = None
for number in range(1, 3):  # two pages; each page is its own charged request
    response = requests.get(
        "https://api.weirapp.io/v1/x/users/XDevelopers/followers",
        headers=headers,
        params={"cursor": cursor} if cursor else None,
        timeout=60,
    )
    response.raise_for_status()
    page = response.json()
    print(f"page {number}: {len(page['data'])} accounts, {response.headers['X-Credits-Charged']} credits")
    cursor = page["meta"]["nextCursor"]
    if not cursor:  # null means there is nothing more
        break
page 1: 70 accounts, 73 credits
page 2: 50 accounts, 51 credits

If a call fails

Failed calls are free. A 429 means too many requests a minute: wait the seconds in Retry-After and send it again. A 402 means the account is out of credits. A 503 means the source is busy and is safe to retry. Every code is on Errors, and paging is on Pagination.

View this page as Markdown