Twitter X Reply Scraper: Reply Sentiment & Tone Breakdown
Pricing
from $3.99 / 1,000 results
Twitter X Reply Scraper: Reply Sentiment & Tone Breakdown
π¬ Twitter/X Reply Scraper extracts tweet replies at scaleβusernames, text, timestamps, IDs & thread context. π Perfect for social listening, sentiment, competitor research & engagement tracking. β‘ CSV/JSON export for dashboards, BI & automation. π
Pricing
from $3.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapio
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
5 days ago
Last modified
Categories
Share
Twitter X Reply Scraper β Posts, Replies and Sentiment Tone
Twitter X Reply Scraper collects posts from any X (Twitter) search and pulls the direct replies underneath each one, then scores every reply for sentiment (positive / negative / neutral) and one of nine tone labels (angry, enthusiastic, humorous, sarcastic, questioning, informative, supportive, critical, neutral) β plus a per-post mood rollup. Unlike scrapers that hand back raw HTML or an unscored reply feed, this Actor returns typed JSON with the analysis already attached, ready for a dashboard, a database, or an LLM context window. Scoring is rule-based and keyless by default; optional multi-provider AI enrichment is available but off unless you turn it on.
What does Twitter X Reply Scraper do?
Twitter X Reply Scraper takes one or more X search-page links, collects the posts each search returns, and β for every post β fetches its conversation thread and keeps up to a set number of direct replies. Every reply is scored the moment it's captured: a sentiment label with a numeric score, and a tone label. Each post also gets a mood rollup that summarizes its captured replies in one object. Reading replies requires a logged-in X session β you supply your own auth_token and ct0 session cookies (or set them as environment variables); there is no anonymous mode.
- Collects posts from any X search URL, not just a hashtag or a single account
- Fetches the direct-reply thread for every collected post
- Scores every reply for sentiment and tone with no API key and no extra network call
- Filters replies by language before capping how many are kept per post
- Rolls up each post's replies into sentiment splits, a dominant mood, and a tone breakdown
- Optionally re-scores replies with a real LLM from 15 selectable models across 7 providers
- Streams each finished post β with its replies and rollup β into the dataset as it completes, not at the end of the run
Features & Capabilities
Three things happen on every reply, in order: capture, deterministic scoring, and β only if you turn it on β an additional AI opinion layered on top.
Core features
- Search-driven collection β input is X search-page URLs (
startUrls); theq=query string is extracted and re-issued against X's own search timeline, so any search you can build in the browser (keywords,min_replies:,from:, date filters) works as input - Per-post reply threads β
repliesDataon every post row is the array of that post's direct replies, each carrying the same author and engagement fields as the post itself - Always-on rule-based analysis β every reply gets
replySentiment,replySentimentScore,replyTone, andreplyAnalysisMethodwith zero configuration and zero API key - Per-post mood rollup β
sentimentBreakdownaggregates the captured replies into sentiment counts and percentages, a dominant sentiment, an average score, a tone breakdown, and a language breakdown - Optional AI re-scoring β
aiReplySentiment/aiReplyTonefrom a provider of your choice, additive to (never replacing) the rule-based fields - Reply-language filter β keep only replies tagged in a given language by X's own per-reply language code, applied before the reply count is capped
- Proxy escalation on blocks β the run starts direct (or on your chosen proxy) and automatically steps up through Apify proxy tiers if X returns a block signal
How Twitter X Reply Scraper compares to other X reply scrapers
Checked on the Apify Store on 26 July 2026. kaitoeasyapi/twitter-reply's own listing documents reply collection with rich author and engagement fields, but its published sample output carries no sentiment or tone field at all β sentiment analysis is not documented as a capability of that Actor. fastcrawler/twitter-x-hashtag-scraper-support-sentiment-tone-analyzer-2025 does offer a sentimentAnalysis toggle, but it operates on hashtag search results rather than reply threads, tags a single tone per tweet rather than per reply, and its own description warns that "the analysis may take longer when checked" β consistent with an on-demand external call rather than a keyless local computation.
| Feature | Twitter X Reply Scraper | kaitoeasyapi/twitter-reply | fastcrawler/twitter-x-hashtag-...-analyzer-2025 |
|---|---|---|---|
| Entity focus | Search β posts β reply threads | Reply collection by conversation ID | Hashtag search results |
| Sentiment/tone field in output | β Always on, no key needed | β Not documented | β Optional toggle, tweet-level |
| Per-reply tone label (9 categories) | β | β Not documented | Partial β one tone per tweet |
| Per-post mood rollup (sentiment split, dominant mood, tone/language breakdown) | β | β Not documented | β Not documented |
| Optional AI re-scoring across multiple providers | β 15 models, 7 providers | β Not documented | Not specified which model |
| Reply-language filter | β | Not documented as reply-level | β (has a tweet-level lang filter instead) |
| Output format | Typed JSON, stable field set | Typed JSON | Typed JSON |
If your use case is feeding structured data straight to an LLM or a dashboard, the sentiment/tone row is the decision-maker β running your own classification pass after scraping is extra latency and extra cost that this Actor's always-on layer removes.
When another tool might suit you better
If you already have kaitoeasyapi/twitter-reply's documented conversation-ID-based collection and only need raw reply text with author and engagement data β no sentiment or tone β its simpler input shape may be less to configure. If your target is a hashtag or keyword search across posts rather than reply threads, and you want the sentiment step to run as a single external analysis pass on the top-level tweet rather than per reply, fastcrawler's hashtag-scoped tool is a closer fit to that narrower need than a reply-thread Actor.
Twitter X Reply Scraper within the Scrapio data stack
Twitter X Reply Scraper covers posts and their reply threads. For keyword or hashtag post search without reply collection, use Twitter X Posts Scraper By Keyword & Hashtag Search. For tracking brand or keyword mentions over time rather than one-off reply capture, use Twitter Trends Scraper β Brand & Keyword Monitoring. For pairing posts with full author profile detail instead of reply threads, use X Twitter Posts Search With Author Profile Details.
Why do developers and data teams scrape X replies?
Brand and customer experience teams
A support or community team runs a search for their brand handle or product name with min_replies: set above zero, capped at a manageable maxReplies per post, and reads sentimentBreakdown.negativePct per post to triage which threads need a human response first. repliesData[].replyTone β specifically angry and critical β surfaces the replies worth escalating over ones tagged humorous or neutral, without anyone reading every reply by hand.
AI training data and RAG indexing
tweetContent and repliesData[].tweetContent are the high-information text fields β real, short-form conversational language paired with a sentiment label and a tone label already attached, which is exactly the kind of labeled text a classifier or a RAG index benefits from without a separate annotation pass. For RAG enrichment, indexing tweetContent alongside replySentiment and replyTone lets an agent answer "how are people reacting to X" questions directly from retrieved rows. For training data, replySentiment and replyTone are consistent categorical labels across every row, useful as weak-supervision targets for a custom sentiment or tone classifier without hand-labeling a corpus from scratch.
Competitive and market intelligence
Running the same search against a competitor's handle or product name on a schedule and comparing sentimentBreakdown.dominantSentiment and sentimentBreakdown.avgSentimentScore run over run turns reply sentiment into a trackable metric β a shift from positive to negative dominant sentiment, or a drop in avgSentimentScore, is a concrete signal worth investigating rather than a vague impression.
Research and academic use
Public-conversation datasets built from tweetContent, replyLang, replySentiment and replyTone support social-media discourse research and market-sentiment studies without a manual annotation pipeline. Scope is limited to what X already surfaces on public search results and public reply threads β no private accounts, no DMs.
Product and SaaS development
sentimentBreakdown and repliesData map directly onto a social-listening dashboard, a brand-health monitoring tool, or an alerting layer built on top of this Actor's dataset output β the rollup fields are already aggregate-ready, so a product doesn't need to recompute sentiment splits itself.
β¬οΈ Input Parameters
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
startUrls | Yes | array | X search-page links β the same URLs you get from searching on x.com. Each link's q= value is used as the query. Legacy urls key is also accepted. | ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"] |
maxSearchResults | No | integer | How many posts to collect per search link. Minimum 1, maximum 5000. Default 10. | 10 |
maxReplies | No | integer | How many direct replies to keep and score per post, applied after the language filter so the cap counts kept replies only. Minimum 1, maximum 500. Default 5. | 5 |
replyLanguage | No | string | Keep only replies tagged in this language before scoring, using X's own per-reply language code (e.g. en, es, pt, fr, de, ja). Blank analyzes every language. Default "". | en |
aiEnhancement | No | boolean | Adds aiReplySentiment / aiReplyTone alongside the always-on rule-based fields. Requires an API key (below). If the AI call fails, those two fields are left null, never fabricated. Default false. | false |
aiModel | No | string (enum) | Model/provider for AI enrichment, only used when aiEnhancement is on. Provider is auto-detected from the name prefix. One of: claude-haiku-4-5, claude-sonnet-5, claude-opus-4-8, gpt-4o-mini, gpt-4o, gpt-4.1-mini, o3-mini, gemini-2.0-flash-lite, gemini-2.0-flash, gemini-2.5-flash, grok-3-mini, grok-3, deepseek-chat, sonar, mistral-small-latest. Default claude-haiku-4-5. | claude-haiku-4-5 |
aiApiKey | No | string (secret) | API key for the chosen provider, only needed when aiEnhancement is on. If left blank, falls back to the provider's own environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY, PERPLEXITY_API_KEY, MISTRAL_API_KEY). Masked in the Apify Console (isSecret). | sk-ant-... |
authToken | No (see note) | string (secret) | Your X account session auth_token cookie, or set the AUTH_TOKEN environment variable. Reading replies requires a logged-in session. Masked in the Apify Console (isSecret). | a1b2c3... |
ct0 | No (see note) | string (secret) | The companion ct0 (CSRF) cookie for your X session, or set the CT0 environment variable. Masked in the Apify Console (isSecret). | d4e5f6... |
proxyConfiguration | No | object | Apify Proxy settings. Off by default β the run goes direct first, then escalates to datacenter and residential proxy tiers automatically on a block. | {"useApifyProxy": false} |
startUrls is the only field marked required in the input schema. In practice, though, a run with no authToken/ct0 (via input or the AUTH_TOKEN/CT0 environment variables) exits immediately with an error and writes no dataset rows at all β reading X's reply threads is gated behind a logged-in session regardless of what the schema marks as optional.
Example input
{"startUrls": ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],"maxSearchResults": 20,"maxReplies": 10,"replyLanguage": "en","aiEnhancement": false,"authToken": "your_x_auth_token_cookie","ct0": "your_x_ct0_cookie","proxyConfiguration": {"useApifyProxy": false}}
Supported URL types and input formats
startUrls accepts any x.com search-page URL β the Actor reads the q= query parameter directly from it, so anything you can build by typing filters into the X search bar becomes valid input:
- Hashtag with engagement filter β
https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=liveβ a hashtag search restricted to posts that already have at least 10 replies, useful for guaranteeing a conversation to analyze - Keyword search β
https://x.com/search?q=customer+support+experience&src=typed_query&f=liveβ a plain keyword search with no operator - Account-scoped search β
https://x.com/search?q=from%3Abrandhandle+min_faves%3A50&src=typed_queryβ replies to a specific account's higher-engagement posts
If a URL has no q= parameter, the Actor falls back to its internal default search query rather than failing the run. Both plain URL strings and legacy urls-key entries are accepted for startUrls.
β¬οΈ Output Format
Every result is one dataset row per post, with the post's captured replies nested inside it as an array and a sentiment rollup nested inside it as an object. Every dataset row is charged as one row_result event β the source code contains a single push_data call per post, so there are no separate uncharged accounting or error rows to filter out.
The default dataset view surfaces 9 columns (tweetLink, tweetContent, tweetDate, handle, commentCount, retweetCount, likeCount, sentimentBreakdown, repliesData) β this is a subset for readability. The full row carries more keys than the view shows, documented below.
Output for a post (tweet) row
{"tweetLink": "https://x.com/newsdesk/status/1832456789012345678","avatar": "https://pbs.twimg.com/profile_images/1234567890/avatar_bigger.jpg","fullname": "News Desk","handle": "@newsdesk","verified": true,"tweetDate": "2026-06-14T09:32:00.000Z","tweetContent": "Looking for people willing to share their experience with remote work burnout for a feature story. #journorequest","commentCount": 42,"retweetCount": 18,"quoteCount": 3,"likeCount": 210,"repliesData": [{"tweetLink": "https://x.com/reader_jane/status/1832457001122334455","avatar": "https://pbs.twimg.com/profile_images/2233445566/avatar_bigger.jpg","fullname": "Jane R.","handle": "@reader_jane","verified": false,"tweetDate": "2026-06-14T09:41:00.000Z","tweetContent": "Happy to help β burned out hard last year and would love to share what actually worked.","commentCount": 2,"retweetCount": 0,"quoteCount": 0,"likeCount": 14,"replyLang": "en","replySentiment": "positive","replySentimentScore": 0.667,"replyTone": "supportive","replyAnalysisMethod": "rule-based","aiReplySentiment": null,"aiReplyTone": null}],"sentimentBreakdown": {"repliesAnalyzed": 5,"positive": 3,"negative": 1,"neutral": 1,"positivePct": 60.0,"negativePct": 20.0,"neutralPct": 20.0,"dominantSentiment": "positive","avgSentimentScore": 0.312,"topTone": "supportive","toneBreakdown": {"supportive": 2,"informative": 1,"questioning": 1,"critical": 1},"languageBreakdown": {"en": 5},"analysisMethod": "rule-based"}}
Every key present on the post row: tweetLink, avatar, fullname, handle, verified, tweetDate, tweetContent, commentCount, retweetCount, quoteCount, likeCount, repliesData, sentimentBreakdown.
Output for each reply object
Each entry in repliesData is a full record in its own right β the same author and engagement shape as a post, plus the analysis fields:
{"tweetLink": "https://x.com/reader_mark/status/1832458112233445566","avatar": "https://pbs.twimg.com/profile_images/3344556677/avatar_bigger.jpg","fullname": "Mark T.","handle": "@reader_mark","verified": false,"tweetDate": "2026-06-14T09:55:00.000Z","tweetContent": "lol this is such a fake problem, everyone's just lazy now","commentCount": 0,"retweetCount": 0,"quoteCount": 0,"likeCount": 3,"replyLang": "en","replySentiment": "negative","replySentimentScore": -0.5,"replyTone": "humorous","replyAnalysisMethod": "rule-based","aiReplySentiment": "negative","aiReplyTone": "sarcastic"}
Every key on a reply object: tweetLink, avatar, fullname, handle, verified, tweetDate, tweetContent, commentCount, retweetCount, quoteCount, likeCount, replyLang, replySentiment, replySentimentScore, replyTone, replyAnalysisMethod, aiReplySentiment, aiReplyTone. The last two are only populated when aiEnhancement is on and the call succeeds β otherwise both are null, never a guessed value.
How the always-on rule-based scoring works: replySentiment and replySentimentScore come from a fixed lexicon of positive and negative words plus emoji polarity, with simple negation handling (a positive or negative word immediately preceded by a negator like "not" or "never" flips its polarity). The raw score is normalized to the -1 to 1 range and rounded to three decimals; replySentiment is positive when the raw sum is above zero, negative when below, neutral at exactly zero. replyTone runs a fixed priority order of checks β humor markers first (unless anger words are also present), then sarcasm phrases, then anger signals (anger words, all-caps, multiple exclamation marks) combined with negative sentiment, then enthusiasm signals combined with positive sentiment, then support words, then a question check, then a negative-sentiment default of critical, then a link-or-length check for informative, falling back to neutral. replyAnalysisMethod is always the literal string "rule-based" β this is a heuristic lexicon and rule engine, not a trained model, and it runs in pure Python with no network call and no API key.
How the optional AI layer works: when aiEnhancement is on and a key is available, reply texts are batched (20 per batch) and sent to the selected provider with a fixed prompt asking for a sentiment (positive/negative/neutral/mixed) and tone (the same 9 labels) per reply, requested as structured JSON. Anthropic models use the native SDK with a JSON-schema-constrained response; every other provider (OpenAI, Gemini, Grok, DeepSeek, Perplexity, Mistral) is called through an OpenAI-compatible chat.completions endpoint. A malformed or missing result for a given reply, or any exception during the call, leaves that reply's aiReplySentiment/aiReplyTone at null β the rule-based fields are computed independently and are never affected by an AI failure.
sentimentBreakdown (the mood rollup) fields: repliesAnalyzed, positive, negative, neutral, positivePct, negativePct, neutralPct, dominantSentiment, avgSentimentScore, topTone, toneBreakdown, languageBreakdown, analysisMethod. This is computed purely from the replies already captured for that post β no extra network fetch β so it always reflects exactly the replies in that post's repliesData array, capped by maxReplies.
Schema stability and export options
Field names stay stable across runs β the Actor reads X's GraphQL response by fixed key path rather than by parsing rendered page markup, so a visual redesign on x.com does not change your output shape. Export the dataset as JSON, CSV, or Excel from the Apify Console, or read it programmatically through the Apify API or apify-client/apify_client SDKs.
Twitter X Reply Scraper Strategy Guide
Strategy 1: Real-time enrichment pipeline
Trigger a run whenever a new mention needs context β a support ticket references a public thread, or a monitoring rule fires on a keyword. Run the Actor against that single search URL with a small maxReplies, then read sentimentBreakdown.dominantSentiment and sentimentBreakdown.negativePct straight off the finished row and write them back to your ticketing or CRM system alongside the original tweetLink. Because rows are pushed to the dataset as each post finishes rather than at the end of the run, a downstream consumer polling the dataset gets the enrichment as soon as it exists.
Strategy 2: Scheduled monitoring and alerting
Set up an Apify Schedule to run the same startUrls search on a recurring interval. On each run, diff the new sentimentBreakdown.avgSentimentScore and dominantSentiment for a tracked post or account search against the previous run's values, and alert when avgSentimentScore drops past a threshold you set, or when dominantSentiment flips from positive/neutral to negative. Apify's built-in webhooks can fire on run completion so the diff-and-alert step runs automatically without polling.
Strategy 3: Bulk dataset build
For a research corpus or a training set, pass a longer list of search URLs into startUrls in one run with maxSearchResults and maxReplies both raised toward their ceilings (5000 and 500 respectively), and export the finished dataset as CSV for a spreadsheet or database load. Each startUrls entry is processed in sequence within the run, so a large list simply extends the run rather than requiring separate runs β no concurrency limit beyond that sequential processing is documented in the source.
Strategy comparison at a glance
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time enrichment | Ticket/CRM context on a single thread | On-demand trigger, small maxReplies | JSON row read via API |
| Scheduled monitoring | Tracking sentiment drift over time | Apify Schedule + webhook | Dataset diffed run over run |
| Bulk dataset build | Research corpus, training data | One run, many startUrls | CSV/JSON export |
π΄ Related X Scrapers & Tools
| Scraper Name | What it extracts |
|---|---|
| Twitter X Posts Scraper By Keyword & Hashtag Search | Posts matching a keyword or hashtag search, without reply collection |
| Twitter Trends Scraper β Brand & Keyword Monitoring | Ongoing brand/keyword mention tracking on X |
| X Twitter Posts Search With Author Profile Details | Posts paired with full author profile detail |
| Instagram Comment Sentiment Scraper | Instagram post comments with the same sentiment-analysis pattern |
| Facebook Pages Scraper: Review Sentiment Analysis | Facebook Page reviews scored for sentiment |
How to integrate Twitter X Reply Scraper with your stack
Twitter X Reply Scraper works with any language or tool that can make an HTTP request, since it runs on Apify as a standard Actor with a dataset output.
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/twitter-x-reply-scraper-reply-sentiment-tone-breakdown").call(run_input={"startUrls": ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],"maxSearchResults": 20,"maxReplies": 10,"replyLanguage": "en","authToken": "your_x_auth_token_cookie","ct0": "your_x_ct0_cookie",})rows = []for post in client.dataset(run["defaultDatasetId"]).iterate_items():rollup = post.get("sentimentBreakdown") or {}rows.append({"handle": post["handle"],"tweetContent": post["tweetContent"],"dominantSentiment": rollup.get("dominantSentiment"),"negativePct": rollup.get("negativePct"),"repliesAnalyzed": rollup.get("repliesAnalyzed"),})import csvwith open("reply_sentiment.csv", "w", newline="", encoding="utf-8") as f:writer = csv.DictWriter(f, fieldnames=rows[0].keys())writer.writeheader()writer.writerows(rows)
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('<YOUR_USERNAME>/twitter-x-reply-scraper-reply-sentiment-tone-breakdown').call({startUrls: ['https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live'],maxSearchResults: 20,maxReplies: 10,replyLanguage: 'en',authToken: 'your_x_auth_token_cookie',ct0: 'your_x_ct0_cookie',});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const post of items) {console.log(post.handle, post.sentimentBreakdown?.dominantSentiment, post.sentimentBreakdown?.negativePct);}
Async and scheduled pipelines
For fire-and-forget large jobs, start the run with client.actor(...).start() instead of .call() and poll client.run(runId).get() for status, or configure an Apify webhook on the Actor to notify your endpoint when the run finishes. For recurring collection, an Apify Schedule re-runs the same input on a cron-style interval without any polling code on your side.
π― Who Needs Twitter X Reply Scraper? (Use Cases & Industries)
Brand and customer experience teams
A CX lead searches their brand handle with min_replies: set, caps maxReplies to a manageable review size, and pulls sentimentBreakdown.negativePct and repliesData[].replyTone per post each morning to decide which threads a human should read first β angry and critical replies get triaged ahead of humorous ones.
Marketing and growth teams
A campaign manager runs the same hashtag search before and after a launch and compares sentimentBreakdown.dominantSentiment and avgSentimentScore across the two runs to see whether reception shifted, using repliesData[].tweetContent for the specific quotes worth featuring or addressing.
Competitive intelligence analysts
An analyst tracks a competitor's product-announcement threads on a schedule, watching sentimentBreakdown.negativePct for spikes that flag a rollout going badly before it shows up in reviews or the press.
Researchers
A researcher builds a public-conversation dataset from tweetContent, replyLang, replySentiment, and replyTone across a topic search, scoped entirely to publicly visible posts and replies β no private accounts, no DMs.
AI and product engineers
A developer building a social-listening feature indexes tweetContent and repliesData straight into an application or vector store β the sentiment and tone fields arrive already computed, so the product layer doesn't need its own classification step before it can render a mood indicator.
Is it legal to scrape X replies?
Scraping publicly accessible data is broadly permitted in U.S. law β in hiQ Labs, Inc. v. LinkedIn Corp. (9th Cir. 2019), the court held that accessing data a website makes available to the public, without authentication, does not violate the Computer Fraud and Abuse Act. Twitter X Reply Scraper only collects posts and replies visible on X's public search and thread pages once your own logged-in session can view them β it does not access private accounts, DMs, or anything gated beyond a standard login.
That legal permissibility is separate from X's own Terms of Service, which restrict automated data collection; violating them is a contractual and civil matter between you and X, not a criminal one, and is a separate question from whether the underlying data is public.
Because each row includes handle, fullname, and avatar β identifiers tied to a real person β this output does contain personal data under GDPR and CCPA-style frameworks, even though every field is already publicly visible on X. Twitter X Reply Scraper returns only publicly accessible data; the lawful basis for storing, processing, or using that personal data is your responsibility as the controller of what you do with it. Consult legal counsel before any commercial use involving personal data, particularly at scale or across jurisdictions.
β Frequently asked questions
Does Twitter X Reply Scraper work without an X account?
No. Reading reply threads requires a logged-in X session β you supply your auth_token and ct0 cookies through the input (or the AUTH_TOKEN/CT0 environment variables). A run without valid session credentials exits immediately with an error and writes no dataset rows, even though authToken and ct0 are not in the input schema's required list.
Is the sentiment and tone analysis AI-generated?
Not by default. The replySentiment, replySentimentScore, replyTone, and replyAnalysisMethod fields always come from a deterministic lexicon-and-rule engine β word lists, emoji polarity, and negation handling β with replyAnalysisMethod literally set to "rule-based" on every reply. A real language model is only involved if you turn on aiEnhancement and supply a provider API key; that adds two separate fields, aiReplySentiment and aiReplyTone, without touching the rule-based ones.
How does Twitter X Reply Scraper handle X's anti-scraping measures?
The Actor sends requests with browser-matching headers and, when a request is blocked (HTTP 401/403/429/503, a missing response, or a GraphQL error payload), automatically escalates: it retries direct or on your chosen proxy first, then steps up to an Apify datacenter proxy group, then to a residential proxy group, retrying up to three times with an increasing delay between attempts. A working proxy session is kept and reused for subsequent requests rather than rotated on every call.
Can I run it at scale without getting blocked?
maxSearchResults and maxReplies cap out at 5000 and 500 respectively β these are the Actor's own input ceilings, not a confirmed X rate limit. No uptime or success-rate figure is published for this Actor; how much you can collect before hitting a block depends on your proxy configuration and X's own enforcement at the time, neither of which the Actor controls.
How fresh is the data Twitter X Reply Scraper returns?
Every run performs a live fetch against X's search and thread endpoints β nothing is served from a cache. The reply set you get reflects the conversation as it exists at the moment the run makes each request.
What happens if a search returns zero posts, or a post has zero replies?
If a search URL returns no posts, the Actor logs it and moves to the next startUrls entry rather than failing the run. If a post has no direct replies (or none survive the replyLanguage filter), its repliesData array is empty and sentimentBreakdown.repliesAnalyzed is 0 β the post row is still written, just with an empty rollup rather than a missing one.
Which fields work best for AI training and RAG indexing?
For RAG indexing, tweetContent (on both posts and replies) is the primary text field, and pairing it with replySentiment and replyTone lets a retrieval step surface conversation context along with its mood. For training data, replySentiment, replyTone, and replyAnalysisMethod are consistent categorical fields across every row β useful as weak-supervision labels for a custom classifier. All fields are typed primitives, requiring no normalization pass before indexing.
Does this output count as personal data under GDPR?
Yes β handle, fullname, and avatar are identifiers tied to a real person, so the output includes personal data even though it is all publicly visible on X. The Actor returns only what's publicly accessible; the lawful basis for storing and using that personal data is the responsibility of whoever runs it.
Does Twitter X Reply Scraper work with Claude, ChatGPT, and other AI agent tools?
Yes. It's callable as a standard Apify Actor through the Apify API, so any agent framework that can make an HTTP request β LangChain, CrewAI, a custom tool definition, n8n β can trigger a run and read back typed JSON with no parsing step required before it enters an LLM's context window.
How does Twitter X Reply Scraper compare to other X reply scrapers?
Checked on the Apify Store on 26 July 2026, kaitoeasyapi/twitter-reply's documented output has richer author profile fields per reply but no sentiment or tone field at all in its own sample output β pick it if all you need is raw reply text and author data with no analysis layer. fastcrawler's hashtag scraper does offer a sentiment/tone toggle, but it scores hashtag search results at the tweet level, not reply threads, and its own description flags the analysis step as slower β pick it if your unit of analysis is the hashtag post itself, not its replies. Twitter X Reply Scraper's difference is a reply-thread-first design with always-on, keyless, per-reply sentiment and tone plus a per-post rollup computed locally with no added latency, and an optional AI layer across 7 providers for teams that want a model's opinion instead of or alongside the rule-based one.
βΉοΈ Disclaimer
Twitter X Reply Scraper extracts only publicly accessible data from X that your own logged-in session is able to view. This tool is intended for lawful use cases only. Users are responsible for complying with X's Terms of Service and applicable data protection laws in their jurisdiction, particularly when the output includes personal identifiers such as handles and display names.