# X (Twitter) Profile Scraper & Growth Monitor (`fascinating_lentil/twitter-x-profile-scraper`) Actor

Extract public X (Twitter) profiles, available recent posts and engagement metrics for creator, brand and competitor research. Track follower growth, posting pace and profile changes; export CSV/JSON reports. $4/1,000 saved profiles plus the start event. No login in public-page mode.

- **URL**: https://apify.com/fascinating_lentil/twitter-x-profile-scraper.md
- **Developed by:** [Md Jakaria Mirza](https://apify.com/fascinating_lentil) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 profile scrapeds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## X (Twitter) Profile Scraper & Growth Monitor

Extract public X (Twitter) profiles for creator research, brand monitoring and competitor intelligence. Collect available profile totals, recent posts, engagement metrics, media, verification details and website links—then reuse a named watchlist to measure observed follower growth, posting pace and profile changes.

**No X login or API key is required for the default public-page mode.** An official X API bearer token remains available as an optional bring-your-own-token path.

### Why use this Actor?

Most profile exports are isolated snapshots. This Actor also makes repeat runs useful:

- Track follower growth, follower change, and followers gained per day.
- Track new posts and estimated posting pace per week.
- Detect bio, display name, website, and verification changes.
- Flag follower spikes, drops, new posts, and profile updates.
- Keep separate histories for different client or competitor watchlists.
- Export a spreadsheet-ready monitoring report in CSV and JSON.
- Receive profile data and recent posts together in one automation-friendly row.

Typical US-market workflows include creator vetting, executive and brand monitoring, influencer research, competitive intelligence, PR watchlists, and social audience tracking.

### What you get

#### Profile intelligence

- Username, display name, bio, location, and website
- Exact follower, following, and total post counts when exposed by X
- Avatar, banner, profile URL, account privacy, and verification type
- Pinned post ID when available
- Collection source and data-quality indicator

#### Recent post analytics

- Post text, URL, timestamp, author, and post ID
- Likes, reposts, replies, views, and quote count when available
- Images or video preview URLs
- Hashtags, mentions, and outbound links
- Reply, repost, quote, media, and pinned-post flags
- Per-profile totals and averages for recent engagement and views

#### Repeat-run monitoring

- `followersDelta` and `followersGrowthPercent`
- `followersPerDay`
- `tweetsDelta` and `postsPerWeek`
- Previous counts, observation count, and first/previous seen timestamps
- Changed fields and growth signals
- `baseline`, `updated`, `unchanged`, or `partial` tracking status

The first run creates a baseline. Later runs using the same `monitorName` compare against that watchlist's previous complete observation. Rate fields require observations at least one hour apart so short test runs do not create misleading growth rates.

### Quick start

```json
{
  "usernames": ["openai", "nasa", "github"],
  "maxTweetsPerProfile": 5,
  "trackGrowth": true,
  "monitorName": "US technology watchlist",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

For recurring intelligence, save this input as an Apify task and schedule it daily or weekly. Keep the same usernames and `monitorName` so comparisons remain continuous.

### Input

| Field | Purpose | Default |
|---|---|---|
| `usernames` | Up to 25 X usernames or x.com/twitter.com profile URLs | `openai` |
| `maxTweetsPerProfile` | Recent posts nested in each profile; set 0 for metrics only | `5` |
| `includeReplies` | Include recent replies | `false` |
| `includeRetweets` | Include recent reposts | `false` |
| `trackGrowth` | Persist bounded observations and calculate changes | `true` |
| `monitorName` | Stable name separating one watchlist from another | `default` |
| `observationHistoryLimit` | Observations retained per profile | `30` |
| `dataSource` | `auto`, `public-page`, or `api` | `auto` |
| `xApiBearerToken` | Optional secret official X API bearer token | empty |
| `proxyConfiguration` | Optional one-retry fallback after direct public access fails | disabled |

Public-page mode returns up to 20 recent posts. Official API mode supports up to 100, subject to the permissions and limits of your X developer plan.

### Output example

```json
{
  "username": "OpenAI",
  "displayName": "OpenAI",
  "followersCount": 5424044,
  "followingCount": 4,
  "tweetsCount": 2179,
  "websiteUrl": "https://openai.com",
  "verificationType": "Business",
  "profileUrl": "https://x.com/OpenAI",
  "dataSource": "public-page",
  "dataQuality": "detailed",
  "trackingStatus": "updated",
  "previousFollowersCount": 5419000,
  "followersDelta": 5044,
  "followersGrowthPercent": 0.0931,
  "followersPerDay": 720.57,
  "tweetsDelta": 4,
  "postsPerWeek": 4,
  "growthSignals": ["followers_growing", "new_posts"],
  "recentPostSummary": {
    "postsReturned": 5,
    "averageLikes": 15600,
    "averageViews": 7320000,
    "postsWithMedia": 3
  },
  "recentTweets": [
    {
      "tweetId": "2107894997538525580",
      "tweetUrl": "https://x.com/OpenAI/status/2107894997538525580",
      "text": "Example post text",
      "postedDate": "2026-10-07T18:05:04.000Z",
      "likesCount": 23000,
      "retweetsCount": 1800,
      "repliesCount": 1100,
      "viewsCount": 5900000,
      "hasMedia": true,
      "isPinned": true
    }
  ],
  "scrapedAt": "2026-10-11T12:00:00.000Z"
}
```

Example values illustrate the schema and can change at the source.

### Reports and integrations

Every successful run provides:

- **Default dataset:** profile records with nested recent posts and monitoring fields
- **`MONITORING-REPORT`:** JSON coverage, status, signal totals, and comparison rows
- **`MONITORING-REPORT.csv`:** spreadsheet-ready growth report with formula-injection protection
- **`OUTPUT`:** saved and failed target counts with concise failure reasons

Use the dataset API with Google Sheets, Airtable, Make, Zapier, n8n, BI tools, or your own data pipeline.

### Pricing: Saved Profiles + Actor Start

The undiscounted `profile-scraped` event costs **$0.004 per successfully saved profile** (`$4.00` per 1,000), including its available recent posts and monitoring comparison. The separate `apify-actor-start` event costs **$0.00005 per GB, minimum one event**, when the Actor starts.

| Successful profiles | Profile-event subtotal, before start fee or tier discounts |
|---:|---:|
| 1 | $0.004 |
| 10 | $0.04 |
| 25 | $0.10 |

Failed targets and empty responses that are not saved do not trigger `profile-scraped`. Profiles already saved before a partial failure retain their normal result charges. The Actor Start fee can still apply to empty or failed runs: Apify counts one start event per GB of memory, with at least one event. At the unchanged 256 MB default, that is `$0.00005` for the start event.

For example, one successfully saved profile at the undiscounted rate has `$0.00405` in result-plus-start event charges at 256 MB. That is an event subtotal, not a guarantee about separate platform or optional third-party API costs. Check the [live Pricing tab](https://apify.com/fascinating_lentil/twitter-x-profile-scraper/pricing) for current subscription-tier discounts and platform-usage terms. Your own official X API access, if selected, is not supplied by this Actor.

### Reliability and cost controls

- Uses direct HTTP rather than a browser for low memory and fast startup.
- Rejects mismatched, incomplete, or oversized source pages instead of saving misleading rows.
- Direct access is attempted first; Residential traffic is never enabled silently.
- A user-configured proxy receives only one retry after direct access fails.
- Monitoring history is bounded from 2 to 90 observations per profile.
- The `profile-scraped` result event is charged only when its dataset record is successfully saved; the separate Actor Start fee is not waived by an empty result.
- If every target fails, the run fails visibly rather than reporting false success.

Public websites can change. The Actor reports `dataQuality` so downstream workflows can distinguish complete post analytics from profile-only results.

### Official X API mode

Choose `dataSource: "api"` and provide `xApiBearerToken` if your workflow requires the official API. The token is treated as a secret and is never written to results or logs. API availability, fields, and request limits depend on your X developer plan.

### Responsible use

Use this Actor only for lawful collection of publicly available information. Respect X's terms, applicable privacy and data-protection laws, and the rights of account owners. Do not use the output for harassment, discrimination, surveillance, or unlawful profiling.

### Support

When reporting an issue, include the Apify run ID, input with secrets removed, affected public usernames, and the approximate run time. Never send API tokens in support messages.

### License

Apache-2.0

# Actor input Schema

## `usernames` (type: `array`):

Up to 25 public X accounts. Enter usernames such as openai or full x.com/twitter.com profile URLs. Duplicates are removed.

## `maxTweetsPerProfile` (type: `integer`):

Recent original posts to include inside each profile row. Public-page mode supports up to 20; official API mode supports up to 100. Set 0 for profile metrics only.

## `includeReplies` (type: `boolean`):

Include recent posts identified as replies.

## `includeRetweets` (type: `boolean`):

Include recent posts identified as reposts.

## `trackGrowth` (type: `boolean`):

Compare this run with the previous matching monitor run. Adds follower growth, posting pace, changed fields, and actionable signals.

## `monitorName` (type: `string`):

Stable name for this watchlist, for example US AI competitors. Use the same name on scheduled runs to preserve its comparison history.

## `observationHistoryLimit` (type: `integer`):

Number of recent observations retained for each profile in this monitor. History is bounded to control storage.

## `dataSource` (type: `string`):

Auto uses your official X API token when supplied; otherwise it reads the public profile page without login. Choose API to require official API data.

## `xApiBearerToken` (type: `string`):

Optional secret token from your X developer account. It is never saved in results or logs.

## `proxyConfiguration` (type: `object`):

Optional fallback for public-page requests. Direct access is tried first to control cost; a configured proxy is used only for one retry after direct access fails.

## Actor input object example

```json
{
  "usernames": [
    "openai"
  ],
  "maxTweetsPerProfile": 5,
  "includeReplies": false,
  "includeRetweets": false,
  "trackGrowth": true,
  "monitorName": "default",
  "observationHistoryLimit": 30,
  "dataSource": "auto",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `profiles` (type: `string`):

Default dataset items containing profile metrics, nested recent posts, engagement summaries, and growth fields.

## `monitoringReport` (type: `string`):

Run-level coverage, tracking states, signals, and profile comparison rows.

## `monitoringCsv` (type: `string`):

Spreadsheet-ready growth and change report with formula-injection protection.

## `runSummary` (type: `string`):

Saved/failed profile counts plus concise per-profile failure reasons.

# 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 = {
    "usernames": [
        "openai"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fascinating_lentil/twitter-x-profile-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 = { "usernames": ["openai"] }

# Run the Actor and wait for it to finish
run = client.actor("fascinating_lentil/twitter-x-profile-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 '{
  "usernames": [
    "openai"
  ]
}' |
apify call fascinating_lentil/twitter-x-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fascinating_lentil/twitter-x-profile-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/sKZNYaneliCJDMMsu/builds/UiuI72G086NCnnHUV/openapi.json
