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

Scrapes public X (Twitter) profiles and tweets: follower, following and post counts, bios, recent tweets with engagement, media, hashtags and links — from profile URLs, handles or tweet IDs.

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

## Pricing

from $2.50 / 1,000 results

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

![banner](https://anyx.solutions/banners/x-twitter-scraper.png)

## X (Twitter) Scraper

**Turn public X (Twitter) profiles and posts into structured data — followers, bios, recent tweets, engagement and media.**

The X (Twitter) Scraper reads public [X](https://x.com) profile pages and individual posts and returns clean JSON: account bios, follower/following/post counts, join dates, plus each account's most recent tweets with like, repost and reply counts, language, media, hashtags, mentions and links. Feed it profile URLs, handles or tweet IDs — no login, no API keys. Built for brand monitoring, influencer research, competitive analysis and social-listening pipelines.

### ⚡ Quick start

```json
{
  "startUrls": [{ "url": "https://x.com/vercel" }, { "url": "https://x.com/vercel/status/1683920951807971329" }],
  "maxItems": 5
}
```

Handles and tweet IDs work without URLs:

```json
{
  "handles": ["nasa", "@vercel"],
  "tweetIds": ["1683920951807971329"],
  "maxItems": 5
}
```

### 🧩 Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `startUrls` | array | no | — | Public X (Twitter) profile or tweet URLs, e.g. `https://x.com/vercel` or `https://x.com/vercel/status/1683920951807971329`. `twitter.com` links work too. |
| `handles` | array | no | — | Account handles to scrape as profiles, with or without the `@`. Each handle counts as its own start URL. |
| `tweetIds` | array | no | — | Numeric tweet IDs to scrape individually. Full status URLs are accepted as well. |
| `maxItems` | integer | no | `5` | Maximum number of items (the profile plus its recent tweets) per start URL, handle or tweet ID. |
| `proxyConfiguration` | object | no | `{ "useApifyProxy": false }` | Apify proxy settings used for the run. Public pages load without a proxy by default. |

At least one of `startUrls`, `handles` or `tweetIds` must be provided.

### 📤 Output

Every dataset item carries an `itemType` of `profile` or `tweet`. A profile URL or handle yields one `profile` item followed by the account's most recent tweets as `tweet` items (up to `maxItems` in total). A tweet URL or ID yields a single `tweet` item. Missing values are `null`.

#### Fields

| Field | Type | Description |
|---|---|---|
| `itemType` | string | `profile` or `tweet`. |
| `id` | string | Profile: opaque account ID. Tweet: the numeric tweet ID. |
| `rest_id` | string | Profile only — numeric account ID. |
| `name` | string | Profile only — display name. |
| `screen_name` | string | Profile only — handle without the `@`. |
| `description` | string | Profile only — bio text. |
| `location` | string | Profile only — free-text location from the bio. |
| `website` | string | Profile only — website link from the bio. |
| `profile_image_url` | string | Profile only — avatar image URL. |
| `created_at` | string | ISO 8601 date the account joined (profile) or the tweet was posted (tweet). |
| `followers_count` | number | Profile only — follower count. |
| `friends_count` | number | Profile only — number of accounts followed. |
| `statuses_count` | number | Profile only — total number of posts. |
| `url` | string | Canonical `x.com` URL of the profile or tweet. |
| `text` | string | Tweet only — full post text. |
| `lang` | string | Tweet only — ISO language code detected by X. |
| `reply_count` | number | Tweet only — number of replies. |
| `retweet_count` | number | Tweet only — number of reposts. |
| `favorite_count` | number | Tweet only — number of likes. |
| `view_count` | number | Tweet only — view count when X exposes it, otherwise `null`. |
| `isReply` | boolean | Tweet only — `true` when the post replies to another post. |
| `inReplyToId` | string | Tweet only — ID of the post being replied to. |
| `quotedTweetId` | string | Tweet only — ID of the quoted post, if any. |
| `media` | array | Tweet only — attached media as `{ type, url, width, height }` where `type` is `photo` or `video`. |
| `hashtags` | array | Tweet only — hashtags without the `#`. |
| `mentions` | array | Tweet only — mentioned handles without the `@`. |
| `urls` | array | Tweet only — expanded links in the post. |
| `user` | object | Tweet only — author as `{ id, name, screen_name, url, profile_image_url, verified }`. |

<details><summary>Example output</summary>

```json
[
  {
    "itemType": "profile",
    "id": "VXNlcjo0Njg2ODM1NDk0",
    "rest_id": "4686835494",
    "name": "Vercel",
    "screen_name": "vercel",
    "description": "Agentic Infrastructure for apps and agents.",
    "location": null,
    "website": "https://vercel.com",
    "profile_image_url": "https://pbs.twimg.com/profile_images/1767351110228918272/3Pndc5OT_400x400.png",
    "created_at": "2016-01-01T03:49:12.000Z",
    "followers_count": 450619,
    "friends_count": 10,
    "statuses_count": 1929,
    "url": "https://x.com/vercel"
  },
  {
    "itemType": "tweet",
    "id": "1683920951807971329",
    "url": "https://x.com/vercel/status/1683920951807971329",
    "text": "Introducing `react-tweet`:\n\n◆ 35x less client-side JavaScript than the Twitter <iframe>\n◆ React Server Components for built-in data fetching\n◆ Works with Next.js, Vite, CRA, and more\n\nhttps://t.co/CMH9A1IGjV",
    "created_at": "2023-07-25T19:23:35.000Z",
    "lang": "en",
    "reply_count": 67,
    "retweet_count": null,
    "favorite_count": 1709,
    "view_count": null,
    "isReply": false,
    "inReplyToId": null,
    "quotedTweetId": null,
    "media": [],
    "hashtags": [],
    "mentions": [],
    "urls": ["https://vercel.com/blog/introducing-react-tweet"],
    "user": {
      "id": "4686835494",
      "name": "Vercel",
      "screen_name": "vercel",
      "url": "https://x.com/vercel",
      "profile_image_url": "https://pbs.twimg.com/profile_images/1767351110228918272/3Pndc5OT_normal.png",
      "verified": true
    }
  }
]
```

</details>

### 💡 Use cases

- **Brand and competitor monitoring** — track follower growth and what competitor accounts post, on a schedule.
- **Influencer research** — pull bios, audience size and recent engagement for a list of handles in one run.
- **Social listening** — archive specific posts with their like, repost and reply counts as they evolve.
- **Content analytics** — collect an account's recent tweets with media, links and hashtags for reporting.
- **Lead enrichment** — attach website, location and audience size to a list of X handles.

### ❓ FAQ

- **Does it need an X account or API key?** No. It reads only what X serves publicly to logged-out visitors.
- **Can it scrape a full timeline, search results or hashtags?** No. X shows logged-out visitors a profile's roughly 20 most recent posts; search, hashtag pages, replies, likes and followers lists require a login and are not supported.
- **Why does a profile return fewer tweets than `maxItems`?** `maxItems` covers the profile item plus its recent tweets, and X exposes at most ~20 recent posts per account publicly. Protected (private), suspended and post-less accounts have no public timeline and return no items.
- **Why is `view_count` often `null`?** X exposes view counts only on some server-rendered pages; when they are not available the field is `null` rather than a guess.
- **Which URLs are supported?** `https://x.com/<handle>` (also `twitter.com`) and `https://x.com/<handle>/status/<id>`. Anything else is rejected at start.
- **Do I need a proxy?** Not by default. If runs start failing with blocked responses, enable Apify Proxy in `proxyConfiguration`.

### 🔗 More scrapers by Anyx

- [Bluesky Scraper](https://apify.com/anyxsolutions/bluesky-scraper)
- [Threads Scraper](https://apify.com/anyxsolutions/threads-scraper)
- [Reddit Scraper](https://apify.com/anyxsolutions/reddit-scraper)
- [TikTok Trending Hashtags Scraper](https://apify.com/anyxsolutions/tiktok-trending-hashtags-scraper)
- [YouTube Channel Scraper](https://apify.com/anyxsolutions/youtube-channel-scraper)

### 🤝 Anyx Solutions

We build custom scrapers and data-extraction pipelines.

- Email: tantosthor@gmail.com

# Actor input Schema

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

Public X (Twitter) profile or tweet URLs, for example https://x.com/vercel or https://x.com/vercel/status/1683920951807971329. twitter.com links work too.

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

Account handles to scrape as profiles, with or without the @ sign, for example nasa or @vercel. Each handle counts as its own start URL.

## `tweetIds` (type: `array`):

Numeric tweet (post) IDs to scrape individually, for example 1683920951807971329. Full status URLs are accepted as well.

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

Maximum number of items (the profile plus its recent tweets) to return per start URL, handle or tweet ID.

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

Apify proxy settings used for the run. Public pages load without a proxy by default.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://x.com/vercel"
    },
    {
      "url": "https://x.com/nasa"
    }
  ],
  "handles": [],
  "tweetIds": [],
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        {
            "url": "https://x.com/vercel"
        },
        {
            "url": "https://x.com/nasa"
        }
    ],
    "handles": [],
    "tweetIds": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("anyxsolutions/x-twitter-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 = {
    "startUrls": [
        { "url": "https://x.com/vercel" },
        { "url": "https://x.com/nasa" },
    ],
    "handles": [],
    "tweetIds": [],
}

# Run the Actor and wait for it to finish
run = client.actor("anyxsolutions/x-twitter-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 '{
  "startUrls": [
    {
      "url": "https://x.com/vercel"
    },
    {
      "url": "https://x.com/nasa"
    }
  ],
  "handles": [],
  "tweetIds": []
}' |
apify call anyxsolutions/x-twitter-scraper --silent --output-dataset

```

## MCP server setup

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