# X (Twitter) Follower Scraper | $0.06/1K | Followers & Following (`feedminer/x-follower-scraper`) Actor

Export the followers and following of any X (Twitter) account, plus its verified followers and the members of any X list. One row per account with handle, name, bio, follower and following counts, verification, location, links and join date, exported as JSON, CSV or Excel. Flat price. By FeedMiner.

- **URL**: https://apify.com/feedminer/x-follower-scraper.md
- **Developed by:** [FeedMiner](https://apify.com/feedminer) (community)
- **Categories:** Social media, Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / 1,000 account returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

<div style="border-left:4px solid #1D9BF0;background:#F2F9FF;padding:14px 18px;border-radius:6px">
<strong>Export the followers of any X (Twitter) account, the accounts it follows, and its verified followers.</strong> One row per account with handle, name, bio, follower counts, verification, location and links, ready for JSON, CSV or Excel. No code.
</div>

💸 **$0.06 per 1,000 accounts, down to $0.05 on the larger Apify plans.** The most visible follower list on the store bills $0.15 per 1,000, the next one $0.25 plus a start fee on every run. Here there is no start fee.

🧩 **Three audiences, one actor.** Followers, following and verified followers come out of the same run, tagged by relation, so a competitor audit is one input instead of three tools.

🧬 **Same fields as the rest of the suite.** An account row here carries the field names of X Profile Scraper and of the author block in X Tweet Scraper. Three actors, one schema, no mapping to write.

🛟 **A dead handle never kills a run.** Renamed, suspended and protected accounts are reported and skipped, and the accounts already collected are kept and delivered.

#### Copy to your AI assistant

```
feedminer/x-follower-scraper on Apify. Exports the followers, following and verified followers of X (Twitter) accounts. One row per account with id, userName, name, description, followers, following, isVerified, isBlueVerified, location, profilePicture, createdAt, plus relation and source. Call ApifyClient("TOKEN").actor("feedminer/x-follower-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items. Requires handles (string[]), relations (string[] of followers|following|verifiedFollowers), maxItems (int). Full spec: GET https://api.apify.com/v2/acts/feedminer~x-follower-scraper/builds/default (Bearer TOKEN) → inputSchema, actorDefinition.storages.dataset, readme. Token: https://console.apify.com/account/integrations
```

***

### <img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/hoZ24gXinDHziMQKm-actor-3hbiY2nfMGfbNdh1w-DUuuMSYQpE-IMG_9471.jpeg" width="26" height="26" style="vertical-align:-4px;border-radius:6px"/> How to scrape followers on X (Twitter)

Paste handles, choose what you want, press Start.

##### Basic: the followers of one account

```json
{ "handles": ["apify"], "relations": ["followers"], "maxItems": 5000 }
```

##### Who a founder follows, which is the shorter and denser list

```json
{ "handles": ["paulg"], "relations": ["following"], "maxItems": 3000 }
```

Following lists are usually a few hundred accounts and say far more about interests than a follower list of a million.

##### Verified followers only, for a partner shortlist

```json
{ "handles": ["stripe"], "relations": ["verifiedFollowers"], "maxItems": 2000 }
```

##### Compare two audiences in one run

```json
{
  "handles": ["stripe", "adyen"],
  "relations": ["followers"],
  "maxItems": 20000
}
```

Every row carries `source`, so one pivot on that column gives you the overlap and the difference between the two audiences.

***

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `handles` | array |  | Accounts to read, as handles or profile URLs |
| `relations` | array | `['followers']` | Followers of the account, accounts it follows, or its verified followers |
| `maxItems` | integer | `1000` | Stop once this many accounts have been collected, shared across the targets |

**Advanced**

| Parameter | Type | Default | Description |
|---|---|---|---|
| `sessions` | array |  | Optional. The Actor works without one. X accounts of your own, for anyone who would rather the run used accounts they control |
| `debugMode` | boolean | `false` | Verbose logs for support |

#### Coming from another follower scraper

Paste the input you already send elsewhere. `user_names`, `userNameList`, `usernames`, `twitterHandles`, `urls`, `profileUrl` and `startUrls` are all read as accounts, and `userIds`, `user_ids` and `userIdList` as numeric account ids, which skip the lookup entirely, `getFollowers`, `getFollowing`, `getVerifiedFollowers`, `relation` and `type` all select what to collect, and `maxFollowers`, `maxFollowings` and `maxResults` all cap the run. Nothing to rewrite.

#### Nothing to connect

Paste handles and press Start. There is no account to create, no cookie to copy and nothing to keep alive on your side.

If you would rather the run worked from accounts you own, the optional `sessions` field takes them as browser cookies. Several can be given at once and the work spreads across them.

***

### What data can you extract from X (Twitter) followers?

| Field | Type | Description |
|---|---|---|
| `id` | string | Numeric account id, stable across renames |
| `userName` | string | Handle, without the at sign |
| `name` | string | Display name |
| `description` | string | Bio, where the job titles and the emails are |
| `followers` | integer | Follower count |
| `following` | integer | Following count |
| `statusesCount` | integer | Posts published |
| `mediaCount` | integer | Photos and videos published |
| `favouritesCount` | integer | Posts this account has liked |
| `isVerified` | boolean | Legacy verification |
| `isBlueVerified` | boolean | Paid verification |
| `location` | string | Free text location from the profile |
| `twitterUrl` | string | Profile URL |
| `profilePicture` | string | Avatar URL |
| `coverPicture` | string | Header image URL |
| `createdAt` | string | Account creation date, RFC 3339 |
| `relation` | string | Why this row is here: `followers`, `following`, `verifiedFollowers` |
| `source` | string | The handle the row was collected from |

#### Example output

```json
{
  "id": "2244994945",
  "userName": "apify",
  "name": "Apify",
  "description": "Full-stack web scraping and data extraction platform.",
  "followers": 6280,
  "following": 412,
  "statusesCount": 3891,
  "isBlueVerified": true,
  "location": "Prague",
  "twitterUrl": "https://x.com/apify",
  "createdAt": "2013-12-14T04:35:55Z",
  "relation": "followers",
  "source": "apify"
}
```

***

### Column mapping, if you are switching

Three vocabularies exist on this market. Ours is the one X Profile Scraper and
X Tweet Scraper already use, so the three FeedMiner actors feed one pipeline.
Here is what to rename if you came from elsewhere.

| Here | kaitoeasyapi | api-ninja | xquik |
|---|---|---|---|
| `id` | `id_str` | `user_id` | `id` |
| `userName` | `screen_name` | `screen_name` | `username` |
| `name` | `name` | `name` | `name` |
| `description` | `description` | `description` | `description` |
| `followers` | `followers_count` | `followers_count` | `followers` |
| `following` | `friends_count` | `friends_count` | `following` |
| `statusesCount` | `statuses_count` | `statuses_count` | `statusesCount` |
| `mediaCount` | `media_count` | `media_count` | `mediaCount` |
| `favouritesCount` | `favourites_count` | not returned | `favouritesCount` |
| `isVerified` | `verified` | `verified` | `isVerified` |
| `isBlueVerified` | not returned | `blue_verified` | not returned |
| `location` | `location` | `location` | `location` |
| `profilePicture` | `profile_image_url_https` | `profile_image` | not returned |
| `createdAt` | `created_at` | `created_at` | not returned |
| `relation` | `type` | not returned | `resultType` |
| `source` | `target_username` | not returned | not returned |

One field appears elsewhere and not here on purpose: `email`. X does not publish
an email on a profile, so a column named that way is empty on every row.

### Pricing: Pay Per Event (PPE)

| Event | Price |
|---|---|
| Account returned | $0.00006 |

That is **$0.06 per 1,000 accounts**, with no start fee and no charge for a run that returns nothing. A 50,000 account audience costs $3. The price steps down on its own for the larger Apify plans, to $0.055 and then $0.05 per 1,000.

***

##### What a run costs

| | |
|---|---|
| A 5,000 account audience | $0.30 |
| Two competitors compared, 20,000 accounts each, 40,000 rows | $2.40 |

##### Free tier

The Apify free plan includes $5 of usage every month, which is roughly 83,000 accounts here. No card required.

### Advanced usage

**Audience overlap.** Run two competitors in one job, export to CSV, pivot on `userName` counting `source`. Anyone appearing twice follows both, which is the shortest path to a lookalike list.

**Filter before you enrich.** `followers`, `description` and `isBlueVerified` are on every row, so a 100,000 row export narrows to the 2,000 accounts worth enriching before you spend anything on enrichment.

**Track an audience over time.** Schedule the same handles weekly. Comparing two exports on `id` shows who joined and who left, which is how you spot a competitor's new hires and lost customers.

**Big audiences.** A million follower account is walked from the newest follower backwards, so a partial run is still the most recent slice, not a random one.

***

### Integrate X follower data into your stack

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("feedminer/x-follower-scraper").call(run_input={
    "handles": ["stripe", "adyen"],
    "relations": ["followers"],
    "maxItems": 20000,
})

rows = client.dataset(run["defaultDatasetId"]).list_items().items
both = {r["userName"] for r in rows if r["source"] == "stripe"} & \
       {r["userName"] for r in rows if r["source"] == "adyen"}
print(len(both), "accounts follow both")
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('feedminer/x-follower-scraper').call({
    handles: ['stripe'],
    relations: ['verifiedFollowers'],
    maxItems: 2000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const leads = items.filter((i) => i.followers > 1000 && /founder|ceo/i.test(i.description || ''));
```

**No code**

The dataset connects to Google Sheets, Airtable, Slack, Zapier, Make and n8n from the Integrations tab of the run, with no extra work.

***

### Performance

| Measure | Value |
|---|---|
| Accounts per page | 20, the same page size X's own web app requests |
| Parallelism | One worker per account supplied, so more accounts means more speed |
| Partial results | Kept and delivered when a limit is reached |

***

### FAQ

**Do I need an X account?**
No. Paste handles and press Start. The optional `sessions` field is there for anyone who would rather run on accounts they own.

**Is my account safe?**
The run reads at the pace of a person browsing, one page of twenty at a time, and stops an account as soon as X pushes back instead of hammering it. Give a secondary account rather than your main one, as you would to any third party tool.

**How many followers can I get from one account?**
X paginates a follower list deeply, and this scraper follows the cursor as far as your `maxItems` asks. Very large audiences are walked newest first, so stopping early still gives you the freshest slice.

**Can I get followers of a protected account?**
No. A protected account hides its relations from everyone, and the run reports it instead of failing.

**Why is a row missing an email?**
X profiles have no email field. What people do put in `description` is often a contact, which is why the bio is on every row.

**What happens when an account gets rate limited?**
The run moves the work to another account you supplied, and keeps everything already collected. With one account it slows down rather than failing.

**Can I schedule this?**
Yes. Apify Schedules run it daily or weekly, and comparing two exports on `id` gives you joins and leaves.

***

### Support

Something wrong in a row, a field you need, an audience you cannot reach: write from the actor page and it gets read.

***

### Legal compliance

This actor collects data that X publishes on public profiles. It does not access private accounts, direct messages or anything behind a follow request. Personal data in the output is subject to GDPR, CCPA and similar regimes: collect what you have a lawful basis to collect, keep it only as long as you need it, and honour deletion requests. You are the controller of what you export.

***

**FeedMiner** · Fast, honestly priced scrapers, kept alive when platforms change.

[X Tweet Scraper](https://apify.com/feedminer/x-tweet-scraper) · [X Profile Scraper](https://apify.com/feedminer/x-profile-scraper) · X Follower Scraper · [X Advanced Search Scraper](https://apify.com/feedminer/x-advanced-search-scraper) · [X Media Scraper](https://apify.com/feedminer/x-media-scraper) · [X Mentions Monitor](https://apify.com/feedminer/x-mentions-scraper) · [X Engagement Scraper](https://apify.com/feedminer/x-engagement-scraper) · [X Likes and Reposts Scraper](https://apify.com/feedminer/x-signals-scraper) · [X Trends Scraper](https://apify.com/feedminer/x-trends-scraper) · [All FeedMiner Actors](https://apify.com/feedminer)

# Actor input Schema

## `handles` (type: `array`):

Accounts to read, as handles or profile URLs.

## `relations` (type: `array`):

Followers of the account, accounts it follows, or its verified followers.

## `maxItems` (type: `integer`):

Stop once this many accounts have been collected, shared across the targets.

## `sessions` (type: `array`):

Optional. The Actor works without one. X accounts of your own, for anyone who would rather the run used accounts they control.

## `debugMode` (type: `boolean`):

Verbose logs for support.

## Actor input object example

```json
{
  "handles": [
    "apify"
  ],
  "relations": [
    "followers"
  ],
  "maxItems": 1000,
  "sessions": [
    {
      "label": "account-1",
      "authToken": "",
      "ct0": ""
    }
  ],
  "debugMode": false
}
```

# Actor output Schema

## `accounts` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "handles": [
        "apify"
    ],
    "maxItems": 1000,
    "sessions": [
        {
            "label": "account-1",
            "authToken": "",
            "ct0": ""
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("feedminer/x-follower-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "handles": ["apify"],
    "maxItems": 1000,
    "sessions": [{
            "label": "account-1",
            "authToken": "",
            "ct0": "",
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("feedminer/x-follower-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "handles": [
    "apify"
  ],
  "maxItems": 1000,
  "sessions": [
    {
      "label": "account-1",
      "authToken": "",
      "ct0": ""
    }
  ]
}' |
apify call feedminer/x-follower-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,feedminer/x-follower-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/YNv33FnCGpcjTd1uw/builds/KUVgrN1hjwdkFUWy9/openapi.json
