# X (Twitter) Scraper (`mscraper/x-scraper`) Actor

Collect public X (Twitter) profiles and content with structured exports, grouped input and bounded API usage. Provider access included.

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

## Pricing

from $0.23 / 1,000 timeline/list 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) Scraper

Collect public X (Twitter) data into a structured Apify dataset. Export JSON, CSV, Excel or JSONL from the dataset. Managed provider access is included; customers do not supply API keys.

Provider access is included; no provider API key is required in input.

### Quick start

```json
{
    "mode": "profiles",
    "profiles": ["NASA"],
    "maxItems": 1,
    "maxRequests": 2
}
```

Choose a mode, supply only the matching source field, set result/request caps, and run. Empty profiles input in the default profile mode uses the example account. Clear the prefilled profiles when switching to other source types.

### Collection modes

| Mode           | Collects            | Source field | Pagination      |
| -------------- | ------------------- | ------------ | --------------- |
| `profiles`     | Profiles            | `profiles`   | Single response |
| `profilesById` | Profiles by ID      | `userIds`    | Single response |
| `posts`        | Profile posts       | `profiles`   | Yes             |
| `media`        | Profile media posts | `profiles`   | Yes             |
| `likes`        | Liked posts         | `profiles`   | Yes             |
| `followers`    | Followers           | `profiles`   | Yes             |
| `following`    | Following           | `profiles`   | Yes             |
| `postsByUrl`   | Posts by URL or ID  | `postUrls`   | Single response |
| `postDetails`  | Post detail         | `postUrls`   | Single response |
| `likers`       | Post likers         | `postUrls`   | Yes             |
| `reposters`    | Post reposters      | `postUrls`   | Yes             |
| `listPosts`    | List posts          | `listIds`    | Yes             |
| `followerIds`  | Follower IDs        | `userIds`    | Yes             |
| `followingIds` | Following IDs       | `userIds`    | Yes             |
| `trends`       | Trends              | `locations`  | Single response |

### Output

Every row includes an exact string ID, data type, source, URL, username, display name, text, timestamp and available counts. Unavailable values are `null`, not invented zeroes. `mediaUrls` contains links; files are not downloaded. `includeRaw` adds the original record. IDs are never converted to floating point numbers. The `OUTPUT` key-value record contains counts, stop reason, requests, estimated weighted units, retries and warnings.

Rows are deduplicated by type + ID across sources. If the same item appears in multiple sources, the first source is retained. A run can stop with `item-limit`, `request-budget`, `charge-limit`, or `usage-limit`; it may contain partial results. Provider failures mark the run failed while preserving saved data. Aborted runs record their summary.

### Pricing

| Operation modes                                                                | USD / 1,000 saved results | Reference                                                         |
| ------------------------------------------------------------------------------ | ------------------------: | ----------------------------------------------------------------- |
| `posts`, `media`, `likes`, `listPosts`                                         |                     0.225 | Kaito tweets, Free plan                                           |
| `profiles`, `profilesById`                                                     |                      3.96 | API Dojo user scraper: $0.004 profile query + $0.0004 result      |
| `postsByUrl`, `postDetails`                                                    |                      0.81 | Axery post detail, Free plan (excluding start fee)                |
| `followers`, `following`, `likers`, `reposters`, `followerIds`, `followingIds` |                     0.135 | Kaito followers/following; adjacent modes use the same group rate |
| `trends`                                                                       |                      0.36 | Karamelo trends, Free plan                                        |

Each saved record triggers exactly one operation event. **$1.00 per 1,000 empty-check units** applies only to validated successful empty responses, including configured endpoint weights. No start fee. Errors, malformed data, duplicates and filtered records do not create empty fees. Lookups used to resolve usernames are not separately charged.

Prices are fixed across Apify plans and are at most 10% below the named comparator's baseline result rate, as checked on September 28, 2026. This compares result rates, not total invoices: competitors may have extra start/query fees or paid-plan discounts. Adjacent operations use the stated group rate, not a claim of an exact feature match.

Set a maximum run charge as well as request and result caps. A request may return many rows; the request cap includes lookups and retries. Endpoint weights default to one pending metering reconciliation. Provider access is included; see the Apify pricing configuration for platform usage billing.

### Limitations

