# Twitter Followers Scraper (X) (`sfoln/x-followers`)

Export the followers of any public X (Twitter) account, newest first: full profiles with bio, location, follower counts and join date, or bulk follower IDs. $0.30 per 1,000 follower profiles + $0.002 per page of 200; IDs $0.05 per 1,000 + $0.003 per page of 5,000.

- Family: Social media data
- Categories: Social media, Lead generation, Automation
- Availability: on request (private on Apify). Email contact@sfoln.com with subject "Access request: Twitter Followers Scraper (X) (sfoln/x-followers)" before calling; calls fail until it is public.
- JSON: https://www.sfoln.com/actors/x-followers.json
- MCP: https://mcp.apify.com?tools=sfoln/x-followers
- REST (sync): POST https://api.apify.com/v2/actors/sfoln~x-followers/run-sync-get-dataset-items
- REST (async): POST https://api.apify.com/v2/actors/sfoln~x-followers/runs

Twitter Followers Scraper (X) exports the followers of any public X (Twitter) account, newest first, as clean, flat records. Choose full follower profiles (handle, name, bio with expanded links, location, website, follower / following / post counts, avatar, account creation date, automated-account label) or bulk follower IDs (up to 5,000 per request, the cheapest way to map a follower graph). Built for audience research, influencer vetting, competitor analysis, lead lists and social-graph datasets.

## Price per delivered record

| Event | Price | Per 1,000 | Charged for |
| --- | --- | --- | --- |
| X follower profile (`x-follower-profile`) | $0.0003 | $0.30 / 1,000 | Charged once per follower profile delivered (mode "profiles"). |
| X follower ID (`x-follower-id`) | $0.00005 | $0.05 / 1,000 | Charged once per follower id delivered (mode "ids"). |
| Followers page (`x-followers-query`) | $0.002 | $2 / 1,000 | Charged once per upstream page of up to 200 follower profiles (mode "profiles"), including the last page and empty pages; covers the provider's per-call minimum. |
| Follower IDs page (`x-follower-ids-query`) | $0.003 | $3 / 1,000 | Charged once per upstream page of up to 5,000 follower ids (mode "ids"), including the last page and empty pages; covers the provider's per-call minimum. |

Pay-per-event, USD, billed by Apify; no platform usage charge. Only records with status `ok` are charged. Cap a run with `maxTotalChargeUsd`. Apify free plan: up to 10 per run.

## Run

```bash
curl -X POST "https://api.apify.com/v2/actors/sfoln~x-followers/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"handles":["apify"],"maxFollowersPerUser":20}'
```

MCP client configuration:

```json
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/x-followers"
    }
  }
}
```

Example prompt: Export the 200 newest followers of @apify on X with their bios, locations and follower counts.

## Input

Paste X (Twitter) handles. The Actor returns their followers (newest first), one dataset record per follower, plus one summary record per account.

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| `handles` (required) | array | — | Handles or profile URLs: X handles (with or without @) or profile URLs, one per line. Duplicates are removed. Accounts on the Apify free plan can process up to 10 accounts per run. |
| `maxFollowersPerUser` | integer | `200` | Max followers per account: How many of the most recent followers to return per account (1–5000). |
| `mode` | string | `"profiles"` | Mode: "profiles" returns full follower profiles (pages of up to 200). "ids" returns only numeric follower ids (pages of up to 5,000), much cheaper per row. One of `"profiles"`, `"ids"`. |
| `maxItems` | integer | `1000` | Max accounts: Safety cap on the number of accounts processed in this run. Accounts beyond it are not processed or charged; their number is reported in the run's status message and OUTPUT (inputItemsDropped). |
| `concurrency` | integer | `3` | Concurrency: Accounts processed in parallel (1–5). |
| `itemTimeoutSecs` | integer | `300` | Per-account time limit (seconds): Stop paginating an account after this long; rows already delivered are kept. |
| `includeRaw` | boolean | `false` | Include raw upstream response: Attach the unmodified TwitterAPI.io user object to each profile record under `raw` (profiles mode only). |

Example input:

```json
{
  "handles": [
    "apify"
  ],
  "maxFollowersPerUser": 20
}
```

## Output

One record per input item with `status` (`ok` is charged; `not_found`, `error`, `skipped_*` are free) and `charged`. The run stores an `OUTPUT` summary record.

