# Twitter X Reply Scraper With Replier Contact Leads (`simpleapi/twitter-x-reply-scraper`) Actor

Twitter/X Reply Scraper extracts replies and replier details, including usernames, profile data, reply text, timestamps, engagement metrics, and publicly available contact leads. Ideal for audience research, lead generation, engagement analysis, and social media intelligence.

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

## Pricing

from $2.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Reply Scraper With Replier Contact Leads

Scrape **X (Twitter) search results** and their **replies**, then turn every reply author into an outreach-ready lead: bio, location, website, email and phone (only when actually present), plus follower and following counts. Point it at a search like `#journorequest` or `#hiring`, and get back not just the posts but the people replying to them, with their real contact details already extracted.

Most X scrapers stop at the post and its reply count. This one follows every reply down to its author's profile and reply text, scans for a literal email, website or phone number, and flags exactly which repliers are usable leads — so you don't open a hundred profiles by hand.

### What is Twitter X Reply Scraper With Replier Contact Leads?

It's an Apify actor built for lead generation from X (Twitter) conversations. Give it search URLs (the same links you'd get from x.com's own search), and it collects the matching posts, then — for each post — pulls the actual replies underneath and mines each reply author's public profile and reply text for a bio, location, declared website, and any email or phone number that appears literally in text. Nothing is guessed or inferred: a reply author only gets an email or phone value if one is actually written in their bio or their reply. It needs your own logged-in X session (`authToken` + `ct0` cookies) because reply threads are no longer readable without authentication.

### What data can I extract with Twitter X Reply Scraper With Replier Contact Leads?

**Post fields** (one row per matched post, `charged_event_name: "row_result"`):

| Field | Description |
| --- | --- |
| `tweetLink` | Direct link to the post. |
| `handle` / `fullname` / `avatar` / `verified` | Post author identity. |
| `tweetContent` / `tweetDate` | Post text and publish date. |
| `commentCount` / `retweetCount` / `quoteCount` / `likeCount` | Post engagement counters. |
| `repliersWithContacts` | Count of repliers on this post who carry an extracted contact. |
| `repliesData` | Array of reply-author lead objects (see below). |

**Reply-author lead fields** (inside each `repliesData` entry):

| Field | Description |
| --- | --- |
| `replierBio` / `replierLocation` | Reply author's profile bio and location text. |
| `replierWebsite` / `replierWebsites` | Declared profile link, plus any additional links found in bio or reply text. |
| `replierEmail` / `replierEmails` / `replierEmailType` | Email(s) found literally in bio or reply text (personal/business heuristic), or `null` if none appears. |
| `replierPhone` | Phone number found literally in bio or reply text, or `null`. |
| `replierFollowers` / `replierFollowing` / `replierTweets` | Reply author's own follower/following/post counts. |
| `replierHasContact` | `true` if the reply author has at least one of email, website or phone. |

### Why not build this yourself?

X's reply threads (`TweetDetail`) are only readable to an authenticated session, and X does not expose account email addresses through any API — the only way to attribute an email to a person is to find it literally written somewhere they control, like their bio or a reply. This actor already scans both places with pattern-matched extraction, discovers X's current GraphQL query IDs at run start (they change without notice), and escalates through a proxy fallback ladder (direct → datacenter → residential) automatically when X starts blocking requests.

Because coverage depends on what people actually publish, `replierHasContact` will be `false` for most repliers — that's expected, not a bug. Use `contactsOnly` to keep just the leads that carry a usable contact instead of scrolling past the empty ones.

### How to use data extracted from Twitter X Reply Scraper With Replier Contact Leads?

- **Sales and BD teams** — turn hashtag conversations like `#hiring` or `#journorequest` into a filtered list of repliers who left a contact detail, ready for outreach.
- **Recruiters** — find candidates replying to job-related threads and pull their bio, website and contact info in one pass.
- **PR agencies** — mine `#journorequest`-style threads for journalists who included an email or website in their reply.
- **Growth marketers** — identify engaged repliers on competitor or industry posts and export only the ones with a public contact channel.

### 🔼 Input sample

