> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sorsa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Followers & Following

# How to Get Twitter Followers and Following Lists via API

The follower and following lists of any public X (formerly Twitter) account are some of the most valuable datasets on the platform. A follower list tells you who is interested in a brand, topic, or personality. A following list reveals who that account pays attention to: their influences, competitors, and information sources. Together, they map the social graph around any account.

Sorsa API provides two endpoints for extracting this data: `/followers` (who follows an account) and `/follows` (who an account is following). Both return up to 200 full user profiles per request, with cursor-based pagination to walk through the complete list. Every user object includes bio, follower count, tweet count, location, verified status, profile image, and more.

This guide covers both endpoints from the simplest possible request through production-scale extraction with filtering, audience overlap analysis, and pagination strategy.

> **Free to start:** Every Sorsa endpoint, including `/followers`, `/follows`, and `/verified-followers`, is available on your first 100 requests: one-time, no credit card, no expiry. Since each request returns up to 200 profiles, that covers roughly the first 20,000 followers of any account before you need a paid plan.

> **Note:** For a complete walkthrough with extra extraction methods and worked audience-analysis examples, see [Twitter Followers API: Get Followers and Following Lists](https://api.sorsa.io/blog/twitter-followers-api) on the blog.

***

## Simplest Example: Get Followers

One request, one response. This is all you need to fetch the first page of followers for any public account.

### cURL

```bash theme={null}
curl "https://api.sorsa.io/v3/followers?username=stripe" \
  -H "ApiKey: YOUR_API_KEY"
```

### Python

```python theme={null}
import requests

resp = requests.get(
    "https://api.sorsa.io/v3/followers",
    headers={"ApiKey": "YOUR_API_KEY"},
    params={"username": "stripe"},
)
for user in resp.json().get("users", []):
    print(f"@{user['username']} - {user.get('description', '')[:80]}")
```

### JavaScript

```javascript theme={null}
const resp = await fetch(
  "https://api.sorsa.io/v3/followers?username=stripe",
  { headers: { "ApiKey": "YOUR_API_KEY" } }
);
const { users } = await resp.json();
users.forEach((u) =>
  console.log(`@${u.username} - ${u.description?.slice(0, 80) ?? ""}`)
);
```

A GET request with your API key and a username. The response is an array of up to 200 user objects with full profile data.

> **Tip:** You can preview followers for any account without code using the [Recent Followers](https://api.sorsa.io/playground/recent-followers) tool or the [API Playground](https://api.sorsa.io/playground).

***

## Simplest Example: Get Following (Subscriptions)

The `/follows` endpoint works identically but returns the accounts that a user is following:

```bash theme={null}
curl "https://api.sorsa.io/v3/follows?username=stripe" \
  -H "ApiKey: YOUR_API_KEY"
```

```python theme={null}
resp = requests.get(
    "https://api.sorsa.io/v3/follows",
    headers={"ApiKey": "YOUR_API_KEY"},
    params={"username": "stripe"},
)
for user in resp.json().get("users", []):
    print(f"@{user['username']} ({user['followers_count']} followers)")
```

***

## Endpoint Reference

Both endpoints are GET requests with the same input options.

### `GET /v3/followers`

Returns users who **follow** the specified account.

### `GET /v3/follows`

Returns accounts that the specified user **is following**.

### Input Parameters (query string)

| Parameter     | Type    | Required | Description                                                                                                              |
| :------------ | :------ | :------- | :----------------------------------------------------------------------------------------------------------------------- |
| `username`    | string  | One of   | The handle without `@`. Example: `stripe`                                                                                |
| `user_id`     | string  | these    | The numeric user ID. Example: `44196397`                                                                                 |
| `user_link`   | string  | three    | Full profile URL. Example: `https://x.com/stripe`                                                                        |
| `next_cursor` | integer | No       | Pagination cursor. Take the `next_cursor` value from the previous response and pass it back here to fetch the next page. |

Provide exactly one of `username`, `user_id`, or `user_link`.

### Response

```json theme={null}
{
  "users": [
    {
      "id": "1234567890",
      "username": "developer_jane",
      "display_name": "Jane Chen",
      "description": "Full-stack developer. Building things with APIs.",
      "location": "San Francisco, CA",
      "profile_image_url": "https://pbs.twimg.com/profile_images/...",
      "profile_background_image_url": "https://pbs.twimg.com/profile_banners/...",
      "followers_count": 4820,
      "followings_count": 312,
      "tweets_count": 1847,
      "favourites_count": 5231,
      "media_count": 89,
      "verified": false,
      "protected": false,
      "can_dm": true,
      "possibly_sensitive": false,
      "created_at": "2018-01-15T08:22:41Z",
      "bio_urls": ["https://janechen.dev"],
      "pinned_tweet_ids": ["1987654321098765432"]
    }
  ],
  "next_cursor": 1234567890
}
```

Each user object includes: `id`, `username`, `display_name`, `description`, `location`, `created_at`, `followers_count`, `followings_count`, `favourites_count`, `tweets_count`, `media_count`, `profile_image_url`, `profile_background_image_url`, `bio_urls`, `pinned_tweet_ids`, `verified`, `can_dm`, `protected`, and `possibly_sensitive`.

Each page returns up to **200 user objects**. When `next_cursor` is present in the response, more results are available: pass its value back as the `next_cursor` parameter in your next request. When it is absent or null, you have reached the end of the list.

***

## Paginating Through a Full Follower List

A single request returns one page. To collect the complete follower list, loop through pages using `next_cursor` until it is absent.

### Python

```python theme={null}
import requests
import time

API_KEY = "YOUR_API_KEY"

def get_all_followers(username, max_pages=50):
    """Fetch the complete follower list of a public account."""
    all_users = []
    cursor = None

    for page in range(max_pages):
        params = {"username": username}
        if cursor:
            params["next_cursor"] = cursor

        resp = requests.get(
            "https://api.sorsa.io/v3/followers",
            headers={"ApiKey": API_KEY},
            params=params,
            timeout=30,
        )
        resp.raise_for_status()
        data = resp.json()

        users = data.get("users", [])
        all_users.extend(users)
        print(f"Page {page + 1}: {len(users)} followers (total: {len(all_users)})")

        cursor = data.get("next_cursor")
        if not cursor:
            print("Reached end of list.")
            break
        time.sleep(0.05)  # stay under 20 req/s

    return all_users


followers = get_all_followers("stripe", max_pages=100)
print(f"\nTotal followers collected: {len(followers)}")
```

### JavaScript

```javascript theme={null}
const API_KEY = "YOUR_API_KEY";

async function getAllFollowers(username, maxPages = 50) {
  const allUsers = [];
  let cursor = null;

  for (let page = 0; page < maxPages; page++) {
    const params = new URLSearchParams({ username });
    if (cursor) params.set("next_cursor", cursor);

    const resp = await fetch(
      `https://api.sorsa.io/v3/followers?${params}`,
      { headers: { "ApiKey": API_KEY } }
    );
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);

    const data = await resp.json();
    allUsers.push(...(data.users || []));

    console.log(`Page ${page + 1}: ${data.users?.length || 0} followers (total: ${allUsers.length})`);

    cursor = data.next_cursor;
    if (!cursor) break;
    await new Promise((r) => setTimeout(r, 50));
  }
  return allUsers;
}

