# Twitter Profile Scraper: Pinned Tweet Details (`simpleapi/twitter-profile-scraper`) Actor

Twitter Profile Scraper extracts detailed data from any public X (Twitter) profile, including bio, followers/following counts, profile image, join date, location, website, and recent tweet metadata. Ideal for research, influencer analysis, audience insights, and automated profile data collection.

- **URL**: https://apify.com/simpleapi/twitter-profile-scraper.md
- **Developed by:** [SimpleAPI](https://apify.com/simpleapi) (community)
- **Categories:** Automation, Lead generation, Social media
- **Stats:** 57 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$19.99/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period.You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#rental-actors

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

### X Scraper — Tweets, Thread Reconstruction and Quote Context

Twitter Profile Scraper: Pinned Tweet Details scrapes tweets from any public X (Twitter) profile and reconstructs the conversation context around them — full quoted-tweet content resolved inline, and the author's own multi-tweet threads clustered into order — all without logging in for the base scrape. It's built for content researchers, social listening teams, and anyone who needs to read a thread top-to-bottom or see exactly what a quote-tweet is reacting to, not just a flat list of disconnected tweets.

### What is Twitter Profile Scraper: Pinned Tweet Details?

Twitter Profile Scraper: Pinned Tweet Details is an Apify Actor that scrapes a profile's tweets and derives thread and quote-tweet structure from data already fetched in the same response — no extra requests for either feature. No X login is required for the base tweet capture; login cookies are only needed if you enable reply fetching. One honest note on the name: despite "Pinned Tweet Details" in the Actor's title, the current source code has no dedicated pinned-tweet extraction logic — its real, verified differentiators are quote-tweet resolution and self-thread reconstruction, both described below. Key capabilities:

- Capture tweets from one or more profiles by URL or handle
- Resolve every quote-tweet (`is_quote_status: true`) inline into a `quotedTweet{}` object — full text, author, and media — at zero extra request cost
- Cluster the author's own consecutive tweets sharing a `conversation_id_str` into ordered threads (`threadId`, `threadPosition`, `isThreadStart`, `isThreadEnd`), derived only from what was actually captured
- Filter by date range, image-only tweets, and native-retweet inclusion
- Optionally fetch reply context for qualifying tweets (requires login cookies) and emit a profile-about record per user

### What data can I extract with Twitter Profile Scraper: Pinned Tweet Details?

| Field | Example Value | Use Case |
| --- | --- | --- |
| `full_text` / `created_at` | `"Just shipped a new feature..."` / `"2026-07-20T10:00:00.000Z"` | Read the tweet's content and timing |
| `favorite_count` / `retweet_count` / `reply_count` / `quote_count` | `4200` / `380` / `92` / `45` | Core engagement metrics |
| `is_quote_status` / `quotedTweet` | `true` / `{"full_text": "...", "user": {...}}` | See exactly what a quote-tweet is reacting to, resolved inline |
| `threadId` / `threadPosition` / `isThreadStart` / `isThreadEnd` | `"1234567890"` / `2` / `false` / `false` | Reconstruct a multi-tweet thread in order |
| `conversation_id_str` | `"1234567890"` | The raw conversation grouping key behind thread reconstruction |
| `user` / `screen_name` / `is_blue_verified` | profile object / `"elonmusk"` / `true` | Identify the tweet's author |
| `entities` / `extended_entities` | hashtags/mentions/media objects | Full structured tweet content |
| `aboutData` | profile-about object | Profile overview data (opt-in, one record per user) |
| `type` / `isReply` / `parentTweetId` | `"reply"` / `true` / parent tweet ID | Distinguish reply rows when reply context is enabled |

#### Real thread and quote reconstruction, honestly scoped

`quotedTweet` is resolved inline from the same response the base tweet capture already fetched — no extra request, and the quoted tweet's full text, author, and media are genuine, not summarized or guessed. `threadId`/`threadPosition`/`isThreadStart`/`isThreadEnd` cluster the author's own consecutive tweets sharing a `conversation_id_str`, but this is explicitly scoped to what was actually captured in this run — X exposes no thread-depth API, so if `maxTweetsToCapture` cuts off partway through a long thread, the reconstructed thread will honestly reflect only the captured portion, not the full original thread.

#### Date, media, and retweet filtering

`captureStartDate`/`captureEndDate` bound the capture to a date range. `imageTweetsOnly` keeps only tweets with at least one photo. `includeRetweetsInCapture` (off by default) drops native retweets — though this filter is honestly only effective for roughly the last 7-10 days of a profile's timeline, per the actual retweet-detection window in the source.

### Why not build this yourself?

X's official API (v2) gates thread and quote-tweet context behind paid tiers with strict rate limits, and doesn't provide a ready-made self-thread clustering feature at all — you'd need to fetch the full conversation and reconstruct thread order yourself regardless of tier. Building an equivalent tool yourself means implementing that same conversation-clustering logic, plus inline quote-tweet resolution from the same response payload. All of that is already implemented in this Actor's source.

### How to use data extracted from X?

#### Content research and thread curation

Capture a creator's tweets with `reconstructSelfThreads` on to read their threads in proper order without manually piecing together a conversation, using `resolveQuotedTweets` to see full context on any quote-tweet commentary.

#### Social listening and brand monitoring

Track a set of profiles' tweets with `imageTweetsOnly` or a date range to focus on recent visual content, using `quotedTweet` data to see how your brand or product is being quoted and discussed.

#### Market and competitive research

Compare thread structure and quote-tweet activity across competitor profiles to see who's building sustained narrative threads versus one-off posts.

#### AI agents and automated pipelines

An agent can call this Actor to pull a profile's tweet history with thread structure intact, using `threadId`/`threadPosition` to reconstruct and summarize multi-tweet arguments coherently rather than processing disconnected tweets.

### 🔼 Input sample

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `threadTargets` | No (either this or `threadHandles`) | array | Profile URLs to capture | `["https://x.com/elonmusk"]` |
| `threadHandles` | No (either this or `threadTargets`) | array | Usernames without `@` | `["elonmusk"]` |
| `maxTweetsToCapture` | No | integer (min 1) | Hard cap on total items written across the run | `20` (default) |
| `captureStartDate` / `captureEndDate` | No | string (date) | Date-range bounds; empty = no bound | `"7 days"` / `""` |
| `includeRetweetsInCapture` | No | boolean | Include native retweets (effective for ~last 7-10 days) | `false` (default) |
| `imageTweetsOnly` | No | boolean | Keep only tweets with at least one photo | `false` (default) |
| `includeProfileOverview` | No | boolean | Emit one profile-about record per user | `false` (default) |
| `resolveQuotedTweets` | No | boolean | Resolve quote-tweets inline at zero extra cost | `true` (default) |
| `reconstructSelfThreads` | No | boolean | Cluster the author's own tweets into ordered threads | `true` (default) |
| `fetchReplyContext` | No | boolean | Fetch replies via TweetDetail; requires login cookies | `false` (default) |
| `minReplyCountForContext` | No | integer (min 0) | Only fetch replies for tweets above this reply count | `0` (default) |
| `authToken` / `csrfToken` | No (required for reply context) | string | X `auth_token`/`ct0` cookies | `"(your cookies)"` |
| `proxyConfiguration` | No | object | Proxy config for reliability | `{"useApifyProxy": true}` |

```json
{
  "threadTargets": ["https://x.com/elonmusk"],
  "maxTweetsToCapture": 50,
  "resolveQuotedTweets": true,
  "reconstructSelfThreads": true
}
```

**Common pitfall:** `fetchReplyContext` requires both `authToken` and `csrfToken` — without valid login cookies, reply fetching will fail even though the base tweet/thread/quote capture works without any login.

### 🔽 Output sample

Output is typed, normalized JSON — one row per tweet, reply, or profile-about record (exportable as JSON, CSV, or Excel).

```json
{
  "id_str": "1234567890123456789",
  "type": "tweet",
  "isChild": false,
  "isReply": false,
  "full_text": "Here's the second tweet in my thread on this topic.",
  "created_at": "2026-07-20T10:05:00.000Z",
  "tweetUrl": "https://x.com/elonmusk/status/1234567890123456789",
  "favorite_count": 4200,
  "retweet_count": 380,
  "reply_count": 92,
  "quote_count": 45,
  "is_quote_status": false,
  "quotedTweet": null,
  "threadId": "1234567890123456780",
  "threadPosition": 2,
  "isThreadStart": false,
  "isThreadEnd": false,
  "conversation_id_str": "1234567890123456780",
  "screen_name": "elonmusk",
  "is_blue_verified": true,
  "profileUrl": "https://x.com/elonmusk",
  "scrapedAt": "2026-07-26T14:02:11.000Z"
}
```

All 45 fields shown above (across tweet, reply, and profile-about row types) are the Actor's real dataset columns.

### How do you filter and target specific tweets?

`threadTargets`/`threadHandles` set scope — one or many profiles by URL or handle. `captureStartDate`/`captureEndDate` is the date-scope precision control. `imageTweetsOnly` and `includeRetweetsInCapture` are the closest thing to quality/content filters, narrowing to visual content or excluding retweets. Volume is controlled by `maxTweetsToCapture`, a hard cap across the whole run (tweets, replies, and about-records combined), and `minReplyCountForContext` bounds which tweets get the extra reply-fetch cost when `fetchReplyContext` is on.

```json
{ "threadHandles": ["elonmusk"], "captureStartDate": "7 days", "imageTweetsOnly": true }
```

```json
{ "threadTargets": ["https://x.com/example"], "fetchReplyContext": true, "minReplyCountForContext": 50, "authToken": "(cookie)", "csrfToken": "(cookie)" }
```

```json
{ "threadHandles": ["elonmusk"], "reconstructSelfThreads": true, "resolveQuotedTweets": false, "maxTweetsToCapture": 100 }
```

### ▶️ Want to try other social scrapers?

| Scraper Name | What it extracts |
| --- | --- |
| YouTube Comments Scraper With Commenter Lead Enrichment | Comparable comment-thread data with commenter enrichment for YouTube |
| Instagram Mentions Scraper & Sentiment Analysis | Comparable brand-mention monitoring for Instagram |
| Reddit Comment Scraper With Author Profile | Comparable thread/comment data with author enrichment for Reddit |
| LinkedIn Post Scraper & Comments Reactions | Comparable post/comment/reaction data for LinkedIn |
| Facebook Posts Scraper: Performance Analyzer | Comparable post-performance benchmarking for Facebook |
| Instagram Hashtag Scraper: Content Planner | Comparable content-thread and topic research for Instagram |

### How to extract X data programmatically

Every run is a standard Apify Actor call — one API request with your token, JSON input, JSON results back.

#### Python example

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_API_TOKEN>")

run_input = {
    "threadHandles": ["elonmusk"],
    "maxTweetsToCapture": 50,
    "reconstructSelfThreads": True,
}

run = client.actor("<YOUR_USERNAME>/twitter-profile-scraper-pinned-tweet-details").call(run_input=run_input)

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["full_text"][:60], row.get("threadPosition"))
```

#### Export to spreadsheets or CRM

Export the dataset directly as CSV or Excel, then map `screen_name`/`tweetUrl` to your CRM's contact fields and `threadId`/`threadPosition` to a content-organization column for thread curation.

### Is it legal to scrape X (Twitter) profiles?

Tweet text, usernames, and profile data are personal data tied to individual accounts, so GDPR and CCPA obligations apply to storing and using this data. Public X profiles and tweets are visible to any logged-out visitor, but downstream storage of individual users' content should follow applicable data-protection rules. Consult legal counsel for commercial applications involving bulk storage of personal data.

### ❓ FAQ

#### Does this Actor actually extract pinned tweet details?

No — despite "Pinned Tweet Details" in the Actor's name, the current source code has no dedicated pinned-tweet extraction logic. Its real, verified features are quote-tweet resolution and self-thread reconstruction, both documented above.

#### How accurate is the thread reconstruction?

It's genuinely derived from real `conversation_id_str` grouping, not guessed — but it's explicitly scoped to what this run actually captured. If `maxTweetsToCapture` cuts off partway through a long thread, the reconstructed thread reflects only the captured portion, since X exposes no thread-depth API to verify completeness against.

#### Does quote-tweet resolution cost extra requests?

No — the quoted tweet's full text, author, and media are resolved inline from the same response the base tweet capture already fetched.

#### Do I need to log into X to use this?

Not for the base tweet/thread/quote capture. Login cookies (`authToken`/`csrfToken`) are only required when `fetchReplyContext` is enabled.

#### How many tweets can I get per run?

`maxTweetsToCapture` (min 1, default 20) is a hard cap across the whole run, covering tweets, replies, and about-records combined.

#### Does Twitter Profile Scraper: Pinned Tweet Details work with Claude, ChatGPT, and AI agent frameworks?

It has no dedicated MCP server registration in this Actor's current setup, but it is callable as a standard Apify API endpoint by any agent framework that can make an authenticated HTTP request and parse JSON.

#### How does this compare to other X/Twitter scrapers?

No independently verifiable competitor listing could be confirmed at the time of writing, so no specific comparison is made here. This Actor's distinguishing feature is the zero-extra-cost quote-tweet resolution and self-thread reconstruction layered onto the base tweet capture.

#### Can I include native retweets?

Yes — set `includeRetweetsInCapture` to `true`, though the underlying detection is honestly only effective for roughly the last 7-10 days of a profile's timeline.

### Conclusion

Twitter Profile Scraper: Pinned Tweet Details turns a raw tweet capture into readable conversation context — genuine inline quote-tweet resolution and self-thread reconstruction, honestly scoped to what was actually captured. It's built for content researchers and social listening teams who need to read a thread in order, not a flat disconnected tweet list. Start a run with your target profiles to get tweets, threads, and quote context back in one pass.

# Actor input Schema

## `threadTargets` (type: `array`):

List of Twitter/X profile URLs to capture (e.g., https://x.com/elonmusk). Required if threadHandles is empty. (Accepts the base actor's `startUrls` key too.)

## `threadHandles` (type: `array`):

List of usernames without the @ (e.g., elonmusk). Required if threadTargets is empty. (Accepts the base actor's `twitterHandles` key too.)

## `maxTweetsToCapture` (type: `integer`):

Hard cap on total items (tweets/replies/about-records) written across the whole run. (Accepts the base actor's `maxItems` key too.)

## `captureStartDate` (type: `string`):

Lower bound for tweet date. Use absolute date (YYYY-MM-DD) or relative value (for example, 7 days). Empty = no lower bound. (Accepts the base actor's `start` key too.)

## `captureEndDate` (type: `string`):

Upper bound for tweet date. Use absolute date (YYYY-MM-DD) or relative value (for example, 1 day). Empty = no upper bound. (Accepts the base actor's `end` key too.)

## `includeRetweetsInCapture` (type: `boolean`):

When false, native retweets (full\_text starts with 'RT @') are dropped. Only effective for the last ~7-10 days. (Accepts the base actor's `includeNativeRetweets` key too.)

## `imageTweetsOnly` (type: `boolean`):

Keep only tweets that contain at least one photo. (Accepts the base actor's `onlyImages` key too.)

## `includeProfileOverview` (type: `boolean`):

Emit one profile-about record per user (uses the embedded user object from UserTweets). (Accepts the base actor's `getAboutData` key too.)

## `resolveQuotedTweets` (type: `boolean`):

When a tweet has is\_quote\_status=true, embed the quoted tweet's full text, author, and media under a quotedTweet{} object (resolved inline from the same response, zero extra requests). Turn off to skip resolution and save processing.

## `reconstructSelfThreads` (type: `boolean`):

Cluster the author's own consecutive tweets that share the same conversation\_id\_str (within this run's captured tweets) into threadId/threadPosition/isThreadStart/isThreadEnd. Derived only from what was actually captured — X exposes no thread-depth API, so no depth is invented.

## `fetchReplyContext` (type: `boolean`):

Fetch replies to each qualifying tweet via the TweetDetail endpoint. Requires login cookies. (Accepts the base actor's `getReplies` key too.)

## `minReplyCountForContext` (type: `integer`):

Only fetch replies for tweets whose reply\_count is at least this value. (Accepts the base actor's `minReplyCount` key too.)

## `authToken` (type: `string`):

Value of the `auth_token` cookie from x.com (devtools → Application → Cookies). Required for fetchReplyContext.

## `csrfToken` (type: `string`):

Value of the `ct0` cookie from x.com. Required for fetchReplyContext.

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

Apify proxy configuration. Recommended for reliability against rate limits.

## Actor input object example

```json
{
  "threadTargets": [
    "https://x.com/elonmusk"
  ],
  "threadHandles": [
    ""
  ],
  "maxTweetsToCapture": 20,
  "captureStartDate": "",
  "captureEndDate": "",
  "includeRetweetsInCapture": false,
  "imageTweetsOnly": false,
  "includeProfileOverview": false,
  "resolveQuotedTweets": true,
  "reconstructSelfThreads": true,
  "fetchReplyContext": false,
  "minReplyCountForContext": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "threadTargets": [
        "https://x.com/elonmusk"
    ],
    "threadHandles": [
        ""
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/twitter-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 = {
    "threadTargets": ["https://x.com/elonmusk"],
    "threadHandles": [""],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/twitter-profile-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "threadTargets": [
    "https://x.com/elonmusk"
  ],
  "threadHandles": [
    ""
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call simpleapi/twitter-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=simpleapi/twitter-profile-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/khmW4JTKdd42pS0eQ/builds/i3YrJFzsTb2GnepDv/openapi.json