| Parameter | Required | Type | Description | Example |
| --- | --- | --- | --- | --- |
| `startUrls` | Yes | array | X search page links — the exact URL you get from searching on x.com. Each defines one topic/keyword set to follow. | `["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"]` |
| `maxSearchResults` | No | integer | Posts to collect per search link. Default `10`, max `5000`. | `10` |
| `maxReplies` | No | integer | Replies (leads) to keep per post, counted **after** the `contactsOnly` filter. Default `5`, max `500`. | `5` |
| `extractReplierContacts` | No | boolean | Harvest each reply author's bio, location, website, email and phone. Default `true`. **Common pitfall:** email is reported only when it appears verbatim in bio/reply text — X never exposes account emails, so coverage is partial by design. | `true` |
| `contactsOnly` | No | boolean | Keep only replies whose author has at least one contact detail, applied before `maxReplies`. Default `false`. | `true` |
| `authToken` | No | string (secret) | Your X `auth_token` session cookie (or set the `AUTH_TOKEN` env var). Required to read replies — the run stops with an error if missing from both sources. | `"a1b2c3..."` |
| `ct0` | No | string (secret) | Your X `ct0` CSRF cookie, same session as `authToken` (or the `CT0` env var). | `"d4e5f6..."` |
| `proxyConfiguration` | No | object | Optional Apify Proxy. The actor escalates through direct → datacenter → residential automatically if X starts blocking requests, regardless of this setting. | `{"useApifyProxy": false}` |

```json
{
  "startUrls": ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],
  "maxSearchResults": 10,
  "maxReplies": 5,
  "contactsOnly": true,
  "authToken": "YOUR_X_AUTH_TOKEN",
  "ct0": "YOUR_X_CT0_TOKEN"
}
```

### 🔽 Output sample

```json
{
  "tweetLink": "https://x.com/exampleuser/status/1234567890123456789",
  "handle": "@exampleuser",
  "tweetContent": "Looking for a freelance writer for a tech piece, DM or reply! #journorequest",
  "tweetDate": "2026-07-20",
  "commentCount": 34,
  "likeCount": 210,
  "repliersWithContacts": 1,
  "repliesData": [
    {
      "replierBio": "Freelance tech journalist. Bylines in..",
      "replierLocation": "London, UK",
      "replierWebsite": "https://janedoe.com",
      "replierEmail": "jane@janedoe.com",
      "replierEmailType": "business",
      "replierPhone": null,
      "replierFollowers": 4210,
      "replierHasContact": true
    }
  ]
}
```

### How do you filter and target specific X reply leads?

Combine `contactsOnly` with `maxReplies` to control exactly how many usable leads you get per post, and stack multiple search URLs in `startUrls` to cover several hashtags or keyword sets in one run.

**Only repliers with a real contact detail, top 5 per post:**

```json
{ "startUrls": ["https://x.com/search?q=%23hiring&f=live"], "contactsOnly": true, "maxReplies": 5 }
```

**Broad reply capture without filtering, for manual review:**

```json
{ "startUrls": ["https://x.com/search?q=%23journorequest&f=live"], "extractReplierContacts": false }
```

**Multiple hashtag searches in one run:**

```json
{ "startUrls": ["https://x.com/search?q=%23hiring&f=live", "https://x.com/search?q=%23journorequest&f=live"], "maxSearchResults": 20 }
```

### ▶️ Want to try other scrapers?