const followers = await getAllFollowers("stripe");
```

The same pagination pattern works for `/follows`: just change the URL.

For a deeper look at pagination behavior across all paginated endpoints, see [Pagination](https://docs.sorsa.io/pagination).

***

## Getting a Full Following List

The code is identical with the endpoint swapped. Looking at who an account follows is often more revealing than looking at their followers: a founder's following list tells you which investors, partners, and competitors they pay attention to; an influencer's following list reveals their information sources.

```python theme={null}
def get_all_following(username, max_pages=50):
    """Fetch the complete list of accounts a user follows."""
    all_users = []
    cursor = None

    for page in range(max_pages):
        params = {"username": username}
        if cursor:
            params["next_cursor"] = cursor

        resp = requests.get(
            "https://api.sorsa.io/v3/follows",
            headers={"ApiKey": API_KEY},
            params=params,
            timeout=30,
        )
        resp.raise_for_status()
        data = resp.json()

        users = data.get("users", [])
        all_users.extend(users)

        cursor = data.get("next_cursor")
        if not cursor:
            break
        time.sleep(0.05)

    return all_users


following = get_all_following("naval", max_pages=20)
print(f"@naval follows {len(following)} accounts")

# Sort by follower count to see the biggest names
following.sort(key=lambda u: u.get("followers_count", 0), reverse=True)
for u in following[:10]:
    print(f"  @{u['username']} ({u['followers_count']:,} followers)")
```

***

## Practical Applications

### Filtering Followers by Profile Criteria

The raw list is useful, but filtering it makes it actionable. Since every user object includes full profile metadata, you can segment the audience by any attribute without additional API calls:

```python theme={null}
followers = get_all_followers("competitor_handle", max_pages=20)

# High-value accounts: 1K+ followers, active (100+ tweets), not protected
qualified = [
    u for u in followers
    if u.get("followers_count", 0) >= 1000
    and u.get("tweets_count", 0) >= 100
    and not u.get("protected", False)
]
print(f"Qualified leads: {len(qualified)} out of {len(followers)} total")

# Accounts with websites in their bio (potential business leads)
with_websites = [u for u in followers if u.get("bio_urls")]
print(f"Accounts with website links: {len(with_websites)}")

# Filter by location keyword (self-reported)
in_usa = [
    u for u in followers
    if "usa" in (u.get("location") or "").lower()
    or "united states" in (u.get("location") or "").lower()
    or ", us" in (u.get("location") or "").lower()
]
print(f"US-based followers: {len(in_usa)}")
```

The `location` field is freeform user-entered text. For more reliable country-level data, use the `/about` endpoint to look up each account's country tag. See [Audience Geography](https://docs.sorsa.io/Audience-Geography) for the full workflow.

### Finding Audience Overlap Between Competitors

Pull follower lists from multiple competitors and find users who follow two or more of them. These are the most engaged people in your market: they have actively opted in to the topic multiple times.

```python theme={null}
from collections import Counter