X keyword search is not available in this provider API. Likes, likers and reposters can be restricted by X and returned empty; emptiness is not evidence of no activity. Post detail exports the requested post; it does not expand the replies array. Some provider endpoints ignore count, so limits are enforced locally.

Only public, provider-accessible data is supported. There is no login, access to private accounts, deleted-content recovery, or content download. No short-link resolution. No guarantees of complete history or exhaustive follower lists; provider pagination and availability control coverage.

### Local development

Node 22 or newer and Redis (for integration tests):

```sh
npm ci
npm run check
npm run publication:check
node --env-file=.env --import tsx src/main.ts
```

Copy `INPUT.example.json` to `storage/key_value_stores/default/INPUT.json` for local input. `.env` and `samples/raw/` are ignored. Required owner configuration: `RAPIDMINE_API_KEY`; cloud runs additionally require Redis URL or Upstash REST URL/token. Local runs use the request cap and per-process rate; shared cloud usage counters are enforced on Apify. Never commit credentials or put them in the actor input.

The shared provider cap is 90,000 weighted units per internal 30-day guard window, with at most 60 requests per minute across all runs; paid user cap 1,000/day, free user 3/window and shared free pool 10/window. These internal windows start on first use and do not mirror provider billing dates. Unknown/free status uses the conservative free allowance. Redis errors stop calls before provider access.

### Monitoring and deployment

`PROVIDER_MONITOR_URL` and `PROVIDER_MONITOR_TOKEN` optionally publish usage observations to the local dashboard collector. Cloud actors require a reachable collector URL; localhost on your laptop is not reachable from Apify. Monitoring failure does not fail a scrape.

See `publication/READINESS.md`, `publication/PUBLISH.md` and `docs/CONTRACTS.md` for verification evidence and release details.

### Related scrapers for brand and audience research

Combine public X posts and profiles with other sources when researching a brand, creator or topic.

- [TikTok Scraper](https://apify.com/mscraper/tiktok-scraper) — Collect video metadata, creator profiles and comments to compare social content and engagement.
- [Reddit Scraper](https://apify.com/mscraper/reddit-scraper) — Search Reddit posts and retrieve comments to explore longer discussions around the same topic.
- [Similarweb Quick Scraper](https://apify.com/mscraper/similarweb-quick-scraper) — Add estimated website traffic, traffic sources and geographic reach for relevant domains.

Run each Actor separately and combine its exported data in your own workflow. Each Actor has its own input, output and pricing.

# Actor input Schema

## `mode` (type: `string`):

Choose which public data to collect. Fill only the source field used by the selected mode.

## `profiles` (type: `array`):

Used by: Profiles, Profile posts, Profile media posts, Liked posts, Followers, Following. Up to 100 sources. Leave empty in other modes.

## `userIds` (type: `array`):

Used by: Profiles by ID, Follower IDs, Following IDs. Up to 100 sources. Leave empty in other modes.

## `postUrls` (type: `array`):

Used by: Posts by URL or ID, Post detail, Post likers, Post reposters. Up to 100 sources. Leave empty in other modes.

## `listIds` (type: `array`):

Used by: List posts. Up to 100 sources. Leave empty in other modes.

## `locations` (type: `array`):

Used by: Trends. Up to 100 sources. Leave empty in other modes.

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

Global cap across all sources. Provider page sizes may be larger; only saved results are billed.

## `maxItemsPerSource` (type: `integer`):

Maximum saved records from each source. The global result limit still applies.

## `maxRequests` (type: `integer`):

Includes username lookups and retries. Successful empty checks are billed separately; malformed responses and provider errors are not empty checks.

## `requestsPerMinute` (type: `integer`):

The shared provider limiter may enforce a lower rate.

## `maxRetries` (type: `integer`):

Retries consume API quota and the request budget. Off by default.

## `includeRaw` (type: `boolean`):

Adds the original per-record payload. It can be large and contain additional public profile fields.

## Actor input object example

```json
{
  "mode": "profiles",
  "profiles": [
    "NASA"
  ],
  "userIds": [],
  "postUrls": [],
  "listIds": [],
  "locations": [],
  "maxItems": 20,
  "maxItemsPerSource": 100,
  "maxRequests": 10,
  "requestsPerMinute": 30,
  "maxRetries": 0,
  "includeRaw": false
}
```

# Actor output Schema

## `dataset` (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 = {
    "profiles": [
        "NASA"
    ]
};

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

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

```

## MCP server setup

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