| Actor | What it does |
| --- | --- |
| [twitter-x-posts-scraper-replies](https://apify.com/SimpleAPI/twitter-x-posts-scraper-replies) | Scrape a profile's posts with full reply threads. |
| [x-twitter-posts-search-by-advanced-keyword-filters](https://apify.com/SimpleAPI/x-twitter-posts-search-by-advanced-keyword-filters) | Search X posts with advanced keyword filters. |
| [twitter-trends-scraper-by-city-multiple-countries](https://apify.com/SimpleAPI/twitter-trends-scraper-by-city-multiple-countries) | Track trending topics across cities and countries. |

### How to extract X reply leads programmatically

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("SimpleAPI/twitter-x-reply-scraper-with-replier-contact-leads").call(run_input={
    "startUrls": ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],
    "maxSearchResults": 10,
    "maxReplies": 5,
    "contactsOnly": True,
    "authToken": "YOUR_X_AUTH_TOKEN",
    "ct0": "YOUR_X_CT0_TOKEN",
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    for lead in item["repliesData"]:
        if lead.get("replierHasContact"):
            print(lead["replierEmail"], lead["replierWebsite"])
```

Every run's dataset can also be exported straight to JSON, CSV, Excel or an API endpoint from the Apify Console — no code needed for a one-off pull.

### Is it legal to scrape X (Twitter) replies for leads?

Scraping publicly accessible data is generally lawful in the US under the precedent set in *hiQ Labs v. LinkedIn*, which held that scraping data not gated behind a login does not violate the Computer Fraud and Abuse Act. This actor reads posts, replies and profile bios that are publicly visible on X — the session cookie it uses is a viewing credential only, not a way to access private content. Because this actor's whole purpose is extracting contact details tied to identifiable people, GDPR (EU) and CCPA (California) apply directly to what you do with the output — review your legal basis before using extracted emails or phone numbers for outreach, especially at scale.

### ❓ FAQ

**Why do I need my own X auth\_token and ct0 cookies?**
X requires an authenticated session to read reply threads — the logged-out guest API for that endpoint was shut off. Log into x.com, open DevTools → Application → Cookies, and copy both values from the same session.

**Why is `replierEmail` null for most repliers?**
X does not expose account email addresses through any API. This actor only reports an email when one is written literally in the reply author's bio or reply text — most people don't publish an email there, so a low hit rate is expected, not a bug.

**How is `replierEmailType` determined?**
It's a lightweight heuristic based on the email's domain (e.g. a free-mail provider vs. a custom domain), reported alongside the email so you can prioritize business-looking addresses if useful — it isn't a verified classification.

**What does `contactsOnly` actually filter?**
It drops any reply whose author has no email, website or phone before `maxReplies` is applied — so `maxReplies: 5` with `contactsOnly: true` returns up to 5 leads that actually carry a contact, not 5 replies total.

**What happens if I don't provide authToken/ct0?**
The actor checks for a valid session (from input or the `AUTH_TOKEN`/`CT0` environment variables) before starting and stops immediately with an error if neither is present — no partial run happens.

**Why did a search return posts but no replies?**
If X starts blocking requests for that session/IP combination, the actor automatically retries through a proxy escalation ladder (direct → datacenter → residential). If replies still come back empty after that, the session cookies may have expired — refresh them from your browser.

**How is this different from other X lead-generation scrapers on Apify?**
As observed on the Apify Store on 2026-07-26, most X reply/contact scrapers we reviewed require chaining a separate post scraper and a separate contact-enrichment actor. This one collects posts, replies and literal contact extraction in a single run, keyed per search URL.

### Conclusion

Twitter X Reply Scraper With Replier Contact Leads turns hashtag and keyword searches into a filtered list of engaged people with real, literally-published contact details — ready for outreach without opening a single profile by hand.

# Actor input Schema

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

📋 Add one or more X search page links (the same URLs you get when you search on x.com). Each link defines what topic or keywords you want to follow. Reply threads like #journorequest or #hiring are great lead sources. Add as many as you need! 🌍✅

## `maxSearchResults` (type: `integer`):

🎯 Choose how many posts you want from each search link — higher numbers give you a broader snapshot; lower numbers finish faster. Pick what fits your project! ⚡📈

## `maxReplies` (type: `integer`):

💡 For each post, how many replies (leads) to keep — counted AFTER the contacts-only filter below. Example: 40 replies fetched, 8 with a contact, maxReplies=5 → 5 kept. Default is 5. 🙌🧵

## `extractReplierContacts` (type: `boolean`):

Harvest each reply author's bio, location, website, email and phone (only when literally present in the profile or reply text — never guessed), plus follower/following/tweet counts. Turn off for the plain post+reply output. Default is on.

## `contactsOnly` (type: `boolean`):

Keep only replies whose author has at least one contact detail (email, website or phone). Replies with no contact are dropped before the reply limit is applied, giving you a clean lead list. Example: 40 replies, 8 with a contact → up to maxReplies of those 8. Default is off.

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

🔑 Your X account session token (or set the AUTH\_TOKEN environment variable in Apify). This lets the actor use your logged-in session to read replies. Keep it private — never share it publicly! 🤫🔒

## `ct0` (type: `string`):

✨ The companion security value for your X session (or use the CT0 env var). It works together with your auth token so everything stays in sync — like a key and a lock! 🔐💙

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

🌍 Optional **Apify Proxy** settings for smoother runs in the cloud. Turn it on if you prefer routing traffic through Apify’s network — handy for stable jobs and privacy-friendly setups. Off by default; enable when it suits you! ☁️✅

## Actor input object example

```json
{
  "startUrls": [
    "https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"
  ],
  "maxSearchResults": 10,
  "maxReplies": 5,
  "extractReplierContacts": true,
  "contactsOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped items in the Actor's default dataset.

# 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/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/twitter-x-reply-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/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/twitter-x-reply-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/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call simpleapi/twitter-x-reply-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,simpleapi/twitter-x-reply-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/ReU6D4f2beMTcuUAE/builds/9X0dZlfZg0wPPu7Fl/openapi.json