competitors = ["competitor1", "competitor2", "competitor3"]
all_ids = []

for handle in competitors:
    followers = get_all_followers(handle, max_pages=10)
    ids = [u["id"] for u in followers]
    all_ids.extend(ids)
    print(f"@{handle}: {len(followers)} followers collected")

# Count how many competitor lists each user appears in
counts = Counter(all_ids)
overlap = {uid: count for uid, count in counts.items() if count >= 2}
print(f"\nUsers following 2+ competitors: {len(overlap)}")
```

For a complete workflow combining follower extraction with bio search and community mining, see [Target Audience Discovery](https://docs.sorsa.io/target-audiences-Discovery).

### Discovering What Industry Leaders Follow

Scrape the following list of an expert or thought leader to find who they consider worth paying attention to. This surfaces niche accounts, emerging voices, and tools that leaders rely on.

```python theme={null}
following = get_all_following("pmarca", max_pages=10)

print(f"@pmarca follows {len(following)} accounts. Top by follower count:")
following.sort(key=lambda u: u.get("followers_count", 0), reverse=True)
for u in following[:15]:
    print(f"  @{u['username']} ({u['followers_count']:,} followers)")
    print(f"    {u.get('description', '')[:70]}\n")
```

***

## Verified Followers

The `/verified-followers` endpoint works the same as `/followers` but returns only verified accounts (Blue, Gold, or Gray checkmarks). This is useful for two cases:

1. **Filtering an audience to high-profile accounts** without post-processing the full list.
2. **Avoiding wasted requests on large accounts** where verified users are a small minority. Walking the entire follower list of a 10M-follower account just to find the 5,000 verified ones spends 50,000 requests; `/verified-followers` returns the same data in roughly 25 requests.

```bash theme={null}
curl "https://api.sorsa.io/v3/verified-followers?username=stripe" \
  -H "ApiKey: YOUR_API_KEY"
```

The response structure and pagination are identical to `/followers`: iterate with `next_cursor` in exactly the same way. See the [API Reference](https://docs.sorsa.io/api-reference/users-data/verified-followers) for full details.

***

## Estimating API Usage at Scale

Each page returns up to 200 user objects. For planning:

| Account Size        | Pages Needed | Requests |
| :------------------ | :----------- | :------- |
| 1,000 followers     | 5            | 5        |
| 10,000 followers    | 50           | 50       |
| 100,000 followers   | 500          | 500      |
| 1,000,000 followers | 5,000        | 5,000    |

At Sorsa's rate limit of 20 requests per second (the same on every plan), extracting 10,000 followers takes about 3 seconds; 100,000 followers takes about 25 seconds. For accounts with millions of followers, consider sampling (for example, the first 50 pages, roughly 10,000 followers) rather than a full extraction, unless you specifically need complete coverage.

Because each request returns up to 200 profiles, follower extraction is request-cheap. To put the request counts above in context: the free 100 requests cover about 20,000 followers, the Starter plan (10,000 requests per month) covers about 2,000,000, and Pro (100,000 requests per month) covers about 20,000,000. For full pricing, see [Pricing](https://api.sorsa.io/pricing).

***

## Data Freshness and Edge Cases

**Follower ordering.** The `/followers` endpoint returns followers in the order X provides them, which is generally reverse-chronological (newest followers first). The first pages contain the most recently acquired followers.

**Protected accounts.** If the target account is protected (private), the follower and following lists are not accessible. The endpoint returns an error.

**Follower count vs. extracted list.** The `followers_count` value on a profile is a real-time counter maintained by X. The extractable list may differ slightly due to suspended, deactivated, or recently removed accounts. Expect a few percent of drift on large accounts; do not write strict equality checks against `followers_count`. This is a platform-level behavior, not Sorsa-specific.

**Profile data is current.** Each user object reflects the profile as it exists at the time of the request (current bio, current follower count, current username), not the state at the moment the follow relationship was established. The numeric `id` is stable; the handle is not.

**Sampling for very large accounts.** For accounts over about 500,000 followers, the first 50 to 100 pages (10,000 to 20,000 followers) is usually a representative sample of the recent audience and is enough for most analyses. Full extraction is rarely necessary unless you have a specific reason to need complete coverage.

***

## Next Steps

* [Target Audience Discovery](https://docs.sorsa.io/target-audiences-Discovery): combine follower extraction with bio search, community scraping, and content mining.
* [Competitor Analysis](https://docs.sorsa.io/Competitor-Analysis): use follower and following data as part of a competitive intelligence pipeline.
* [Audience Geography](https://docs.sorsa.io/Audience-Geography): map follower distribution by country using the `/about` endpoint.
* [Pagination](https://docs.sorsa.io/pagination): general pagination patterns for large-scale extraction.
* [API Reference](https://docs.sorsa.io/api-reference-guide): full specification for `/followers`, `/follows`, `/verified-followers`, and all Sorsa API endpoints.
