# Twitter (X) Profile & Tweets Scraper (`memo23/twitter-x-scraper`) Actor

Scrape Twitter (X) profiles and individual tweets — no login, no API key. Get clean, structured data: full text, likes, retweets, replies, views, author profile, follower counts, media and entities. Mix profile URLs and tweet links in one run. Export to JSON, CSV, Excel or API

- **URL**: https://apify.com/memo23/twitter-x-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, AI, Agents
- **Stats:** 59 total users, 23 monthly users, 99.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 tweet scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Twitter / X Profile & Tweets Scraper 🐦

**Ask for 500 tweets and get 500.** This scraper pages through the whole timeline, honours a date
range, returns view counts, keeps retweets and replies with the parent tweet attached, and never
bills you twice for the same tweet — the things X scrapers most often get wrong.

Scrape any **Twitter (X)** profile's tweets — fast, no login, no API keys. Paste one or more X
profile URLs (or bare handles) and get back clean, structured records: full tweet text, engagement
metrics, author details, media, and entities. Built on X's public endpoints, so it's quick and the
output drops straight into your app, sheet, or database.

![How the Twitter (X) Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-x.png)

***

### What you can scrape

- **Profile timelines** — a user's tweets, e.g. `https://x.com/nasa` (or just `nasa`)
- **Individual tweets** — paste a tweet URL, e.g. `https://x.com/Twitter/status/20`
- For each tweet: full text, engagement counts, media, and the author's profile data

Mix profile URLs and tweet URLs in one run. No authentication, no cookies, no API token required.

**Filter as you scrape** — set **Only tweets after** / **Only tweets before** to pull just a date
window, and switch **Include retweets** or **Include replies** off for original posts only. Because
a timeline is newest-first, the scraper stops paging the moment it walks past your start date, so a
narrow window costs a fraction of a full run.

> Keyword **search** and **follower/following** lists are not part of this actor — those require a
> logged-in X account. Profiles and individual tweets work with no login at all.

***

### Data you get per tweet

**Tweet:** id, url, full text, language, created date, source, reply/quote/retweet flags, quoted-tweet id.

**Engagement:** view count (impressions), like count, retweet count, reply count, quote count, bookmark count.

**Threading:** `inReplyToId`, `inReplyToUserId` and `inReplyToUsername` on every reply, so you can
rebuild a conversation without a second pass.

**Nested tweets:** a retweet carries the original expanded under `retweetedTweet`; a quote tweet
carries the quoted one under `quote`.

**Author:** username, display name, id, bio, location, follower & following counts, verified /
blue-verified status, profile + banner image, account-created date, tweet/media/likes counts.

**Media & entities:** image and video URLs, cards, hashtags, mentions, URLs.

Clean, flat records by default. Need the raw X GraphQL object too? Flip on **Include raw data** and
each record carries the full payload under `otherData`.

***

### How to use it

1. Put one or more X profile URLs (or `@handles`) in **Start URLs**.
2. Set **Max items** to cap how many tweets you collect.
3. Run it, then download as JSON / CSV / Excel, or pull via the Apify API.

#### Example input

```json
{
  "startUrls": [
    "https://x.com/nasa",
    "elonmusk",
    "https://x.com/Twitter/status/20"
  ],
  "maxItems": 100
}
```

***

### Input parameters

| Field | Type | Description |
|---|---|---|
| **Start URLs** | array | X profile URLs, bare handles like `nasa`, or individual tweet URLs (`.../status/<id>`). |
| **Max items** | integer | Cap on tweets collected across all profiles. |
| **Include raw data** | boolean | Add the full raw X GraphQL object as `otherData` per record. Off by default (clean output). |
| **Max concurrency** | integer | Parallel requests. |
| **Proxy** | object | Proxy configuration (residential recommended). |

***

### Example output

```json
{
  "type": "tweet",
  "id": "2067746088296038531",
  "url": "https://x.com/NASA/status/2067746088296038531",
  "text": "What a great moment! …",
  "lang": "en",
  "createdAt": "Thu Jun 18 23:07:38 +0000 2026",
  "retweetCount": 260,
  "replyCount": 38,
  "likeCount": 980,
  "quoteCount": 12,
  "bookmarkCount": 44,
  "isReply": false,
  "isRetweet": false,
  "isQuote": false,
  "source": "Twitter for iPhone",
  "media": [],
  "author": {
    "userName": "NASA",
    "name": "NASA",
    "id": "11348282",
    "followers": 92118329,
    "following": 198,
    "isVerified": true,
    "isBlueVerified": true,
    "description": "There's space for everybody.",
    "location": "",
    "profilePicture": "https://pbs.twimg.com/profile_images/.../...jpg"
  }
}
```

***

### Popular use cases

- **Competitor & influencer monitoring** — track any account's tweets, engagement, and follower counts
- **Brand & campaign tracking** — pull a brand account's timeline over time
- **Engagement analytics** — benchmark posts and accounts
- **Datasets for ML/AI** — clean tweet corpora for training or analysis
- **Journalism & academic research** — reproducible, citation-friendly data pulls

***

### Export & integrate

Download results as **JSON, CSV, Excel, or HTML**, or pull via the **Apify API**. Schedule runs to
keep data fresh, and connect to Make, Zapier, n8n, Google Sheets, and more.

***

### FAQ

**Do I need a Twitter/X account or API key?**
No — it uses X's public endpoints. No login, no cookies, no developer API.

**What do I give it as input?**
X profile URLs (e.g. `https://x.com/nasa`), bare handles (e.g. `nasa`), or individual tweet URLs
(e.g. `https://x.com/Twitter/status/20`). Add as many as you like.