| Field | Type | Meaning |
| --- | --- | --- |
| `input` | string | object | Input: The input item this record corresponds to. |
| `status` | string | Status: ok \| not_found \| error \| skipped_invalid \| skipped_budget \| skipped_free_plan (result rows are always ok) |
| `charged` | boolean | Charged: Whether this record incurred a pay-per-event charge. |
| `chargedEvent` | string | Charged event: Pay-per-event event charged for this record. |
| `source` | string | Source: Upstream data source (twitterapi = TwitterAPI.io). |
| `fetchedAt` | string | Fetched at: ISO timestamp. |
| `error` | object | Error: code / message when status is not ok. |
| `warnings` | array | Warnings: Non-fatal notes (e.g. stopped early). |
| `recordType` | string | Row type: follower (one per profile, charged) \| follower-id (one per id, charged) \| account-summary (one per input account, free). |
| `ofHandle` | string | null | Of account: The input account whose followers this row lists. |
| `position` | integer | null | Position: 1 = most recent follower (newest first). |
| `handle` | string | null | Handle: X handle without @. |
| `userId` | string | null | User id: Numeric X user id as a string. |
| `name` | string | null | Name: Display name. |
| `bio` | string | null | Bio: Profile description with t.co links expanded. |
| `location` | string | null | Location: Free-text profile location. |
| `url` | string | null | Website: Website link from the profile (expanded). |
| `profileUrl` | string | null | Profile URL: https://x.com/<handle>. |
| `followers` | integer | null | Followers: Follower count. |
| `following` | integer | null | Following: Accounts followed. |
| `tweets` | integer | null | Posts: Total posts incl. replies and reposts (statusesCount). |
| `likes` | integer | null | Likes given: Posts this account has liked (favouritesCount). |
| `mediaCount` | integer | null | Media: Media posts. |
| `isBlueVerified` | boolean | null | Blue verified: Has a blue check (null when the endpoint does not report it). |
| `verifiedType` | string | null | Verified type: Business / Government / null. |
| `profileImageUrl` | string | null | Avatar: Profile image URL. |
| `coverImageUrl` | string | null | Banner: Banner image URL. |
| `createdAt` | string | null | Created at: ISO 8601 account creation time. |
| `isAutomated` | boolean | null | Automated: Labelled as an automated account. |
| `automatedBy` | string | null | Automated by: Handle of the operator of an automated account. |
| `canDm` | boolean | null | Can DM: Accepts direct messages. |
| `possiblySensitive` | boolean | null | Possibly sensitive: Marked as possibly sensitive. |
| `withheldInCountries` | array | Withheld in: Country codes where the account is withheld. |
| `pinnedTweetIds` | array | Pinned post ids: Ids of pinned posts. |
| `unavailable` | boolean | null | Unavailable: Account is suspended / deactivated / unavailable. |
| `unavailableReason` | string | null | Unavailable reason: e.g. suspended. |
| `unavailableMessage` | string | null | Unavailable message: Upstream message for unavailable accounts. |
| `mode` | string | null | Mode: profiles \| ids (summary rows). |
| `followersReturned` | integer | null | Rows returned: followers delivered for this account (summary rows). |
| `pageFeesCharged` | integer | null | Page fees charged: Per-page events charged for this account (summary rows). |
| `pageFeeEvent` | string | null | Page fee event: Event name of the per-page fee (summary rows). |
| `pagesFetched` | integer | null | Pages fetched: Upstream pages fetched (summary rows). |
| `stopReason` | string | null | Stop reason: limit \| end \| budget \| deadline \| empty_pages \| max_pages \| error (summary rows). |

Example record:

```json
{
  "input": "apify",
  "recordType": "follower",
  "ofHandle": "apify",
  "position": 1,
  "handle": "jane_dev",
  "userId": "1458000000000000000",
  "name": "Jane",
  "bio": "Data engineer. Blog: https://jane.dev",
  "location": "Prague",
  "url": "https://jane.dev",
  "profileUrl": "https://x.com/jane_dev",
  "followers": 812,
  "following": 301,
  "tweets": 4210,
  "likes": 9120,
  "mediaCount": 133,
  "isBlueVerified": null,
  "verifiedType": null,
  "profileImageUrl": "https://pbs.twimg.com/profile_images/1/a_normal.jpg",
  "coverImageUrl": "https://pbs.twimg.com/profile_banners/1/1",
  "createdAt": "2021-11-03T09:12:44.000Z",
  "isAutomated": false,
  "automatedBy": null,
  "canDm": true,
  "possiblySensitive": false,
  "withheldInCountries": [],
  "pinnedTweetIds": [],
  "unavailable": false,
  "unavailableReason": null,
  "unavailableMessage": null,
  "status": "ok",
  "charged": true,
  "chargedEvent": "x-follower-profile",
  "source": "twitterapi",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}
```

## Related

- [Twitter Following Scraper (X)](https://www.sfoln.com/actors/x-following.md) (`sfoln/x-following`)
- [Twitter Profile Scraper (X)](https://www.sfoln.com/actors/x-profile-lookup.md) (`sfoln/x-profile-lookup`)
- [Twitter (X) Account Audit – Engagement](https://www.sfoln.com/actors/x-account-overview.md) (`sfoln/x-account-overview`)

Publisher: SFOLN LLC, contact@sfoln.com. Catalogue: https://www.sfoln.com/catalog.json. Agent guide: https://www.sfoln.com/agents.md.
