Twitter X Reply Scraper By Verified & Engagement Filter
Pricing
from $4.99 / 1,000 results
Twitter X Reply Scraper By Verified & Engagement Filter
π¬ Twitter X Reply Scraper captures public replies from X/Twitter threads β usernames, timestamps, text, links, IDs & engagement. β‘ Export CSV/JSON, filter by keywords, track sentiment & monitor campaigns. π Perfect for social listening, customer support, and research.
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
API Empire
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
4 days ago
Last modified
Categories
Share
Twitter X Reply Scraper β Posts, Replies and Engagement Filters
Twitter X Reply Scraper reads any X (Twitter) search results page and returns two entity types on the same dataset row: the matching posts and the replies underneath each one β pre-filtered to verified repliers, a minimum like count, and keyword matches before anything is saved. Every row is typed, normalized JSON β no HTML, no selectors, no parsing step between the Actor and your pipeline. Paste one or more x.com search links, add your X session, and choose exactly which replies survive the cut. What follows documents every filter formula, every field the Actor actually writes, and the run behavior worth knowing before you start.
What is Twitter X Reply Scraper By Verified & Engagement Filter?
Twitter X Reply Scraper By Verified & Engagement Filter is an Apify Actor that turns an X (Twitter) search URL into a set of posts and their replies, filtered down before anything is written to your dataset. It runs the same SearchTimeline and TweetDetail GraphQL operations X's own web client uses, so the fields returned match what a logged-in browser session sees β nothing is re-derived or guessed. A working X session is required: reply data on X sits behind a login wall, and the Actor pastes your session cookies into the same requests a browser would send. There is no MCP server documented for this Actor; it is reachable as a standard Apify Actor run through the Console, the Apify API, or apify_client.
- Scrape posts matching your X search query β text, author details, engagement counts
- Scrape each post's replies, capped per post by
maxReplies - Filter replies to verified repliers, a minimum like count, and/or include or exclude keywords β every active filter is combined with AND
- Export as JSON, CSV or Excel through the Apify dataset β no proxy management, no HTML parsing
What data does Twitter X Reply Scraper collect?
Every dataset row combines three things: the post that matched your search, the replies that survived your filters, and an accounting field for what got filtered out.
| Data Type | Key Fields | JSON Field Names |
|---|---|---|
| Posts (tweets) | Link, full text, ISO date, author handle/name/avatar, verified flag, reply/retweet/quote/like counts | tweetLink, tweetContent, tweetDate, handle, fullname, avatar, verified, commentCount, retweetCount, quoteCount, likeCount |
| Replies (nested per post) | Same field shape as a post, one object per surviving reply, capped at maxReplies | repliesData[].tweetLink, repliesData[].tweetContent, repliesData[].handle, repliesData[].fullname, repliesData[].avatar, repliesData[].verified, repliesData[].tweetDate, repliesData[].commentCount, repliesData[].retweetCount, repliesData[].quoteCount, repliesData[].likeCount |
| Reply filter accounting | How many of the replies X actually returned did not make it into repliesData β removed by a filter, or cut by the maxReplies cap | repliesFilteredOut |
Need more X data?
Twitter X Reply Scraper By Verified & Engagement Filter is built specifically around search β post β reply threads with verified and engagement filtering applied before rows are saved. If you need the posts themselves without the reply-filtering layer β media and link extraction across a broader result set β Twitter X Posts Scraper (Media & Link Extraction) covers that ground. For trend discovery instead of a search-driven collection, Twitter Trends Scraper & Country List Per Trend surfaces what's trending and where, rather than what people are replying with.
How does Twitter X Reply Scraper differ from the official X API?
X publishes its own X API (developer.x.com) for programmatic access to posts, search and conversation data. Getting there means registering a developer account, creating an approved App, and picking one of X's API access tiers β the tier you're granted determines which endpoints, including search and reply/conversation retrieval, you're allowed to call, and X's own documentation is the source of truth for what each tier includes. Twitter X Reply Scraper needs none of that: paste a search URL and a logged-in session, and it reads the same GraphQL endpoints X's own web client calls.
| Feature | Official X API | Twitter X Reply Scraper |
|---|---|---|
| Access | Developer account, approved App, an X API access tier | β Apify account, paste a URL and a session, press Start |
| Setup | Register an app, generate keys and tokens, select a tier | No developer registration β session cookies only |
| Reply/conversation retrieval | Governed by your tier's documented access scope | Every reply X's TweetDetail endpoint returns for that post, filtered locally, capped by maxReplies |
| Search input | An API query built against X's documented parameters | Any x.com/search URL you can build and copy from a browser |
| Reply-level filtering | Not part of the API surface β build it yourself against the response | β Verified-only, minimum likes, include/exclude keywords, applied before rows are saved |
| Output shape | X's documented, versioned API response schema | One flat row per post, replies nested under repliesData |
Use the official X API when you have, or can get, developer access and want first-party terms and support. Use this Actor when you need search-to-reply rows today, starting from a URL you can build in your own browser in seconds.
Why do developers and teams scrape X replies?
X's reply threads are where intent, sentiment and sourcing signals live β not in the original post. Four groups get distinct value from turning a search into filtered rows.
For journalists and researchers sourcing quotes
The Actor's own default search β #journorequest min_replies:10 β is a journalist-sourcing query: find posts asking for input, then read only the replies worth a follow-up. Run a hashtag or keyword search, set verifiedRepliersOnly if you only want replies from accounts X has verified, or use replyKeywords to keep replies that mention "expert" or "happy to talk". Because filtering runs before the row is saved, a thread with 200 replies and 6 usable ones costs one dataset row, not 200.
For marketers and brand teams
A branded hashtag or @mention search turns into a live read on how people are engaging, not just whether they posted. Use minReplyLikes to surface replies the audience itself has already amplified, and excludeKeywords to drop spam and giveaway noise before it reaches your dashboard. commentCount, retweetCount and likeCount on the post row give you the same engagement signal at the thread level.
For sales and community teams
Reply text is a lead signal when someone answers a call-for-interest post with words like "available" or "pitch me". Set replyKeywords to the phrases your offer expects and verifiedRepliersOnly to prioritise established accounts, and every row that reaches your dataset already matches your outreach criteria β no manual thread-reading required.
For AI engineers and agent builders
Typed JSON with a stable field set means a reply thread can be indexed into a vector store or passed straight into an LLM context window without an HTML-stripping step. Route a search on a topic, cap maxReplies, and hand tweetContent plus the nested repliesData array to a summarisation or sentiment-scoring agent β the schema doesn't change between runs, so the downstream prompt doesn't need to change either.
How to scrape X replies (step by step)
This Actor runs on Apify. Start it from the Apify Console, or call it through the Apify API with your Apify token.
- Open Twitter X Reply Scraper By Verified & Engagement Filter on the Apify Store and click Try for free
- Paste one or more X search URLs into π Start URLs (
startUrls) β this is the only required input - Add your X session under π Account session β
authTokenandct0, or set theAUTH_TOKEN/CT0environment variables instead - Set your reply filters under π Reply filters β
verifiedRepliersOnly,minReplyLikes,replyKeywords,excludeKeywordsβ and setmaxSearchResults/maxRepliesto size the run - Click Start, then read results live in the dataset tab as each post is saved, or export as JSON, CSV or Excel
While a run is going, the log shows exactly what's happening in real time: which page of a search is loading, how many posts have been found against your maxSearchResults target, and a line per row as it's written β handle, reply count kept, and a short preview of the post text. Multiple startUrls are processed one after another within a run, each with its own maxSearchResults/maxReplies budget and its own reply filters (the same filter settings apply to every URL in the list β there's no per-URL override). If a working proxy is found partway through the first search, that same proxy is kept ("sticky") for the remaining search URLs in the run rather than renegotiated from scratch each time.
What to do when X changes its structure
Twitter X Reply Scraper By Verified & Engagement Filter doesn't hardcode X's GraphQL query IDs. Each run re-extracts the current SearchTimeline and TweetDetail query IDs directly from X's own main.*.js bundle, falling back to a bundled fixed ID only if that extraction fails, and the x-client-transaction-id header is generated per request from X's own transaction-signing algorithm rather than reused. When X rotates its query IDs β which happens routinely β most runs adapt without a code change. The Actor is maintained, and the output schema stays stable, so your field names and types don't change on your end. No specific turnaround time is promised here.
What changed in X scraping recently?
Two structural changes to X still shape how this Actor β and any X scraper β has to work. Since the login wall X enforced for search and tweet viewing (rolled out from mid-2023), anonymous browsing of search results and replies stopped being reliable for most surfaces, which is why this Actor requires a pasted auth_token/ct0 session rather than running anonymously. Separately, since X retired the legacy free blue checkmark and folded verification into the paid X Premium (formerly Twitter Blue) subscription in 2023, a verified: true flag on X denotes a paid subscriber or an eligible organization/government account β not the identity-vetting check the pre-2023 blue check implied. That distinction matters directly for verifiedRepliersOnly: it keeps paid-verified accounts, not accounts X has manually confirmed as authentic. The Actor is maintained against these shifts on an ongoing basis, without a numeric update SLA.
β¬οΈ Input
Ten parameters, read directly from the Actor's input schema. Only startUrls is required.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
startUrls | β Yes | array | One or more X search page links β the same URLs you get when you search on x.com. Each link defines a topic or keyword set to follow. editor: stringList. | ["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. | 25 |
maxReplies | No | integer | How many replies to keep per post, counted after the reply filters below are applied. Minimum 1, maximum 500, default 5. | 15 |
verifiedRepliersOnly | No | boolean | Keep only replies from a verified account (blue check / verified organization); unverified replies are dropped before maxReplies is applied. Default false. | true |
minReplyLikes | No | integer | Drop any reply with fewer likes (favorites) than this number. 0 keeps replies with any like count. Minimum 0, maximum 10000000, default 0. | 5 |
replyKeywords | No | array | Keep only replies whose text contains at least one of these words or phrases (case-insensitive substring match). Default [] β empty keeps replies regardless of wording. editor: stringList. | ["pitch", "available"] |
excludeKeywords | No | array | Drop any reply whose text contains one of these words or phrases (case-insensitive substring match), applied after the include filter. Default [] β empty disables it. editor: stringList. | ["spam", "giveaway"] |
authToken | No* | string | Your X account session token, or set the AUTH_TOKEN environment variable instead. Stored as an encrypted Apify secret (isSecret: true). editor: textfield. | "<YOUR_X_AUTH_TOKEN_COOKIE>" |
ct0 | No* | string | The companion CSRF/security value for your X session, or set the CT0 environment variable instead. Stored as an encrypted Apify secret (isSecret: true). editor: textfield. | "<YOUR_X_CT0_COOKIE>" |
proxyConfiguration | No | object | Optional Apify Proxy settings. editor: proxy, prefilled {"useApifyProxy": false}. | {"useApifyProxy": false} |
* Neither field is marked required in the schema, but the run validates that a usable auth_token + ct0 pair exists (from input or from the AUTH_TOKEN/CT0 environment variables) before doing any work β without one, the run logs an error and exits without pushing a single row.
How the reply filters really combine. All active filters are ANDed β a reply must pass every filter you turn on to survive. They run locally, against fields the Actor has already fetched, so turning more of them on never costs an extra request. maxReplies is applied last, after filtering, so it caps how many surviving replies you keep, not how many were fetched.
Common pitfall: startUrls must be an X search URL containing a ?q= query parameter β the kind you get from typing into the search box on x.com. If a URL has no q= parameter (a profile page, a status link, a hashtag page opened without a search), the Actor does not raise an error β it silently falls back to its own built-in default query, #journorequest min_replies:10, and runs that instead. Always copy the URL from an actual X search results page, not from any other X page.
Example input
{"startUrls": ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],"maxSearchResults": 25,"maxReplies": 15,"verifiedRepliersOnly": true,"minReplyLikes": 5,"replyKeywords": ["available", "pitch"],"excludeKeywords": ["spam", "giveaway"],"authToken": "<YOUR_X_AUTH_TOKEN_COOKIE>","ct0": "<YOUR_X_CT0_COOKIE>","proxyConfiguration": { "useApifyProxy": false }}
β¬οΈ Output
Every result is one dataset row per matching post, with its filtered replies nested inside it. Fields are typed and consistently named across runs. Export as JSON, CSV or Excel, or read the dataset through the Apify API. The default dataset view shows only nine columns β tweetLink, tweetContent, tweetDate, handle, commentCount, retweetCount, likeCount, repliesData, repliesFilteredOut β but the Actor writes more than that to every row; avatar, fullname, verified and quoteCount are present on every post and every reply, just not shown in the table view. Switch to JSON view, or export, to see all of them.
Scraped post (tweet) row
{"tweetLink": "https://x.com/exampleuser/status/1834521098765432101","avatar": "https://pbs.twimg.com/profile_images/1234567890/avatar_bigger.jpg","fullname": "Example User","handle": "@exampleuser","verified": true,"tweetDate": "2026-07-20T14:32:05.000Z","tweetContent": "Looking for a freelance video editor for a 3-part series, budget open β reply or DM #journorequest","commentCount": 42,"retweetCount": 11,"quoteCount": 3,"likeCount": 187,"repliesData": ["β¦ see the reply object shape below, one entry per surviving reply, capped at maxReplies β¦"],"repliesFilteredOut": 34}
repliesFilteredOut is present only when at least one reply filter is active (verifiedRepliersOnly, minReplyLikes > 0, or a non-empty replyKeywords/excludeKeywords). On an unfiltered run the key is left off the row entirely β it is not written as 0.
avatar is always the higher-resolution version of the profile image X returns β the Actor rewrites the _normal suffix X's API sends to _bigger before saving the row, on both posts and replies. tweetDate is normalized to ISO 8601 (YYYY-MM-DDTHH:MM:SS.000Z); if X's own date string ever fails to parse, the raw string is saved as-is rather than dropping the field.
Reply object shape (inside repliesData)
{"tweetLink": "https://x.com/anotherhandle/status/1834521555512340992","avatar": "https://pbs.twimg.com/profile_images/9876543210/avatar_bigger.jpg","fullname": "Another Handle","handle": "@anotherhandle","verified": null,"tweetDate": "2026-07-20T14:41:12.000Z","tweetContent": "I'm available for this β sent a DM with my reel","commentCount": 1,"retweetCount": 0,"quoteCount": 0,"likeCount": 9}
verified is true or null β never false. An unverified account's reply carries verified: null, so a downstream check should test for === true rather than === false to catch unverified replies correctly.
β οΈ How verified and engagement filtering actually work
This is the core of the Actor, so it's worth stating exactly rather than leaving it to the filter names.
Verified-repliers detection. A reply's verified field is set to true when X's own response marks the replier as is_blue_verified, or as a verified organization/government account (verification.verified) β otherwise the field is left null. verifiedRepliersOnly drops any reply where verified is not exactly true. As covered above, "verified" on X today means an X Premium subscriber or an eligible verified organization, not an identity check.
Engagement filter (minReplyLikes). A reply is kept when its likeCount β X's favorite_count at fetch time β is greater than or equal to minReplyLikes. 0 disables the floor entirely. There is no separate "engagement score" combining likes, retweets and replies; the engagement filter is a like-count threshold only.
Keyword filters. replyKeywords is an allow-list: if set, a reply is kept only when its text contains at least one term, case-insensitive, substring match. excludeKeywords is a block-list checked afterward: a reply is dropped if its text contains any term. Both are empty by default, meaning no keyword filtering happens unless you set them.
Order and combination. All active filters are combined with AND, checked in this order: verified β minimum likes β include keywords β exclude keywords. maxReplies is applied last, after filtering, so it caps kept replies, not fetched ones β a post with 40 replies and verifiedRepliersOnly on might fetch 40 and keep only the 6 that passed, then maxReplies further trims that 6 if it's set below 6.
repliesFilteredOut isn't purely "failed the filter." It's computed as replies fetched minus replies kept, so it blends replies your filters actively removed with replies that passed every filter but were simply beyond the maxReplies cap. A high number doesn't always mean your filters were strict β it can just mean the thread had more matching replies than you asked to keep.
Billing is per post, not per reply. Every matching post is charged as one row_result event, regardless of how many replies survive filtering β a post whose replies were all filtered out still pushes a row with repliesData: [] and is still charged. Filtering itself never costs an extra request or an extra charge, but the row is never free either.
Reply-fetch failures look identical to "no replies." Unlike the search request, a failed reply fetch for a specific post (blocked, rate-limited, or erroring) is not retried and does not trigger the proxy escalation the search step uses β it is treated the same as a post genuinely having zero replies, and the row is still saved and charged with repliesData: []. If you see many rows with no replies in a row, check your session is still valid before assuming the posts truly have none.
How does Twitter X Reply Scraper compare to other X reply scrapers?
| Feature | Twitter X Reply Scraper | Generic alternative |
|---|---|---|
| Output format | β Typed JSON, fixed keys on every row | Varies by actor |
| Reply-level filtering before save | β Verified / minimum likes / include & exclude keywords, ANDed | Not commonly offered as a pre-save filter |
| Dedicated verified-repliers toggle | β
verifiedRepliersOnly | Not commonly a dedicated input |
| Entity coverage per row | Post and its nested, filtered replies together | Often posts and replies as separate outputs or separate runs |
| Session requirement | Documented authToken / ct0, stored as Apify secrets | Varies by actor |
Observed on the Apify Store on 2026-07-25: kaitoeasyapi/twitter-reply takes a conversation_ids array plus max_items_per_conversation and returns tweet-level objects (type, id, url, retweetCount, replyCount, likeCount, quoteCount, viewCount, a nested author block) β its listing does not document a reply-level verified-only or minimum-like filter, and pricing is advertised at $0.25 per 1,000 tweets on that listing. Its listing also advertises figures like "150 tweets per second" and "99.9% uptime" β those are the competitor's own marketing claims, checked on the Apify Store 2026-07-25, and are not measured or reproduced here. A third ranked competitor, fastcrawler/twitter-reply-scraper-0-2-1k-tweets-pay-per-result-2025, returned a 404 on the Apify Store as of 2026-07-25 and could not be reviewed.
If you're building an AI agent or a RAG pipeline, the output-format row is the decision-maker β parsing HTML inside an agent loop is a reliability failure mode, not a feature.
How many results can you scrape with Twitter X Reply Scraper?
maxSearchResults caps posts collected per search URL β minimum 1, maximum 5000, default 10 β and maxReplies caps replies kept per post, after filtering β minimum 1, maximum 500, default 5. Both are hard-clamped in code to those ranges regardless of what's sent. Multiple startUrls each run independently and their totals add up; there is no shared budget across URLs.
Search pagination fetches 20 posts per page (a fixed internal page size, not configurable) and follows X's own cursor until maxSearchResults is reached, the cursor runs out, or a page returns no new posts β whichever comes first. There is no hard cap in the Actor itself beyond maxSearchResults and maxReplies; the real ceiling on any given run is how many posts and replies X's own search index actually has for that query. No throughput benchmark is quoted here because none has been measured for this documentation.
Integrate Twitter X Reply Scraper and automate your workflow
Twitter X Reply Scraper works with any language or tool that can send an HTTP request to the Apify API.
REST API integration
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/twitter-x-reply-scraper-by-verified-engagement-filter").call(run_input={"startUrls": ["https://x.com/search?q=%23journorequest+min_replies%3A10&src=typed_query&f=live"],"maxSearchResults": 25,"maxReplies": 15,"verifiedRepliersOnly": True,"minReplyLikes": 5,"authToken": "<YOUR_X_AUTH_TOKEN_COOKIE>","ct0": "<YOUR_X_CT0_COOKIE>",})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["handle"], row["tweetLink"], len(row["repliesData"]))
Works in Python, Node.js, Go, Ruby, cURL.
Automation platforms (n8n, Make, LangChain)
In n8n, use the Apify node β or an HTTP Request node against the Actor's run endpoint β with the JSON input shown above; a downstream Filter node can branch on verified or on repliesFilteredOut. In Make, the Apify module's run-and-wait mode lets you schedule a recurring hashtag or #journorequest-style search and pipe rows straight into Google Sheets, Airtable or a Slack notification step. In LangChain, wrap the Actor run as a Tool and hand repliesData directly to the model β it's already typed JSON, so no parsing step sits between the Actor and the agent's context window.
Is it legal to scrape X replies?
Yes, when limited to publicly accessible posts and replies, though the data involved is personal data and that changes what applies. Twitter X Reply Scraper By Verified & Engagement Filter returns only posts and replies visible through a standard, logged-in X session β the same content a normal user browsing that search or thread would see; protected/locked accounts and private conversations are not reachable through the Actor.
Because a post's handle, fullname, avatar and reply text identify real individuals, this falls under personal-data regimes like GDPR and CCPA where they apply β you need a lawful basis to store and use it, particularly for anything beyond ad-hoc research. This differs from scraping product or business-listing data, where terms-of-service and database-rights framing apply instead. Consult legal counsel for commercial use cases involving bulk personal data.
β Frequently asked questions
Does Twitter X Reply Scraper work without an X account?
No. The Actor requires a working X session β an auth_token and ct0 cookie pair, supplied via input or the AUTH_TOKEN/CT0 environment variables. Reply data on X sits behind a login wall, and without a valid session the run logs an error and exits before pushing any rows.
How often is the scraped data updated?
Every run fetches live from X β nothing is cached between runs, and no data is reused from a previous run. Schedule the Actor on Apify if you want a recurring refresh of the same search.
What happens when a post has no replies, or every reply gets filtered out?
The row is still saved and charged. repliesData comes back as an empty array ([]), and if any filter is active, repliesFilteredOut reports how many fetched replies didn't make the cut. There's no way from the output alone to distinguish "this post genuinely has no replies" from "the reply fetch for this post failed silently" β both look identical.
Can I scrape private or protected X accounts, or direct messages?
No. Only posts and replies visible to a standard logged-in X session are returned. Protected (locked) accounts and direct messages are not accessible through this Actor, and there is no input that changes that.
Do I need X Premium (a paid, verified account) to use this Actor?
No. The session behind authToken/ct0 doesn't need to belong to a verified or paid account β verifiedRepliersOnly filters on the repliers' verification status, not on your own account's.
Can I run several searches, or apply different filters to each?
You can run several searches β list as many URLs in startUrls as you need, and each is processed independently with its own maxSearchResults/maxReplies budget. You cannot apply different reply filters per URL in a single run: verifiedRepliersOnly, minReplyLikes, replyKeywords and excludeKeywords are set once and apply to every URL in that run. Start separate runs if different searches need different filter combinations.
Does Twitter X Reply Scraper work for AI agent workflows and LLM pipelines?
Yes. It's callable as a standard HTTP-triggered Actor run through the Apify API, so LangChain, CrewAI, n8n, or a hand-written tool definition can invoke it and receive typed JSON with no parsing step. repliesData and repliesFilteredOut give an agent a clean signal to branch on.
How does Twitter X Reply Scraper handle X's anti-bot system?
The Actor generates its x-client-transaction-id header per request using X's own transaction-signing algorithm rather than a static value, and re-extracts current SearchTimeline/TweetDetail GraphQL query IDs from X's live JS bundle each run (falling back to bundled IDs only if that fails). On a blocked or errored search response, it escalates through a proxy ladder β direct or your chosen Apify Proxy setting first, then an Apify datacenter proxy group, then Apify Residential with up to three retry attempts and backoff β and keeps a working proxy sticky across the remaining search URLs in that run.
How does Twitter X Reply Scraper compare to other X reply scrapers?
Observed on the Apify Store on 2026-07-25, kaitoeasyapi/twitter-reply takes conversation IDs rather than search URLs and returns tweet-level fields without a documented reply-level verified or like-count filter; its throughput and uptime figures are the competitor's own marketing claims, not independently measured. A second ranked competitor's listing returned a 404 as of the same date and couldn't be reviewed. This Actor's difference is starting from a search URL and filtering replies to verified/engagement/keyword criteria before a row is ever saved.
Does it return data in a format LLMs can use directly?
Yes. Typed, normalized JSON with stable field names on every run. No HTML, no selectors, no parsing. Pass a row straight into an LLM context window, index it into a vector store, or hand it to an agent tool.
Can I use it without managing proxies?
Yes, to a point. Leaving proxyConfiguration.useApifyProxy off (the default) means the Actor's first attempt goes out directly. If that attempt gets blocked, the Actor automatically requests Apify Proxy anyway β first from a SHADER datacenter group, then from RESIDENTIAL β regardless of your toggle, so the setting controls the starting behavior rather than being an absolute opt-out of Apify Proxy usage.
What happens when X changes its structure or blocks the scraper?
The scraper is maintained, and because GraphQL query IDs and the transaction-signing header are generated fresh each run rather than hardcoded, many of X's routine changes don't require a redeploy at all. Your field names and types don't change on your end. No numeric turnaround time is promised.
π¬ Your feedback
Found a bug, or missing a field that X's response actually carries? We want to know. Open an issue on the Actor's Issues tab on Apify with the search URL you used (redact your session cookies first) and the exact input JSON β that's what gets a fix shipped fastest.