# X (Twitter) Post Scraper (`scraper_creator/x-twitter-post-scraper`) Actor

Collect X/Twitter profile posts, engagement metrics and author follower counts using your own login session. Supports pagination and excludes replies and retweets. Login cookies are required.

- **URL**: https://apify.com/scraper_creator/x-twitter-post-scraper.md
- **Developed by:** [Scraper Creator](https://apify.com/scraper_creator) (community)
- **Stats:** 1 total users, 1 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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) Post Statistics

Experimental Actor for collecting public profile posts, engagement metrics, and author follower counts using an operator-managed login session. Supply profile URLs and limits; no login credentials are needed in your input.

### How to use

1. Add 1–100 public X/Twitter profile URLs under **Profile URLs**, such as `https://x.com/NASA`.
2. Set **Total post limit** (`maxItems`, default 100, range 1–10,000). This limit is shared across all profiles, not applied separately to each one. Start with one profile to avoid leaving later profiles unattempted.
3. Leave **Optional proxy** unset unless you need a custom configuration. No proxy is selected automatically; proxy collection has not been validated.
4. Start the Actor. The operator must already have configured a valid login session; ordinary input contains only target URLs and options, not credentials.
5. Check the run status and `RUN-SUMMARY`, then export the dataset or retrieve it through the Apify API. A skipped profile makes the run fail, even if earlier rows were returned.

Replies and retweets are excluded. Pinned posts may be included, and the feed is not guaranteed to be strictly chronological. Search and individual post URLs are not supported.

### Input

Run memory defaults are managed in Apify Console under Actor Settings. The source does not declare `defaultMemoryMbytes`; explicit run, task, or API memory settings can override the cloud default. Memory is a run option, not an input JSON field.

#### Example

```json
{
  "startUrls": ["https://x.com/NASA"],
  "maxItems": 100
}
```

#### Fields

| Field | Required | Description |
| --- | --- | --- |
| `startUrls` | Yes | Array of 1–100 HTTPS X/Twitter profile URLs, as strings or objects containing `url`. |
| `maxItems` | No | Total output limit across all profiles, from 1 to 10,000; default 100. |
| `proxyConfiguration` | No | Optional Apify proxy configuration, with one sticky session per profile. |

Use `x.com`, `www.x.com`, `twitter.com`, or `www.twitter.com` without query parameters or fragments. Bare usernames and `/status/` links are not accepted.

### Output

Each row is one post. Text preserves long-form content and line breaks when supplied by X.

#### Example

The following is a synthetic example, not live statistics:

```json
{
  "id": "1234567890123456789",
  "url": "https://x.com/example/status/1234567890123456789",
  "inputUrl": "https://x.com/example",
  "fullText": "First line\nSecond line #test",
  "text": "First line\nSecond line #test",
  "createdAt": "2026-10-19T00:00:00.000Z",
  "isReply": false,
  "isRetweet": false,
  "likeCount": 0,
  "replyCount": 2,
  "retweetCount": 3,
  "quoteCount": 1,
  "bookmarkCount": 0,
  "viewCount": 100,
  "author": {
    "id": "123",
    "userName": "example",
    "followers": 42
  },
  "entities": {
    "hashtags": [
      {
        "text": "test"
      }
    ]
  },
  "scrapedAt": "2026-10-19T14:38:02.670Z"
}
```

#### Fields

| Field | Description |
| --- | --- |
| `id`, `url`, `inputUrl` | String post ID, canonical post URL, and requested profile. |
| `fullText`, `text`, `createdAt`, `entities.hashtags` | Post text, publication time, and hashtags. |
| `isReply`, `isRetweet` | Boolean flags; replies and retweets are excluded. |
| `author.id`, `author.userName`, `author.followers` | Author identity and current follower count. |
| `likeCount`, `replyCount`, `retweetCount`, `quoteCount`, `bookmarkCount`, `viewCount` | Public engagement metrics. |
| `scrapedAt` | Collection time. |

#### Data accuracy

Missing metrics remain `null`; confirmed zero remains `0`. Counts are snapshots and can change after the run.

### Viewing and exporting results

Open the run's dataset to view one row per returned post. Export JSON to preserve the nested `author` object and hashtag arrays, or use a tabular export for spreadsheet analysis. API integrations can retrieve the run's default dataset items.

Open `RUN-SUMMARY` in the run's default key-value store. Check every requested profile, unattempted targets, and `limitReached` before treating the output as a complete snapshot. Use successful runs only; rows may remain after a failed run.

### Pricing

Check the Actor page for current prices. In pay-per-event runs, each returned result is billable. Proxy usage may add separate charges. Results delivered before a failure or budget stop may already be charged; a failed run does not mean no cost.

### Limits and failures

- **The 10,000-post maximum is shared across all profiles.** If the limit leaves any profile unattempted, the run fails. A profile reaching the limit is recorded as `limitReached`, not as full historical coverage.
- All runs use the operator-configured login session. You do not need to provide passwords or cookies and cannot override the session through input. Expired sessions, account checks, and rate limits stop collection; the operator must renew the session when needed.
- Inaccessible profiles, malformed data, stalled pagination, and output failures fail the run. Earlier rows may remain; import successful runs only and check requested-profile coverage in `RUN-SUMMARY`.
- Budget exhaustion that prevents completion fails the run with `stopReason: MAX_TOTAL_CHARGE_REACHED` and `partial: true`.
- Search, direct-post refresh, standalone follower collection, and other post filters are not supported. Login does not guarantee access to all historical posts.

### Refreshing statistics

Start a new run with the same profile URLs and a fresh dataset. The Actor reads the profile feed again up to the shared `maxItems` limit. Older posts outside that scope are not refreshed, and direct-post refresh is not supported. Follower totals are attached to posts; there is no standalone follower mode.

For API compatibility and operator setup, see [DEVELOPMENT.md](DEVELOPMENT.md).

# Changelog

This Actor's version history is a separate document: https://apify.com/scraper_creator/x-twitter-post-scraper/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

HTTPS x.com or twitter.com profile URLs. No search or individual post URLs.

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

Shared across all profiles. Targets skipped due to the limit make the run fail.

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

One sticky session per profile. Proxy collection has not been validated.

## Actor input object example

```json
{
  "maxItems": 100
}
```

# Actor output Schema

## `posts` (type: `string`):

No description

## `summary` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper_creator/x-twitter-post-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 = {}

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

```

## MCP server setup

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