**Can I mix profiles and single tweets in one run?**
Yes — put any combination of profile URLs/handles and tweet URLs in Start URLs.

**Does it do keyword search or follower lists?**
No — those require a logged-in X account, so they're out of scope for this no-login actor.

**Is the output clean or raw?**
Clean flat records by default (~22 fields). Toggle **Include raw data** for the full raw object too.

**Why use a proxy?**
X rate-limits by IP. A residential proxy keeps runs reliable at volume.

**How current is the data?**
Live — pulled from X at run time, not a pre-built database.

***

### 💬 Support

Questions, a bug, or a field you need added? Email **muhameddidovic@gmail.com** or open an issue on
the actor's Apify page.

***

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/twitter-x-scraper`).

**Purpose:** Scrape Twitter (X) profile timelines and individual tweets from X's public endpoints — clean flat records with engagement metrics, author details, and media, no login required.

**Minimal input:**

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

**Output:** one row per tweet — type, id, url, text, lang, createdAt, source, retweetCount, replyCount, likeCount, quoteCount, bookmarkCount, isReply, isRetweet, isQuote, media, author {userName, name, id, followers, following, isVerified, isBlueVerified, description, location, profilePicture}.

**Behaviors an agent should know:**

- Always set `maxItems` — it caps tweets/profiles across all start URLs; default is 1000, so an uncapped profile run can be large.
- `startUrls` accepts profile URLs, bare handles (`nasa`), and individual tweet URLs (`.../status/<id>`) mixed in one run.
- Keyword search and follower/following lists are not supported — they require a logged-in X account.
- `includeRawData: true` adds the full raw X GraphQL object under `otherData` per record (off by default for compact output).
- Use a residential proxy (schema default) — X rate-limits by IP.
- Pay-per-event billing — see the Pricing tab on the actor page.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by X Corp.
(Twitter), or any of its subsidiaries or affiliates. All trademarks mentioned are the property of
their respective owners.

The scraper accesses only publicly available tweets and profiles — no authenticated endpoints,
private accounts, or content behind a login. Users are responsible for ensuring their use complies
with X's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual
obligations of their own organisation.

***

### SEO Keywords

twitter scraper, x scraper, x.com scraper, twitter profile scraper, x profile scraper, scrape tweets, tweet scraper, twitter timeline scraper, twitter api, twitter data extraction, tweet data api, twitter followers data, no-auth twitter scraper, social media scraper, twitter analytics scraper, twitter engagement data, apify twitter

# Actor input Schema

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

X profile URLs or bare handles (e.g. `https://x.com/nasa` or `nasa`), and/or individual tweet URLs (e.g. `https://x.com/Twitter/status/20`). You can mix profiles and tweets in one run. Optional if you supply Tweet IDs instead. Keyword search and follower lists are not supported (they need a logged-in account).

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

Bare numeric tweet ids to fetch, e.g. 20. Use this instead of building https://x.com/i/status/<id> URLs by hand. Combined with Start URLs when both are given.

## `maxConcurrency` (type: `integer`):

Maximum number of pages that can be processed at the same time.

## `minConcurrency` (type: `integer`):

Minimum number of pages that will be processed at the same time.

## `maxRequestRetries` (type: `integer`):

Number of times the crawler will retry a failed request before giving up. Each retry is billed for the full time it waits, so this is capped at 5.

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

Maximum number of tweets/profiles to scrape across all start URLs.

## `onlyTweetsAfter` (type: `string`):

Keep only tweets posted on or after this date. Accepts YYYY-MM-DD or a full ISO timestamp. Because a profile timeline is newest-first, the scraper stops paging as soon as it walks past this date.

## `onlyTweetsBefore` (type: `string`):

Keep only tweets posted before this date. Accepts YYYY-MM-DD or a full ISO timestamp.

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

Keep retweets in the output. Retweets carry the original tweet expanded under retweetedTweet. Turn off for original posts only.

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

Keep replies in the output. Replies carry inReplyToId, inReplyToUserId and inReplyToUsername so you can thread them.

## `includeRawData` (type: `boolean`):

When enabled, each record also includes the full raw X GraphQL object under `otherData`. Off by default for clean, compact output.

## `proxy` (type: `object`):

Proxy servers used to hide the scraper's origin. Leave as Apify Proxy (automatic) unless you have a reason to change it — pinning a specific group such as RESIDENTIAL means the run is rejected outright if that group is unavailable to the account paying for it. You can still select RESIDENTIAL here if you want it.

## Actor input object example

```json
{
  "startUrls": [
    "https://x.com/nasa",
    "https://x.com/Twitter/status/20"
  ],
  "tweetIds": [],
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 5,
  "maxItems": 1000,
  "includeRetweets": true,
  "includeReplies": true,
  "includeRawData": false,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# 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": [
        "https://x.com/nasa",
        "https://x.com/Twitter/status/20"
    ],
    "tweetIds": [],
    "onlyTweetsAfter": "",
    "onlyTweetsBefore": "",
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/twitter-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 = {
    "startUrls": [
        "https://x.com/nasa",
        "https://x.com/Twitter/status/20",
    ],
    "tweetIds": [],
    "onlyTweetsAfter": "",
    "onlyTweetsBefore": "",
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/twitter-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 '{
  "startUrls": [
    "https://x.com/nasa",
    "https://x.com/Twitter/status/20"
  ],
  "tweetIds": [],
  "onlyTweetsAfter": "",
  "onlyTweetsBefore": "",
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call memo23/twitter-x-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/twitter-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/8GfRQh3MTYMiPWgqI/builds/Lwe5V8NFpfDw3GxxZ/openapi.json
